johnson 1.2.0 → 2.0.0.pre0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (782) hide show
  1. data/CHANGELOG.rdoc +8 -0
  2. data/Manifest.txt +762 -48
  3. data/README.rdoc +2 -1
  4. data/Rakefile +90 -18
  5. data/ext/spidermonkey/conversions.c +9 -2
  6. data/ext/spidermonkey/ruby_land_proxy.c +1 -1
  7. data/ext/spidermonkey/runtime.h +1 -1
  8. data/ext/tracemonkey/context.cc +125 -0
  9. data/ext/tracemonkey/context.h +19 -0
  10. data/ext/tracemonkey/conversions.cc +365 -0
  11. data/ext/tracemonkey/conversions.h +32 -0
  12. data/ext/tracemonkey/debugger.cc +234 -0
  13. data/ext/tracemonkey/debugger.h +10 -0
  14. data/ext/tracemonkey/extconf.rb +37 -0
  15. data/ext/tracemonkey/extensions.cc +37 -0
  16. data/ext/tracemonkey/extensions.h +12 -0
  17. data/ext/tracemonkey/global.cc +40 -0
  18. data/ext/tracemonkey/global.h +11 -0
  19. data/ext/tracemonkey/idhash.cc +16 -0
  20. data/ext/tracemonkey/idhash.h +8 -0
  21. data/ext/tracemonkey/immutable_node.cc +1199 -0
  22. data/ext/tracemonkey/immutable_node.cc.erb +559 -0
  23. data/ext/tracemonkey/immutable_node.h +22 -0
  24. data/ext/tracemonkey/jroot.h +215 -0
  25. data/ext/tracemonkey/js_land_proxy.cc +620 -0
  26. data/ext/tracemonkey/js_land_proxy.h +20 -0
  27. data/ext/tracemonkey/ruby_land_proxy.cc +618 -0
  28. data/ext/tracemonkey/ruby_land_proxy.h +38 -0
  29. data/ext/tracemonkey/runtime.cc +454 -0
  30. data/ext/tracemonkey/runtime.h +27 -0
  31. data/ext/tracemonkey/split_global.cc +392 -0
  32. data/ext/tracemonkey/split_global.h +11 -0
  33. data/ext/tracemonkey/tracemonkey.cc +23 -0
  34. data/ext/tracemonkey/tracemonkey.h +32 -0
  35. data/lib/johnson.rb +12 -4
  36. data/lib/johnson/error.rb +5 -0
  37. data/lib/johnson/js/prelude.js +16 -1
  38. data/lib/johnson/parser.rb +2 -1
  39. data/lib/johnson/runtime.rb +87 -26
  40. data/lib/johnson/spidermonkey/runtime.rb +7 -16
  41. data/lib/johnson/tracemonkey.rb +13 -0
  42. data/lib/johnson/tracemonkey/context.rb +10 -0
  43. data/lib/johnson/tracemonkey/debugger.rb +67 -0
  44. data/lib/johnson/tracemonkey/immutable_node.rb +282 -0
  45. data/lib/johnson/tracemonkey/js_land_proxy.rb +64 -0
  46. data/lib/johnson/tracemonkey/mutable_tree_visitor.rb +242 -0
  47. data/lib/johnson/tracemonkey/ruby_land_proxy.rb +17 -0
  48. data/lib/johnson/tracemonkey/runtime.rb +80 -0
  49. data/test/{johnson_test.rb → generic/johnson_test.rb} +1 -1
  50. data/test/{parser_test.rb → generic/parser_test.rb} +1 -1
  51. data/test/helper.rb +23 -4
  52. data/test/johnson/{browser_test.rb → generic/browser_test.rb} +1 -1
  53. data/test/johnson/{conversions → generic/conversions}/array_test.rb +1 -1
  54. data/test/johnson/{conversions → generic/conversions}/boolean_test.rb +1 -1
  55. data/test/johnson/{conversions → generic/conversions}/callable_test.rb +1 -1
  56. data/test/johnson/{conversions → generic/conversions}/file_test.rb +1 -1
  57. data/test/johnson/generic/conversions/helper.rb +1 -0
  58. data/test/johnson/{conversions → generic/conversions}/nil_test.rb +1 -1
  59. data/test/johnson/{conversions → generic/conversions}/number_test.rb +1 -1
  60. data/test/johnson/{conversions → generic/conversions}/regexp_test.rb +1 -1
  61. data/test/johnson/{conversions → generic/conversions}/string_test.rb +1 -1
  62. data/test/johnson/{conversions → generic/conversions}/struct_test.rb +1 -1
  63. data/test/johnson/{conversions → generic/conversions}/symbol_test.rb +1 -1
  64. data/test/johnson/{conversions → generic/conversions}/thread_test.rb +1 -1
  65. data/test/johnson/{custom_conversions_test.rb → generic/custom_conversions_test.rb} +1 -1
  66. data/test/johnson/generic/default_test.rb +12 -0
  67. data/test/johnson/{error_test.rb → generic/error_test.rb} +1 -1
  68. data/test/johnson/{extensions_test.rb → generic/extensions_test.rb} +1 -1
  69. data/test/johnson/generic/helper.rb +1 -0
  70. data/test/johnson/{nodes → generic/nodes}/array_literal_test.rb +1 -1
  71. data/test/johnson/{nodes → generic/nodes}/array_node_test.rb +1 -1
  72. data/test/johnson/{nodes → generic/nodes}/binary_node_test.rb +1 -1
  73. data/test/johnson/{nodes → generic/nodes}/bracket_access_test.rb +1 -1
  74. data/test/johnson/{nodes → generic/nodes}/delete_test.rb +1 -1
  75. data/test/johnson/{nodes → generic/nodes}/do_while_test.rb +1 -1
  76. data/test/johnson/{nodes → generic/nodes}/dot_accessor_test.rb +1 -1
  77. data/test/johnson/generic/nodes/export_test.rb +11 -0
  78. data/test/johnson/{nodes → generic/nodes}/for_test.rb +1 -1
  79. data/test/johnson/{nodes → generic/nodes}/function_test.rb +1 -1
  80. data/test/johnson/generic/nodes/helper.rb +1 -0
  81. data/test/johnson/{nodes → generic/nodes}/if_test.rb +16 -6
  82. data/test/johnson/generic/nodes/import_test.rb +15 -0
  83. data/test/johnson/{nodes → generic/nodes}/label_test.rb +1 -1
  84. data/test/johnson/{nodes → generic/nodes}/let_test.rb +1 -1
  85. data/test/johnson/{nodes → generic/nodes}/object_literal_test.rb +1 -1
  86. data/test/johnson/{nodes → generic/nodes}/return_test.rb +1 -1
  87. data/test/johnson/{nodes → generic/nodes}/semi_test.rb +1 -1
  88. data/test/johnson/{nodes → generic/nodes}/switch_test.rb +1 -1
  89. data/test/johnson/{nodes → generic/nodes}/ternary_test.rb +1 -1
  90. data/test/johnson/{nodes → generic/nodes}/throw_test.rb +1 -1
  91. data/test/johnson/{nodes → generic/nodes}/try_node_test.rb +36 -6
  92. data/test/johnson/{nodes → generic/nodes}/typeof_test.rb +1 -1
  93. data/test/johnson/{nodes → generic/nodes}/unary_node_test.rb +1 -1
  94. data/test/johnson/{nodes → generic/nodes}/void_test.rb +1 -1
  95. data/test/johnson/{nodes → generic/nodes}/while_test.rb +1 -1
  96. data/test/johnson/{nodes → generic/nodes}/with_test.rb +1 -1
  97. data/test/johnson/{prelude_test.rb → generic/prelude_test.rb} +1 -1
  98. data/test/johnson/{runtime_test.rb → generic/runtime_test.rb} +3 -6
  99. data/test/johnson/generic/version_test.rb +13 -0
  100. data/test/johnson/{visitors → generic/visitors}/dot_visitor_test.rb +1 -1
  101. data/test/johnson/{visitors → generic/visitors}/enumerating_visitor_test.rb +1 -1
  102. data/test/johnson/generic/visitors/helper.rb +1 -0
  103. data/test/johnson/spidermonkey/js_land_proxy_test.rb +1 -5
  104. data/test/johnson/spidermonkey/ruby_land_proxy_test.rb +11 -7
  105. data/test/johnson/tracemonkey/context_test.rb +21 -0
  106. data/test/johnson/tracemonkey/immutable_node_test.rb +34 -0
  107. data/test/johnson/tracemonkey/js_land_proxy_test.rb +273 -0
  108. data/test/johnson/tracemonkey/ruby_land_proxy_test.rb +274 -0
  109. data/test/johnson/tracemonkey/runtime_test.rb +41 -0
  110. data/test/johnson/tracemonkey/split_global_test.rb +32 -0
  111. data/vendor/spidermonkey/js.pkg +2 -0
  112. data/vendor/tracemonkey/Makefile.in +668 -0
  113. data/vendor/tracemonkey/Makefile.ref +483 -0
  114. data/vendor/tracemonkey/README.html +54 -0
  115. data/vendor/tracemonkey/SpiderMonkey.rsp +11 -0
  116. data/vendor/tracemonkey/Y.js +19 -0
  117. data/vendor/tracemonkey/aclocal.m4 +9 -0
  118. data/vendor/tracemonkey/bench.sh +5 -0
  119. data/vendor/tracemonkey/build/autoconf/acoutput-fast.pl +202 -0
  120. data/vendor/tracemonkey/build/autoconf/altoptions.m4 +154 -0
  121. data/vendor/tracemonkey/build/autoconf/config.guess +1537 -0
  122. data/vendor/tracemonkey/build/autoconf/config.sub +1595 -0
  123. data/vendor/tracemonkey/build/autoconf/install-sh +119 -0
  124. data/vendor/tracemonkey/build/autoconf/make-makefile +315 -0
  125. data/vendor/tracemonkey/build/autoconf/match-dir.sh +101 -0
  126. data/vendor/tracemonkey/build/autoconf/moznbytetype.m4 +136 -0
  127. data/vendor/tracemonkey/build/autoconf/nspr.m4 +82 -0
  128. data/vendor/tracemonkey/build/autoconf/pkg.m4 +59 -0
  129. data/vendor/tracemonkey/build/autoconf/update-makefile.sh +118 -0
  130. data/vendor/tracemonkey/build/cygwin-wrapper +75 -0
  131. data/vendor/tracemonkey/build/hcc +111 -0
  132. data/vendor/tracemonkey/build/hcpp +155 -0
  133. data/vendor/tracemonkey/build/unix/mddepend.pl +165 -0
  134. data/vendor/tracemonkey/build/unix/uniq.pl +63 -0
  135. data/vendor/tracemonkey/build/win32/pgomerge.py +40 -0
  136. data/vendor/tracemonkey/builtins.tbl +91 -0
  137. data/vendor/tracemonkey/call.js +13 -0
  138. data/vendor/tracemonkey/config.mk +206 -0
  139. data/vendor/tracemonkey/config/Makefile.in +106 -0
  140. data/vendor/tracemonkey/config/Moz/Milestone.pm +232 -0
  141. data/vendor/tracemonkey/config/autoconf.mk.in +362 -0
  142. data/vendor/tracemonkey/config/check-sync-dirs.py +103 -0
  143. data/vendor/tracemonkey/config/check-sync-exceptions +7 -0
  144. data/vendor/tracemonkey/config/config.mk +881 -0
  145. data/vendor/tracemonkey/config/fastcwd.pl +66 -0
  146. data/vendor/tracemonkey/config/gcc_hidden.h +2 -0
  147. data/vendor/tracemonkey/config/insure.mk +53 -0
  148. data/vendor/tracemonkey/config/make-system-wrappers.pl +59 -0
  149. data/vendor/tracemonkey/config/milestone.pl +112 -0
  150. data/vendor/tracemonkey/config/milestone.txt +13 -0
  151. data/vendor/tracemonkey/config/mkdepend/Makefile.in +84 -0
  152. data/vendor/tracemonkey/config/mkdepend/cppsetup.c +233 -0
  153. data/vendor/tracemonkey/config/mkdepend/def.h +184 -0
  154. data/vendor/tracemonkey/config/mkdepend/ifparser.c +551 -0
  155. data/vendor/tracemonkey/config/mkdepend/ifparser.h +83 -0
  156. data/vendor/tracemonkey/config/mkdepend/imakemdep.h +733 -0
  157. data/vendor/tracemonkey/config/mkdepend/include.c +337 -0
  158. data/vendor/tracemonkey/config/mkdepend/main.c +860 -0
  159. data/vendor/tracemonkey/config/mkdepend/mkdepend.man +382 -0
  160. data/vendor/tracemonkey/config/mkdepend/parse.c +686 -0
  161. data/vendor/tracemonkey/config/mkdepend/pr.c +124 -0
  162. data/vendor/tracemonkey/config/nfspwd.pl +50 -0
  163. data/vendor/tracemonkey/config/nsinstall.c +481 -0
  164. data/vendor/tracemonkey/config/nsinstall.py +155 -0
  165. data/vendor/tracemonkey/config/pathsub.c +247 -0
  166. data/vendor/tracemonkey/config/pathsub.h +74 -0
  167. data/vendor/tracemonkey/config/preprocessor.pl +671 -0
  168. data/vendor/tracemonkey/config/revdepth-nt.pl +48 -0
  169. data/vendor/tracemonkey/config/revdepth.pl +51 -0
  170. data/vendor/tracemonkey/config/rules.mk +2310 -0
  171. data/vendor/tracemonkey/config/static-checking-config.mk +21 -0
  172. data/vendor/tracemonkey/config/static-checking.js +92 -0
  173. data/vendor/tracemonkey/config/string-format.js +61 -0
  174. data/vendor/tracemonkey/config/system-headers +1035 -0
  175. data/vendor/tracemonkey/config/version.mk +85 -0
  176. data/vendor/tracemonkey/config/version_win.pl +442 -0
  177. data/vendor/tracemonkey/configure +14183 -0
  178. data/vendor/tracemonkey/configure.in +5363 -0
  179. data/vendor/tracemonkey/correct.sh +23 -0
  180. data/vendor/tracemonkey/correct/check-3d-morph.js +55 -0
  181. data/vendor/tracemonkey/correct/check-3d-raytrace.js +445 -0
  182. data/vendor/tracemonkey/correct/check-access-binary-trees.js +52 -0
  183. data/vendor/tracemonkey/correct/check-access-fannkuch.js +66 -0
  184. data/vendor/tracemonkey/correct/check-access-nbody.js +171 -0
  185. data/vendor/tracemonkey/correct/check-access-nsieve.js +40 -0
  186. data/vendor/tracemonkey/correct/check-bitops-3bit-bits-in-byte.js +35 -0
  187. data/vendor/tracemonkey/correct/check-bitops-bits-in-byte.js +24 -0
  188. data/vendor/tracemonkey/correct/check-bitops-bitwise-and.js +29 -0
  189. data/vendor/tracemonkey/correct/check-bitops-nsieve-bits.js +40 -0
  190. data/vendor/tracemonkey/correct/check-controlflow-recursive.js +27 -0
  191. data/vendor/tracemonkey/correct/check-date-format-tofte.js +302 -0
  192. data/vendor/tracemonkey/correct/check-date-format-xparb.js +421 -0
  193. data/vendor/tracemonkey/correct/check-mont.js +119 -0
  194. data/vendor/tracemonkey/dtoa.c +3335 -0
  195. data/vendor/tracemonkey/editline/Makefile.in +55 -0
  196. data/vendor/tracemonkey/editline/Makefile.ref +143 -0
  197. data/vendor/tracemonkey/editline/README +83 -0
  198. data/vendor/tracemonkey/editline/editline.3 +175 -0
  199. data/vendor/tracemonkey/editline/editline.c +1371 -0
  200. data/vendor/tracemonkey/editline/editline.h +135 -0
  201. data/vendor/tracemonkey/editline/sysunix.c +182 -0
  202. data/vendor/tracemonkey/editline/unix.h +82 -0
  203. data/vendor/tracemonkey/if.js +13 -0
  204. data/vendor/tracemonkey/imacro_asm.js.in +396 -0
  205. data/vendor/tracemonkey/imacros.c.out +1034 -0
  206. data/vendor/tracemonkey/imacros.jsasm +770 -0
  207. data/vendor/tracemonkey/javascript-trace.d +73 -0
  208. data/vendor/tracemonkey/jitstats.tbl +55 -0
  209. data/vendor/tracemonkey/js-config.h.in +82 -0
  210. data/vendor/tracemonkey/js-config.in +111 -0
  211. data/vendor/tracemonkey/js.mdp +0 -0
  212. data/vendor/tracemonkey/js.msg +312 -0
  213. data/vendor/tracemonkey/js3240.rc +79 -0
  214. data/vendor/tracemonkey/jsOS240.def +654 -0
  215. data/vendor/tracemonkey/jsapi.cpp +6005 -0
  216. data/vendor/tracemonkey/jsapi.h +2727 -0
  217. data/vendor/tracemonkey/jsarena.cpp +450 -0
  218. data/vendor/tracemonkey/jsarena.h +318 -0
  219. data/vendor/tracemonkey/jsarray.cpp +3664 -0
  220. data/vendor/tracemonkey/jsarray.h +238 -0
  221. data/vendor/tracemonkey/jsatom.cpp +1244 -0
  222. data/vendor/tracemonkey/jsatom.h +493 -0
  223. data/vendor/tracemonkey/jsbit.h +249 -0
  224. data/vendor/tracemonkey/jsbool.cpp +184 -0
  225. data/vendor/tracemonkey/jsbool.h +88 -0
  226. data/vendor/tracemonkey/jsbuiltins.cpp +415 -0
  227. data/vendor/tracemonkey/jsbuiltins.h +456 -0
  228. data/vendor/tracemonkey/jsclist.h +139 -0
  229. data/vendor/tracemonkey/jscntxt.cpp +1816 -0
  230. data/vendor/tracemonkey/jscntxt.h +1541 -0
  231. data/vendor/tracemonkey/jscompat.h +57 -0
  232. data/vendor/tracemonkey/jsconfig.mk +181 -0
  233. data/vendor/tracemonkey/jscpucfg.cpp +194 -0
  234. data/vendor/tracemonkey/jscpucfg.h +91 -0
  235. data/vendor/tracemonkey/jsdate.cpp +2465 -0
  236. data/vendor/tracemonkey/jsdate.h +129 -0
  237. data/vendor/tracemonkey/jsdbgapi.cpp +2017 -0
  238. data/vendor/tracemonkey/jsdbgapi.h +500 -0
  239. data/vendor/tracemonkey/jsdhash.cpp +876 -0
  240. data/vendor/tracemonkey/jsdhash.h +588 -0
  241. data/vendor/tracemonkey/jsdtoa.cpp +572 -0
  242. data/vendor/tracemonkey/jsdtoa.h +131 -0
  243. data/vendor/tracemonkey/jsdtracef.c +318 -0
  244. data/vendor/tracemonkey/jsdtracef.h +81 -0
  245. data/vendor/tracemonkey/jsemit.cpp +7292 -0
  246. data/vendor/tracemonkey/jsemit.h +802 -0
  247. data/vendor/tracemonkey/jsexn.cpp +1337 -0
  248. data/vendor/tracemonkey/jsexn.h +96 -0
  249. data/vendor/tracemonkey/jsfile.cpp +2747 -0
  250. data/vendor/tracemonkey/jsfile.h +56 -0
  251. data/vendor/tracemonkey/jsfile.msg +90 -0
  252. data/vendor/tracemonkey/jsfun.cpp +3089 -0
  253. data/vendor/tracemonkey/jsfun.h +366 -0
  254. data/vendor/tracemonkey/jsgc.cpp +3816 -0
  255. data/vendor/tracemonkey/jsgc.h +429 -0
  256. data/vendor/tracemonkey/jshash.cpp +477 -0
  257. data/vendor/tracemonkey/jshash.h +151 -0
  258. data/vendor/tracemonkey/jsify.pl +483 -0
  259. data/vendor/tracemonkey/jsinterp.cpp +7441 -0
  260. data/vendor/tracemonkey/jsinterp.h +666 -0
  261. data/vendor/tracemonkey/jsinvoke.cpp +42 -0
  262. data/vendor/tracemonkey/jsiter.cpp +1040 -0
  263. data/vendor/tracemonkey/jsiter.h +140 -0
  264. data/vendor/tracemonkey/jskeyword.tbl +124 -0
  265. data/vendor/tracemonkey/jskwgen.cpp +460 -0
  266. data/vendor/tracemonkey/jslibmath.h +69 -0
  267. data/vendor/tracemonkey/jslock.cpp +1512 -0
  268. data/vendor/tracemonkey/jslock.h +325 -0
  269. data/vendor/tracemonkey/jslocko.asm +60 -0
  270. data/vendor/tracemonkey/jslog2.cpp +111 -0
  271. data/vendor/tracemonkey/jslong.h +167 -0
  272. data/vendor/tracemonkey/jsmath.cpp +806 -0
  273. data/vendor/tracemonkey/jsmath.h +63 -0
  274. data/vendor/tracemonkey/jsnum.cpp +1374 -0
  275. data/vendor/tracemonkey/jsnum.h +280 -0
  276. data/vendor/tracemonkey/jsobj.cpp +6165 -0
  277. data/vendor/tracemonkey/jsobj.h +870 -0
  278. data/vendor/tracemonkey/json.cpp +1338 -0
  279. data/vendor/tracemonkey/json.h +108 -0
  280. data/vendor/tracemonkey/jsopcode.cpp +5484 -0
  281. data/vendor/tracemonkey/jsopcode.h +434 -0
  282. data/vendor/tracemonkey/jsopcode.tbl +591 -0
  283. data/vendor/tracemonkey/jsoplengen.cpp +121 -0
  284. data/vendor/tracemonkey/jsotypes.h +202 -0
  285. data/vendor/tracemonkey/jsparse.cpp +9257 -0
  286. data/vendor/tracemonkey/jsparse.h +900 -0
  287. data/vendor/tracemonkey/jsprf.cpp +1262 -0
  288. data/vendor/tracemonkey/jsprf.h +150 -0
  289. data/vendor/tracemonkey/jsproto.tbl +117 -0
  290. data/vendor/tracemonkey/jsprvtd.h +366 -0
  291. data/vendor/tracemonkey/jspubtd.h +585 -0
  292. data/vendor/tracemonkey/jsregexp.cpp +5051 -0
  293. data/vendor/tracemonkey/jsregexp.h +199 -0
  294. data/vendor/tracemonkey/jsreops.tbl +145 -0
  295. data/vendor/tracemonkey/jsscan.cpp +2040 -0
  296. data/vendor/tracemonkey/jsscan.h +467 -0
  297. data/vendor/tracemonkey/jsscope.cpp +1966 -0
  298. data/vendor/tracemonkey/jsscope.h +487 -0
  299. data/vendor/tracemonkey/jsscript.cpp +1932 -0
  300. data/vendor/tracemonkey/jsscript.h +345 -0
  301. data/vendor/tracemonkey/jsshell.msg +54 -0
  302. data/vendor/tracemonkey/jsstack.js +167 -0
  303. data/vendor/tracemonkey/jsstaticcheck.h +69 -0
  304. data/vendor/tracemonkey/jsstddef.h +87 -0
  305. data/vendor/tracemonkey/jsstdint.h +96 -0
  306. data/vendor/tracemonkey/jsstr.cpp +5277 -0
  307. data/vendor/tracemonkey/jsstr.h +702 -0
  308. data/vendor/tracemonkey/jstracer.cpp +10991 -0
  309. data/vendor/tracemonkey/jstracer.h +794 -0
  310. data/vendor/tracemonkey/jstypes.h +481 -0
  311. data/vendor/tracemonkey/jsutil.cpp +361 -0
  312. data/vendor/tracemonkey/jsutil.h +178 -0
  313. data/vendor/tracemonkey/jsversion.h +243 -0
  314. data/vendor/tracemonkey/jswince.asm +44 -0
  315. data/vendor/tracemonkey/jsxdrapi.cpp +800 -0
  316. data/vendor/tracemonkey/jsxdrapi.h +220 -0
  317. data/vendor/tracemonkey/jsxml.cpp +8327 -0
  318. data/vendor/tracemonkey/jsxml.h +305 -0
  319. data/vendor/tracemonkey/liveconnect/LiveConnect.dsp +157 -0
  320. data/vendor/tracemonkey/liveconnect/LiveConnectShell.dsp +120 -0
  321. data/vendor/tracemonkey/liveconnect/LiveConnectShell.dsw +44 -0
  322. data/vendor/tracemonkey/liveconnect/Makefile.in +105 -0
  323. data/vendor/tracemonkey/liveconnect/Makefile.ref +169 -0
  324. data/vendor/tracemonkey/liveconnect/README.html +712 -0
  325. data/vendor/tracemonkey/liveconnect/_jni/netscape_javascript_JSException.h +14 -0
  326. data/vendor/tracemonkey/liveconnect/_jni/netscape_javascript_JSObject.h +155 -0
  327. data/vendor/tracemonkey/liveconnect/classes/Makefile.in +89 -0
  328. data/vendor/tracemonkey/liveconnect/classes/Makefile.ref +57 -0
  329. data/vendor/tracemonkey/liveconnect/classes/netscape/Makefile.ref +47 -0
  330. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSException.java +140 -0
  331. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSObject.java +183 -0
  332. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSProxy.java +58 -0
  333. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSRunnable.java +70 -0
  334. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSUtil.java +59 -0
  335. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/Makefile.ref +53 -0
  336. data/vendor/tracemonkey/liveconnect/config/AIX4.1.mk +45 -0
  337. data/vendor/tracemonkey/liveconnect/config/AIX4.2.mk +45 -0
  338. data/vendor/tracemonkey/liveconnect/config/AIX4.3.mk +50 -0
  339. data/vendor/tracemonkey/liveconnect/config/HP-UXB.10.10.mk +43 -0
  340. data/vendor/tracemonkey/liveconnect/config/HP-UXB.10.20.mk +43 -0
  341. data/vendor/tracemonkey/liveconnect/config/HP-UXB.11.00.mk +43 -0
  342. data/vendor/tracemonkey/liveconnect/config/IRIX6.2.mk +43 -0
  343. data/vendor/tracemonkey/liveconnect/config/IRIX6.3.mk +43 -0
  344. data/vendor/tracemonkey/liveconnect/config/IRIX6.5.mk +43 -0
  345. data/vendor/tracemonkey/liveconnect/config/Linux_All.mk +73 -0
  346. data/vendor/tracemonkey/liveconnect/config/OSF1V4.0.mk +65 -0
  347. data/vendor/tracemonkey/liveconnect/config/OSF1V5.0.mk +62 -0
  348. data/vendor/tracemonkey/liveconnect/config/SunOS5.5.1.mk +55 -0
  349. data/vendor/tracemonkey/liveconnect/config/SunOS5.6.mk +39 -0
  350. data/vendor/tracemonkey/liveconnect/config/SunOS5.7.mk +39 -0
  351. data/vendor/tracemonkey/liveconnect/config/SunOS5.8.mk +39 -0
  352. data/vendor/tracemonkey/liveconnect/config/WINNT4.0.mk +53 -0
  353. data/vendor/tracemonkey/liveconnect/jsj.c +886 -0
  354. data/vendor/tracemonkey/liveconnect/jsj.msg +98 -0
  355. data/vendor/tracemonkey/liveconnect/jsj_JSObject.c +1377 -0
  356. data/vendor/tracemonkey/liveconnect/jsj_JavaArray.c +474 -0
  357. data/vendor/tracemonkey/liveconnect/jsj_JavaClass.c +737 -0
  358. data/vendor/tracemonkey/liveconnect/jsj_JavaMember.c +191 -0
  359. data/vendor/tracemonkey/liveconnect/jsj_JavaObject.c +1079 -0
  360. data/vendor/tracemonkey/liveconnect/jsj_JavaPackage.c +569 -0
  361. data/vendor/tracemonkey/liveconnect/jsj_array.c +207 -0
  362. data/vendor/tracemonkey/liveconnect/jsj_class.c +770 -0
  363. data/vendor/tracemonkey/liveconnect/jsj_convert.c +902 -0
  364. data/vendor/tracemonkey/liveconnect/jsj_field.c +421 -0
  365. data/vendor/tracemonkey/liveconnect/jsj_hash.c +488 -0
  366. data/vendor/tracemonkey/liveconnect/jsj_hash.h +161 -0
  367. data/vendor/tracemonkey/liveconnect/jsj_method.c +1825 -0
  368. data/vendor/tracemonkey/liveconnect/jsj_nodl.c +1 -0
  369. data/vendor/tracemonkey/liveconnect/jsj_private.h +677 -0
  370. data/vendor/tracemonkey/liveconnect/jsj_simpleapi.c +219 -0
  371. data/vendor/tracemonkey/liveconnect/jsj_utils.c +513 -0
  372. data/vendor/tracemonkey/liveconnect/jsjava.h +316 -0
  373. data/vendor/tracemonkey/liveconnect/netscape_javascript_JSObject.h +155 -0
  374. data/vendor/tracemonkey/liveconnect/nsCLiveconnect.cpp +785 -0
  375. data/vendor/tracemonkey/liveconnect/nsCLiveconnect.h +197 -0
  376. data/vendor/tracemonkey/liveconnect/nsCLiveconnectFactory.cpp +118 -0
  377. data/vendor/tracemonkey/liveconnect/nsCLiveconnectFactory.h +76 -0
  378. data/vendor/tracemonkey/liveconnect/nsILiveconnect.h +197 -0
  379. data/vendor/tracemonkey/liveconnect/nsISecureLiveconnect.h +94 -0
  380. data/vendor/tracemonkey/liveconnect/nsISecurityContext.h +136 -0
  381. data/vendor/tracemonkey/lock_SunOS.s +119 -0
  382. data/vendor/tracemonkey/mandelbrot-results.js +3 -0
  383. data/vendor/tracemonkey/math-partial-sums.js +32 -0
  384. data/vendor/tracemonkey/math-trace-tests.js +507 -0
  385. data/vendor/tracemonkey/md5.js +289 -0
  386. data/vendor/tracemonkey/nanojit/Assembler.cpp +1984 -0
  387. data/vendor/tracemonkey/nanojit/Assembler.h +375 -0
  388. data/vendor/tracemonkey/nanojit/Fragmento.cpp +651 -0
  389. data/vendor/tracemonkey/nanojit/Fragmento.h +237 -0
  390. data/vendor/tracemonkey/nanojit/LIR.cpp +2314 -0
  391. data/vendor/tracemonkey/nanojit/LIR.h +879 -0
  392. data/vendor/tracemonkey/nanojit/LIRopcode.tbl +252 -0
  393. data/vendor/tracemonkey/nanojit/Native.h +127 -0
  394. data/vendor/tracemonkey/nanojit/NativeARM.cpp +1742 -0
  395. data/vendor/tracemonkey/nanojit/NativeARM.h +844 -0
  396. data/vendor/tracemonkey/nanojit/NativeSparc.cpp +1130 -0
  397. data/vendor/tracemonkey/nanojit/NativeSparc.h +948 -0
  398. data/vendor/tracemonkey/nanojit/NativeThumb.cpp +1322 -0
  399. data/vendor/tracemonkey/nanojit/NativeThumb.h +525 -0
  400. data/vendor/tracemonkey/nanojit/Nativei386.cpp +1748 -0
  401. data/vendor/tracemonkey/nanojit/Nativei386.h +857 -0
  402. data/vendor/tracemonkey/nanojit/RegAlloc.cpp +183 -0
  403. data/vendor/tracemonkey/nanojit/RegAlloc.h +95 -0
  404. data/vendor/tracemonkey/nanojit/TraceTreeDrawer.cpp +306 -0
  405. data/vendor/tracemonkey/nanojit/TraceTreeDrawer.h +88 -0
  406. data/vendor/tracemonkey/nanojit/avmplus.cpp +56 -0
  407. data/vendor/tracemonkey/nanojit/avmplus.h +1016 -0
  408. data/vendor/tracemonkey/nanojit/nanojit.h +253 -0
  409. data/vendor/tracemonkey/perfect.js +39 -0
  410. data/vendor/tracemonkey/plify_jsdhash.sed +35 -0
  411. data/vendor/tracemonkey/prmjtime.cpp +869 -0
  412. data/vendor/tracemonkey/prmjtime.h +103 -0
  413. data/vendor/tracemonkey/ref-config/AIX4.1.mk +65 -0
  414. data/vendor/tracemonkey/ref-config/AIX4.2.mk +64 -0
  415. data/vendor/tracemonkey/ref-config/AIX4.3.mk +65 -0
  416. data/vendor/tracemonkey/ref-config/Darwin.mk +85 -0
  417. data/vendor/tracemonkey/ref-config/Darwin1.3.mk +81 -0
  418. data/vendor/tracemonkey/ref-config/Darwin1.4.mk +41 -0
  419. data/vendor/tracemonkey/ref-config/Darwin5.2.mk +81 -0
  420. data/vendor/tracemonkey/ref-config/Darwin5.3.mk +81 -0
  421. data/vendor/tracemonkey/ref-config/Darwin64.mk +72 -0
  422. data/vendor/tracemonkey/ref-config/HP-UXB.10.10.mk +77 -0
  423. data/vendor/tracemonkey/ref-config/HP-UXB.10.20.mk +77 -0
  424. data/vendor/tracemonkey/ref-config/HP-UXB.11.00.mk +80 -0
  425. data/vendor/tracemonkey/ref-config/IRIX.mk +87 -0
  426. data/vendor/tracemonkey/ref-config/IRIX5.3.mk +44 -0
  427. data/vendor/tracemonkey/ref-config/IRIX6.1.mk +44 -0
  428. data/vendor/tracemonkey/ref-config/IRIX6.2.mk +44 -0
  429. data/vendor/tracemonkey/ref-config/IRIX6.3.mk +44 -0
  430. data/vendor/tracemonkey/ref-config/IRIX6.5.mk +44 -0
  431. data/vendor/tracemonkey/ref-config/Linux_All.mk +105 -0
  432. data/vendor/tracemonkey/ref-config/Mac_OS10.0.mk +82 -0
  433. data/vendor/tracemonkey/ref-config/OSF1V4.0.mk +72 -0
  434. data/vendor/tracemonkey/ref-config/OSF1V5.0.mk +69 -0
  435. data/vendor/tracemonkey/ref-config/SunOS4.1.4.mk +101 -0
  436. data/vendor/tracemonkey/ref-config/SunOS5.10.mk +50 -0
  437. data/vendor/tracemonkey/ref-config/SunOS5.3.mk +91 -0
  438. data/vendor/tracemonkey/ref-config/SunOS5.4.mk +92 -0
  439. data/vendor/tracemonkey/ref-config/SunOS5.5.1.mk +44 -0
  440. data/vendor/tracemonkey/ref-config/SunOS5.5.mk +87 -0
  441. data/vendor/tracemonkey/ref-config/SunOS5.6.mk +89 -0
  442. data/vendor/tracemonkey/ref-config/SunOS5.7.mk +44 -0
  443. data/vendor/tracemonkey/ref-config/SunOS5.8.mk +44 -0
  444. data/vendor/tracemonkey/ref-config/SunOS5.9.mk +44 -0
  445. data/vendor/tracemonkey/ref-config/WINNT4.0.mk +118 -0
  446. data/vendor/tracemonkey/ref-config/WINNT5.0.mk +118 -0
  447. data/vendor/tracemonkey/ref-config/WINNT5.1.mk +118 -0
  448. data/vendor/tracemonkey/ref-config/WINNT5.2.mk +118 -0
  449. data/vendor/tracemonkey/ref-config/WINNT6.0.mk +118 -0
  450. data/vendor/tracemonkey/ref-config/dgux.mk +64 -0
  451. data/vendor/tracemonkey/resource.h +15 -0
  452. data/vendor/tracemonkey/rules.mk +206 -0
  453. data/vendor/tracemonkey/shell/Makefile.in +72 -0
  454. data/vendor/tracemonkey/shell/js.cpp +4719 -0
  455. data/vendor/tracemonkey/t/3d-cube.js +337 -0
  456. data/vendor/tracemonkey/t/3d-morph.js +54 -0
  457. data/vendor/tracemonkey/t/3d-raytrace.js +441 -0
  458. data/vendor/tracemonkey/t/access-binary-trees.js +50 -0
  459. data/vendor/tracemonkey/t/access-fannkuch.js +66 -0
  460. data/vendor/tracemonkey/t/access-nbody.js +169 -0
  461. data/vendor/tracemonkey/t/access-nsieve.js +38 -0
  462. data/vendor/tracemonkey/t/bitops-3bit-bits-in-byte.js +32 -0
  463. data/vendor/tracemonkey/t/bitops-bits-in-byte.js +21 -0
  464. data/vendor/tracemonkey/t/bitops-bitwise-and.js +28 -0
  465. data/vendor/tracemonkey/t/bitops-nsieve-bits.js +32 -0
  466. data/vendor/tracemonkey/t/controlflow-recursive.js +25 -0
  467. data/vendor/tracemonkey/t/crypto-aes.js +422 -0
  468. data/vendor/tracemonkey/t/crypto-md5.js +286 -0
  469. data/vendor/tracemonkey/t/crypto-sha1.js +224 -0
  470. data/vendor/tracemonkey/t/date-format-tofte.js +299 -0
  471. data/vendor/tracemonkey/t/date-format-xparb.js +417 -0
  472. data/vendor/tracemonkey/t/math-cordic.js +95 -0
  473. data/vendor/tracemonkey/t/math-partial-sums.js +33 -0
  474. data/vendor/tracemonkey/t/math-spectral-norm.js +51 -0
  475. data/vendor/tracemonkey/t/regexp-dna.js +1712 -0
  476. data/vendor/tracemonkey/t/string-base64.js +135 -0
  477. data/vendor/tracemonkey/t/string-fasta.js +85 -0
  478. data/vendor/tracemonkey/t/string-tagcloud.js +265 -0
  479. data/vendor/tracemonkey/t/string-unpack-code.js +68 -0
  480. data/vendor/tracemonkey/t/string-validate-input.js +89 -0
  481. data/vendor/tracemonkey/time.sh +13 -0
  482. data/vendor/tracemonkey/trace-test.js +5564 -0
  483. data/vendor/tracemonkey/v8/base.js +187 -0
  484. data/vendor/tracemonkey/v8/crypto.js +1689 -0
  485. data/vendor/tracemonkey/v8/deltablue.js +880 -0
  486. data/vendor/tracemonkey/v8/earley-boyer.js +4682 -0
  487. data/vendor/tracemonkey/v8/raytrace.js +3418 -0
  488. data/vendor/tracemonkey/v8/richards.js +539 -0
  489. data/vendor/tracemonkey/v8/run-crypto.js +44 -0
  490. data/vendor/tracemonkey/v8/run-deltablue.js +44 -0
  491. data/vendor/tracemonkey/v8/run-earley-boyer.js +44 -0
  492. data/vendor/tracemonkey/v8/run-raytrace.js +44 -0
  493. data/vendor/tracemonkey/v8/run-richards.js +44 -0
  494. data/vendor/tracemonkey/v8/run.js +49 -0
  495. data/vendor/tracemonkey/vprof/readme.txt +93 -0
  496. data/vendor/tracemonkey/vprof/vprof.cpp +360 -0
  497. data/vendor/tracemonkey/vprof/vprof.h +245 -0
  498. data/vendor/tracemonkey/xpconnect/Makefile.in +67 -0
  499. data/vendor/tracemonkey/xpconnect/crashtests/117307-1.html +20 -0
  500. data/vendor/tracemonkey/xpconnect/crashtests/193710.html +11 -0
  501. data/vendor/tracemonkey/xpconnect/crashtests/290162-1.html +5 -0
  502. data/vendor/tracemonkey/xpconnect/crashtests/326615-1.html +16 -0
  503. data/vendor/tracemonkey/xpconnect/crashtests/328553-1.html +13 -0
  504. data/vendor/tracemonkey/xpconnect/crashtests/346258-1.html +12 -0
  505. data/vendor/tracemonkey/xpconnect/crashtests/346512-1-frame1.xhtml +16 -0
  506. data/vendor/tracemonkey/xpconnect/crashtests/346512-1-frame2.xhtml +15 -0
  507. data/vendor/tracemonkey/xpconnect/crashtests/346512-1.xhtml +30 -0
  508. data/vendor/tracemonkey/xpconnect/crashtests/382133-1.html +3 -0
  509. data/vendor/tracemonkey/xpconnect/crashtests/386680-1.html +22 -0
  510. data/vendor/tracemonkey/xpconnect/crashtests/394810-1.html +4 -0
  511. data/vendor/tracemonkey/xpconnect/crashtests/400349-1.html +20 -0
  512. data/vendor/tracemonkey/xpconnect/crashtests/403356-1.html +13 -0
  513. data/vendor/tracemonkey/xpconnect/crashtests/418139-1.svg +22 -0
  514. data/vendor/tracemonkey/xpconnect/crashtests/420513-1.html +11 -0
  515. data/vendor/tracemonkey/xpconnect/crashtests/453935-1.html +37 -0
  516. data/vendor/tracemonkey/xpconnect/crashtests/462926.html +12 -0
  517. data/vendor/tracemonkey/xpconnect/crashtests/468552-1.html +18 -0
  518. data/vendor/tracemonkey/xpconnect/crashtests/471366-1.html +12 -0
  519. data/vendor/tracemonkey/xpconnect/crashtests/475185-1.html +13 -0
  520. data/vendor/tracemonkey/xpconnect/crashtests/475291-1.html +14 -0
  521. data/vendor/tracemonkey/xpconnect/crashtests/503286-1.html +23 -0
  522. data/vendor/tracemonkey/xpconnect/crashtests/crashtests.list +21 -0
  523. data/vendor/tracemonkey/xpconnect/idl/Makefile.in +78 -0
  524. data/vendor/tracemonkey/xpconnect/idl/XPCIDispatch.idl +51 -0
  525. data/vendor/tracemonkey/xpconnect/idl/mozIJSSubScriptLoader.idl +64 -0
  526. data/vendor/tracemonkey/xpconnect/idl/nsIActiveXSecurityPolicy.idl +67 -0
  527. data/vendor/tracemonkey/xpconnect/idl/nsIDispatchSupport.idl +119 -0
  528. data/vendor/tracemonkey/xpconnect/idl/nsIJSContextStack.idl +85 -0
  529. data/vendor/tracemonkey/xpconnect/idl/nsIJSRuntimeService.idl +51 -0
  530. data/vendor/tracemonkey/xpconnect/idl/nsIScriptError.idl +102 -0
  531. data/vendor/tracemonkey/xpconnect/idl/nsIScriptableInterfaces.idl +67 -0
  532. data/vendor/tracemonkey/xpconnect/idl/nsIXPCScriptNotify.idl +66 -0
  533. data/vendor/tracemonkey/xpconnect/idl/nsIXPCScriptable.idl +183 -0
  534. data/vendor/tracemonkey/xpconnect/idl/nsIXPCSecurityManager.idl +114 -0
  535. data/vendor/tracemonkey/xpconnect/idl/nsIXPConnect.idl +819 -0
  536. data/vendor/tracemonkey/xpconnect/idl/xpcIJSModuleLoader.idl +95 -0
  537. data/vendor/tracemonkey/xpconnect/idl/xpcIJSWeakReference.idl +49 -0
  538. data/vendor/tracemonkey/xpconnect/idl/xpccomponents.idl +254 -0
  539. data/vendor/tracemonkey/xpconnect/idl/xpcexception.idl +66 -0
  540. data/vendor/tracemonkey/xpconnect/idl/xpcjsid.idl +83 -0
  541. data/vendor/tracemonkey/xpconnect/loader/ISO8601DateUtils.jsm +176 -0
  542. data/vendor/tracemonkey/xpconnect/loader/Makefile.in +63 -0
  543. data/vendor/tracemonkey/xpconnect/loader/XPCOMUtils.jsm +267 -0
  544. data/vendor/tracemonkey/xpconnect/loader/mozJSComponentLoader.cpp +1717 -0
  545. data/vendor/tracemonkey/xpconnect/loader/mozJSComponentLoader.h +172 -0
  546. data/vendor/tracemonkey/xpconnect/loader/mozJSLoaderConstructors.h +101 -0
  547. data/vendor/tracemonkey/xpconnect/loader/mozJSSubScriptLoader.cpp +360 -0
  548. data/vendor/tracemonkey/xpconnect/loader/mozJSSubScriptLoader.h +66 -0
  549. data/vendor/tracemonkey/xpconnect/public/Makefile.in +54 -0
  550. data/vendor/tracemonkey/xpconnect/public/nsAXPCNativeCallContext.h +89 -0
  551. data/vendor/tracemonkey/xpconnect/public/nsAutoJSValHolder.h +168 -0
  552. data/vendor/tracemonkey/xpconnect/public/xpc_map_end.h +327 -0
  553. data/vendor/tracemonkey/xpconnect/sample/Makefile.in +71 -0
  554. data/vendor/tracemonkey/xpconnect/sample/README +39 -0
  555. data/vendor/tracemonkey/xpconnect/sample/xpcsample1.cpp +337 -0
  556. data/vendor/tracemonkey/xpconnect/sample/xpcsample1.idl +82 -0
  557. data/vendor/tracemonkey/xpconnect/sample/xpcsample1.js +21 -0
  558. data/vendor/tracemonkey/xpconnect/shell/Makefile.in +106 -0
  559. data/vendor/tracemonkey/xpconnect/shell/jsshell.msg +50 -0
  560. data/vendor/tracemonkey/xpconnect/shell/xpcshell.cpp +1817 -0
  561. data/vendor/tracemonkey/xpconnect/shell/xpcshellMacUtils.h +43 -0
  562. data/vendor/tracemonkey/xpconnect/shell/xpcshellMacUtils.mm +54 -0
  563. data/vendor/tracemonkey/xpconnect/src/Makefile.in +228 -0
  564. data/vendor/tracemonkey/xpconnect/src/README +3 -0
  565. data/vendor/tracemonkey/xpconnect/src/XPCCrossOriginWrapper.cpp +1186 -0
  566. data/vendor/tracemonkey/xpconnect/src/XPCDispConvert.cpp +593 -0
  567. data/vendor/tracemonkey/xpconnect/src/XPCDispInlines.h +667 -0
  568. data/vendor/tracemonkey/xpconnect/src/XPCDispInterface.cpp +383 -0
  569. data/vendor/tracemonkey/xpconnect/src/XPCDispObject.cpp +516 -0
  570. data/vendor/tracemonkey/xpconnect/src/XPCDispParamPropJSClass.cpp +223 -0
  571. data/vendor/tracemonkey/xpconnect/src/XPCDispParams.cpp +103 -0
  572. data/vendor/tracemonkey/xpconnect/src/XPCDispPrivate.h +1401 -0
  573. data/vendor/tracemonkey/xpconnect/src/XPCDispTearOff.cpp +547 -0
  574. data/vendor/tracemonkey/xpconnect/src/XPCDispTypeInfo.cpp +471 -0
  575. data/vendor/tracemonkey/xpconnect/src/XPCIDispatchClassInfo.cpp +139 -0
  576. data/vendor/tracemonkey/xpconnect/src/XPCIDispatchExtension.cpp +362 -0
  577. data/vendor/tracemonkey/xpconnect/src/XPCNativeWrapper.cpp +1350 -0
  578. data/vendor/tracemonkey/xpconnect/src/XPCNativeWrapper.h +88 -0
  579. data/vendor/tracemonkey/xpconnect/src/XPCSafeJSObjectWrapper.cpp +1148 -0
  580. data/vendor/tracemonkey/xpconnect/src/XPCSystemOnlyWrapper.cpp +718 -0
  581. data/vendor/tracemonkey/xpconnect/src/XPCWrapper.cpp +850 -0
  582. data/vendor/tracemonkey/xpconnect/src/XPCWrapper.h +394 -0
  583. data/vendor/tracemonkey/xpconnect/src/dom_quickstubs.qsconf +568 -0
  584. data/vendor/tracemonkey/xpconnect/src/nsDispatchSupport.cpp +348 -0
  585. data/vendor/tracemonkey/xpconnect/src/nsScriptError.cpp +201 -0
  586. data/vendor/tracemonkey/xpconnect/src/nsXPConnect.cpp +2609 -0
  587. data/vendor/tracemonkey/xpconnect/src/qsgen.py +1487 -0
  588. data/vendor/tracemonkey/xpconnect/src/xpc.msg +217 -0
  589. data/vendor/tracemonkey/xpconnect/src/xpcJSWeakReference.cpp +148 -0
  590. data/vendor/tracemonkey/xpconnect/src/xpcJSWeakReference.h +56 -0
  591. data/vendor/tracemonkey/xpconnect/src/xpccallcontext.cpp +579 -0
  592. data/vendor/tracemonkey/xpconnect/src/xpccomponents.cpp +4144 -0
  593. data/vendor/tracemonkey/xpconnect/src/xpccontext.cpp +115 -0
  594. data/vendor/tracemonkey/xpconnect/src/xpcconvert.cpp +2298 -0
  595. data/vendor/tracemonkey/xpconnect/src/xpcdebug.cpp +481 -0
  596. data/vendor/tracemonkey/xpconnect/src/xpcexception.cpp +502 -0
  597. data/vendor/tracemonkey/xpconnect/src/xpcforwards.h +114 -0
  598. data/vendor/tracemonkey/xpconnect/src/xpcinlines.h +772 -0
  599. data/vendor/tracemonkey/xpconnect/src/xpcjsid.cpp +1025 -0
  600. data/vendor/tracemonkey/xpconnect/src/xpcjsruntime.cpp +1342 -0
  601. data/vendor/tracemonkey/xpconnect/src/xpclog.cpp +128 -0
  602. data/vendor/tracemonkey/xpconnect/src/xpclog.h +101 -0
  603. data/vendor/tracemonkey/xpconnect/src/xpcmaps.cpp +761 -0
  604. data/vendor/tracemonkey/xpconnect/src/xpcmaps.h +713 -0
  605. data/vendor/tracemonkey/xpconnect/src/xpcmodule.cpp +136 -0
  606. data/vendor/tracemonkey/xpconnect/src/xpcprivate.h +4138 -0
  607. data/vendor/tracemonkey/xpconnect/src/xpcquickstubs.cpp +1128 -0
  608. data/vendor/tracemonkey/xpconnect/src/xpcquickstubs.h +480 -0
  609. data/vendor/tracemonkey/xpconnect/src/xpcruntimesvc.cpp +179 -0
  610. data/vendor/tracemonkey/xpconnect/src/xpcstack.cpp +342 -0
  611. data/vendor/tracemonkey/xpconnect/src/xpcstring.cpp +139 -0
  612. data/vendor/tracemonkey/xpconnect/src/xpcthreadcontext.cpp +599 -0
  613. data/vendor/tracemonkey/xpconnect/src/xpcthrower.cpp +399 -0
  614. data/vendor/tracemonkey/xpconnect/src/xpcvariant.cpp +850 -0
  615. data/vendor/tracemonkey/xpconnect/src/xpcwrappedjs.cpp +670 -0
  616. data/vendor/tracemonkey/xpconnect/src/xpcwrappedjsclass.cpp +2015 -0
  617. data/vendor/tracemonkey/xpconnect/src/xpcwrappednative.cpp +3482 -0
  618. data/vendor/tracemonkey/xpconnect/src/xpcwrappednativeinfo.cpp +945 -0
  619. data/vendor/tracemonkey/xpconnect/src/xpcwrappednativejsops.cpp +2003 -0
  620. data/vendor/tracemonkey/xpconnect/src/xpcwrappednativeproto.cpp +302 -0
  621. data/vendor/tracemonkey/xpconnect/src/xpcwrappednativescope.cpp +991 -0
  622. data/vendor/tracemonkey/xpconnect/tests/Makefile.in +75 -0
  623. data/vendor/tracemonkey/xpconnect/tests/TestXPC.cpp +785 -0
  624. data/vendor/tracemonkey/xpconnect/tests/chrome/Makefile.in +51 -0
  625. data/vendor/tracemonkey/xpconnect/tests/chrome/test_bug500931.xul +43 -0
  626. data/vendor/tracemonkey/xpconnect/tests/components/Makefile.in +85 -0
  627. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_array.cpp +388 -0
  628. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_attributes.cpp +305 -0
  629. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_calljs.cpp +135 -0
  630. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_child.cpp +225 -0
  631. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_const.cpp +76 -0
  632. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_domstring.cpp +118 -0
  633. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_echo.cpp +616 -0
  634. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_in.cpp +204 -0
  635. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_inout.cpp +171 -0
  636. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_module.cpp +77 -0
  637. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_multiple.cpp +554 -0
  638. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_noisy.cpp +154 -0
  639. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_out.cpp +335 -0
  640. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_overloaded.cpp +250 -0
  641. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_private.h +192 -0
  642. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_string.cpp +185 -0
  643. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_variant.cpp +355 -0
  644. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/StdAfx.cpp +12 -0
  645. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/StdAfx.h +28 -0
  646. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCDispUtilities.h +28 -0
  647. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.cpp +86 -0
  648. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.def +9 -0
  649. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.dsp +318 -0
  650. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.dsw +29 -0
  651. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.idl +454 -0
  652. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.rc +145 -0
  653. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispSimple.cpp +44 -0
  654. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispSimple.h +56 -0
  655. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispSimple.rgs +23 -0
  656. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestArrays.cpp +221 -0
  657. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestArrays.h +53 -0
  658. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestArrays.rgs +23 -0
  659. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestMethods.cpp +699 -0
  660. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestMethods.h +138 -0
  661. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestMethods.rgs +23 -0
  662. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestNoIDispatch.cpp +23 -0
  663. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestNoIDispatch.h +41 -0
  664. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestNoIDispatch.rgs +23 -0
  665. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestProperties.cpp +256 -0
  666. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestProperties.h +88 -0
  667. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestProperties.rgs +23 -0
  668. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOff.cpp +23 -0
  669. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOff.h +43 -0
  670. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOff.rgs +23 -0
  671. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOn.cpp +29 -0
  672. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOn.h +45 -0
  673. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOn.rgs +23 -0
  674. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestWrappedJS.cpp +177 -0
  675. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestWrappedJS.h +50 -0
  676. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestWrappedJS.rgs +23 -0
  677. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/resource.h +36 -0
  678. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/Arrays/XPCIDispatchArrayTests.js +54 -0
  679. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/Attributes/XPCIDispatchAttributeTests.js +150 -0
  680. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/General/XPCIDispatchInstantiations.js +122 -0
  681. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/General/XPCStress.js +58 -0
  682. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/Methods/XPCIDispatchMethodTests.js +376 -0
  683. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/shell.js +377 -0
  684. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedJS/General/XPCIDispatchTestWrappedJS.js +76 -0
  685. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedJS/shell.js +377 -0
  686. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/exectests.cmd +1 -0
  687. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/jsDriver.pl +1288 -0
  688. data/vendor/tracemonkey/xpconnect/tests/idl/Makefile.in +61 -0
  689. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest.idl +312 -0
  690. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest2.idl +51 -0
  691. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_attributes.idl +67 -0
  692. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_calljs.idl +59 -0
  693. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_const.idl +61 -0
  694. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_domstring.idl +59 -0
  695. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_in.idl +88 -0
  696. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_inout.idl +86 -0
  697. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_multiple.idl +77 -0
  698. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_out.idl +142 -0
  699. data/vendor/tracemonkey/xpconnect/tests/js/checkid.js +82 -0
  700. data/vendor/tracemonkey/xpconnect/tests/js/evaluate.js +311 -0
  701. data/vendor/tracemonkey/xpconnect/tests/js/exceptions-2.js +153 -0
  702. data/vendor/tracemonkey/xpconnect/tests/js/exceptions-3.js +194 -0
  703. data/vendor/tracemonkey/xpconnect/tests/js/exceptions-4.js +297 -0
  704. data/vendor/tracemonkey/xpconnect/tests/js/exceptions-5.js +343 -0
  705. data/vendor/tracemonkey/xpconnect/tests/js/exceptions.js +230 -0
  706. data/vendor/tracemonkey/xpconnect/tests/js/javascript.js +96 -0
  707. data/vendor/tracemonkey/xpconnect/tests/js/multiple-2.js +151 -0
  708. data/vendor/tracemonkey/xpconnect/tests/js/multiple-3.js +148 -0
  709. data/vendor/tracemonkey/xpconnect/tests/js/multiple-4.js +152 -0
  710. data/vendor/tracemonkey/xpconnect/tests/js/multiple.js +137 -0
  711. data/vendor/tracemonkey/xpconnect/tests/js/notscriptable.js +104 -0
  712. data/vendor/tracemonkey/xpconnect/tests/js/old/simpletest.js +36 -0
  713. data/vendor/tracemonkey/xpconnect/tests/js/old/speed.js +60 -0
  714. data/vendor/tracemonkey/xpconnect/tests/js/old/testxpc.js +464 -0
  715. data/vendor/tracemonkey/xpconnect/tests/js/old/threads.js +74 -0
  716. data/vendor/tracemonkey/xpconnect/tests/js/old/try.js +27 -0
  717. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_array.js +308 -0
  718. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_callcontext.js +68 -0
  719. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_echo.js +636 -0
  720. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_enum_and_sort.js +28 -0
  721. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_enum_constants.js +15 -0
  722. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_enum_create.js +200 -0
  723. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_exceptions.js +167 -0
  724. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_ids.js +135 -0
  725. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_observer.js +36 -0
  726. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_overloaded.js +14 -0
  727. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_primitives.js +141 -0
  728. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_propertybag.js +36 -0
  729. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_variant.js +339 -0
  730. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_variant_array.js +30 -0
  731. data/vendor/tracemonkey/xpconnect/tests/js/readonlyattributes.js +74 -0
  732. data/vendor/tracemonkey/xpconnect/tests/js/readwriteattributes.js +101 -0
  733. data/vendor/tracemonkey/xpconnect/tests/js/scriptable.js +120 -0
  734. data/vendor/tracemonkey/xpconnect/tests/js/testin.js +203 -0
  735. data/vendor/tracemonkey/xpconnect/tests/js/xpcfun.js +234 -0
  736. data/vendor/tracemonkey/xpconnect/tests/js/xpctest_primitives.js +200 -0
  737. data/vendor/tracemonkey/xpconnect/tests/mochitest/Makefile.in +66 -0
  738. data/vendor/tracemonkey/xpconnect/tests/mochitest/bug500931_helper.html +7 -0
  739. data/vendor/tracemonkey/xpconnect/tests/mochitest/inner.html +7 -0
  740. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug361111.xul +29 -0
  741. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug384632.html +32 -0
  742. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug390488.html +65 -0
  743. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug393269.html +46 -0
  744. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug396851.html +43 -0
  745. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug428021.html +41 -0
  746. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug446584.html +49 -0
  747. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug448587.html +31 -0
  748. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug462428.html +42 -0
  749. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug478438.html +66 -0
  750. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug484107.html +100 -0
  751. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug484459.html +36 -0
  752. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug500691.html +28 -0
  753. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_wrappers.html +116 -0
  754. data/vendor/tracemonkey/xpconnect/tests/unit/bogus_element_type.jsm +1 -0
  755. data/vendor/tracemonkey/xpconnect/tests/unit/bogus_exports_type.jsm +1 -0
  756. data/vendor/tracemonkey/xpconnect/tests/unit/bug451678_subscript.js +2 -0
  757. data/vendor/tracemonkey/xpconnect/tests/unit/component_import.js +144 -0
  758. data/vendor/tracemonkey/xpconnect/tests/unit/recursive_importA.jsm +44 -0
  759. data/vendor/tracemonkey/xpconnect/tests/unit/recursive_importB.jsm +45 -0
  760. data/vendor/tracemonkey/xpconnect/tests/unit/syntax_error.jsm +1 -0
  761. data/vendor/tracemonkey/xpconnect/tests/unit/test_bogus_files.js +88 -0
  762. data/vendor/tracemonkey/xpconnect/tests/unit/test_bug408412.js +51 -0
  763. data/vendor/tracemonkey/xpconnect/tests/unit/test_bug451678.js +52 -0
  764. data/vendor/tracemonkey/xpconnect/tests/unit/test_bug_442086.js +68 -0
  765. data/vendor/tracemonkey/xpconnect/tests/unit/test_import.js +127 -0
  766. data/vendor/tracemonkey/xpconnect/tests/unit/test_js_weak_references.js +63 -0
  767. data/vendor/tracemonkey/xpconnect/tests/unit/test_recursive_import.js +62 -0
  768. data/vendor/tracemonkey/xpconnect/tools/Makefile.in +49 -0
  769. data/vendor/tracemonkey/xpconnect/tools/idl/Makefile.in +53 -0
  770. data/vendor/tracemonkey/xpconnect/tools/idl/nsIXPCToolsCompiler.idl +60 -0
  771. data/vendor/tracemonkey/xpconnect/tools/idl/nsIXPCToolsProfiler.idl +57 -0
  772. data/vendor/tracemonkey/xpconnect/tools/js/CompileJSFiles.js +28 -0
  773. data/vendor/tracemonkey/xpconnect/tools/js/ListJSFiles.js +18 -0
  774. data/vendor/tracemonkey/xpconnect/tools/src/Makefile.in +76 -0
  775. data/vendor/tracemonkey/xpconnect/tools/src/nsXPCToolsCompiler.cpp +161 -0
  776. data/vendor/tracemonkey/xpconnect/tools/src/nsXPCToolsModule.cpp +65 -0
  777. data/vendor/tracemonkey/xpconnect/tools/src/nsXPCToolsProfiler.cpp +370 -0
  778. data/vendor/tracemonkey/xpconnect/tools/src/xpctools_private.h +236 -0
  779. metadata +782 -107
  780. data/test/johnson/nodes/export_test.rb +0 -9
  781. data/test/johnson/nodes/import_test.rb +0 -13
  782. data/test/johnson/version_test.rb +0 -13
@@ -0,0 +1,69 @@
1
+ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2
+ *
3
+ * ***** BEGIN LICENSE BLOCK *****
4
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5
+ *
6
+ * The contents of this file are subject to the Mozilla Public License Version
7
+ * 1.1 (the "License"); you may not use this file except in compliance with
8
+ * the License. You may obtain a copy of the License at
9
+ * http://www.mozilla.org/MPL/
10
+ *
11
+ * Software distributed under the License is distributed on an "AS IS" basis,
12
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13
+ * for the specific language governing rights and limitations under the
14
+ * License.
15
+ *
16
+ * The Original Code is Mozilla Communicator client code, released
17
+ * March 31, 1998.
18
+ *
19
+ * The Initial Developer of the Original Code is
20
+ * Netscape Communications Corporation.
21
+ * Portions created by the Initial Developer are Copyright (C) 1998
22
+ * the Initial Developer. All Rights Reserved.
23
+ *
24
+ * Contributor(s):
25
+ * IBM Corp.
26
+ *
27
+ * Alternatively, the contents of this file may be used under the terms of
28
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
29
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30
+ * in which case the provisions of the GPL or the LGPL are applicable instead
31
+ * of those above. If you wish to allow use of your version of this file only
32
+ * under the terms of either the GPL or the LGPL, and not to allow others to
33
+ * use your version of this file under the terms of the MPL, indicate your
34
+ * decision by deleting the provisions above and replace them with the notice
35
+ * and other provisions required by the GPL or the LGPL. If you do not delete
36
+ * the provisions above, a recipient may use your version of this file under
37
+ * the terms of any one of the MPL, the GPL or the LGPL.
38
+ *
39
+ * ***** END LICENSE BLOCK ***** */
40
+
41
+ #ifndef _LIBMATH_H
42
+ #define _LIBMATH_H
43
+
44
+ #include <math.h>
45
+ #include "jsversion.h"
46
+
47
+ /*
48
+ * Use system provided math routines.
49
+ */
50
+
51
+ /* The right copysign function is not always named the same thing. */
52
+ #if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
53
+ #define js_copysign __builtin_copysign
54
+ #elif defined WINCE
55
+ #define js_copysign _copysign
56
+ #elif defined _WIN32
57
+ #if _MSC_VER < 1400
58
+ /* Try to work around apparent _copysign bustage in VC6 and VC7. */
59
+ #define js_copysign js_copysign
60
+ extern double js_copysign(double, double);
61
+ #else
62
+ #define js_copysign _copysign
63
+ #endif
64
+ #else
65
+ #define js_copysign copysign
66
+ #endif
67
+
68
+ #endif /* _LIBMATH_H */
69
+
@@ -0,0 +1,1512 @@
1
+ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2
+ *
3
+ * ***** BEGIN LICENSE BLOCK *****
4
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5
+ *
6
+ * The contents of this file are subject to the Mozilla Public License Version
7
+ * 1.1 (the "License"); you may not use this file except in compliance with
8
+ * the License. You may obtain a copy of the License at
9
+ * http://www.mozilla.org/MPL/
10
+ *
11
+ * Software distributed under the License is distributed on an "AS IS" basis,
12
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13
+ * for the specific language governing rights and limitations under the
14
+ * License.
15
+ *
16
+ * The Original Code is Mozilla Communicator client code, released
17
+ * March 31, 1998.
18
+ *
19
+ * The Initial Developer of the Original Code is
20
+ * Netscape Communications Corporation.
21
+ * Portions created by the Initial Developer are Copyright (C) 1998
22
+ * the Initial Developer. All Rights Reserved.
23
+ *
24
+ * Contributor(s):
25
+ *
26
+ * Alternatively, the contents of this file may be used under the terms of
27
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
28
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29
+ * in which case the provisions of the GPL or the LGPL are applicable instead
30
+ * of those above. If you wish to allow use of your version of this file only
31
+ * under the terms of either the GPL or the LGPL, and not to allow others to
32
+ * use your version of this file under the terms of the MPL, indicate your
33
+ * decision by deleting the provisions above and replace them with the notice
34
+ * and other provisions required by the GPL or the LGPL. If you do not delete
35
+ * the provisions above, a recipient may use your version of this file under
36
+ * the terms of any one of the MPL, the GPL or the LGPL.
37
+ *
38
+ * ***** END LICENSE BLOCK ***** */
39
+
40
+ #ifdef JS_THREADSAFE
41
+
42
+ /*
43
+ * JS locking stubs.
44
+ */
45
+ #include "jsstddef.h"
46
+ #include <stdlib.h>
47
+ #include <string.h>
48
+ #include "jspubtd.h"
49
+ #include "jsutil.h" /* Added by JSIFY */
50
+ #include "jstypes.h"
51
+ #include "jsbit.h"
52
+ #include "jscntxt.h"
53
+ #include "jsdtoa.h"
54
+ #include "jsgc.h"
55
+ #include "jsfun.h" /* for VALUE_IS_FUNCTION used by *_WRITE_BARRIER */
56
+ #include "jslock.h"
57
+ #include "jsscope.h"
58
+ #include "jsstr.h"
59
+
60
+ #define ReadWord(W) (W)
61
+
62
+ /* Implement NativeCompareAndSwap. */
63
+
64
+ #if defined(_WIN32) && defined(_M_IX86)
65
+ #pragma warning( disable : 4035 )
66
+ JS_BEGIN_EXTERN_C
67
+ extern long __cdecl
68
+ _InterlockedCompareExchange(long *volatile dest, long exchange, long comp);
69
+ JS_END_EXTERN_C
70
+ #pragma intrinsic(_InterlockedCompareExchange)
71
+
72
+ JS_STATIC_ASSERT(sizeof(jsword) == sizeof(long));
73
+
74
+ static JS_ALWAYS_INLINE int
75
+ NativeCompareAndSwapHelper(jsword *w, jsword ov, jsword nv)
76
+ {
77
+ _InterlockedCompareExchange((long*) w, nv, ov);
78
+ __asm {
79
+ sete al
80
+ }
81
+ }
82
+
83
+ static JS_ALWAYS_INLINE int
84
+ NativeCompareAndSwap(jsword *w, jsword ov, jsword nv)
85
+ {
86
+ return (NativeCompareAndSwapHelper(w, ov, nv) & 1);
87
+ }
88
+
89
+ #elif defined(XP_MACOSX) || defined(DARWIN)
90
+
91
+ #include <libkern/OSAtomic.h>
92
+
93
+ static JS_ALWAYS_INLINE int
94
+ NativeCompareAndSwap(jsword *w, jsword ov, jsword nv)
95
+ {
96
+ /* Details on these functions available in the manpage for atomic */
97
+ return OSAtomicCompareAndSwapPtrBarrier(ov, nv, w);
98
+ }
99
+
100
+ #elif defined(__GNUC__) && defined(__i386__)
101
+
102
+ /* Note: This fails on 386 cpus, cmpxchgl is a >= 486 instruction */
103
+ static JS_ALWAYS_INLINE int
104
+ NativeCompareAndSwap(jsword *w, jsword ov, jsword nv)
105
+ {
106
+ unsigned int res;
107
+
108
+ __asm__ __volatile__ (
109
+ "lock\n"
110
+ "cmpxchgl %2, (%1)\n"
111
+ "sete %%al\n"
112
+ "andl $1, %%eax\n"
113
+ : "=a" (res)
114
+ : "r" (w), "r" (nv), "a" (ov)
115
+ : "cc", "memory");
116
+ return (int)res;
117
+ }
118
+
119
+ #elif defined(__GNUC__) && defined(__x86_64__)
120
+ static JS_ALWAYS_INLINE int
121
+ NativeCompareAndSwap(jsword *w, jsword ov, jsword nv)
122
+ {
123
+ unsigned int res;
124
+
125
+ __asm__ __volatile__ (
126
+ "lock\n"
127
+ "cmpxchgq %2, (%1)\n"
128
+ "sete %%al\n"
129
+ "movzbl %%al, %%eax\n"
130
+ : "=a" (res)
131
+ : "r" (w), "r" (nv), "a" (ov)
132
+ : "cc", "memory");
133
+ return (int)res;
134
+ }
135
+
136
+ #elif defined(SOLARIS) && defined(sparc) && defined(ULTRA_SPARC)
137
+
138
+ static JS_ALWAYS_INLINE int
139
+ NativeCompareAndSwap(jsword *w, jsword ov, jsword nv)
140
+ {
141
+ #if defined(__GNUC__)
142
+ unsigned int res;
143
+ JS_ASSERT(ov != nv);
144
+ asm volatile ("\
145
+ stbar\n\
146
+ cas [%1],%2,%3\n\
147
+ cmp %2,%3\n\
148
+ be,a 1f\n\
149
+ mov 1,%0\n\
150
+ mov 0,%0\n\
151
+ 1:"
152
+ : "=r" (res)
153
+ : "r" (w), "r" (ov), "r" (nv));
154
+ return (int)res;
155
+ #else /* !__GNUC__ */
156
+ extern int compare_and_swap(jsword*, jsword, jsword);
157
+ JS_ASSERT(ov != nv);
158
+ return compare_and_swap(w, ov, nv);
159
+ #endif
160
+ }
161
+
162
+ #elif defined(AIX)
163
+
164
+ #include <sys/atomic_op.h>
165
+
166
+ static JS_ALWAYS_INLINE int
167
+ NativeCompareAndSwap(jsword *w, jsword ov, jsword nv)
168
+ {
169
+ return !_check_lock((atomic_p)w, ov, nv);
170
+ }
171
+
172
+ #elif defined(USE_ARM_KUSER)
173
+
174
+ /* See https://bugzilla.mozilla.org/show_bug.cgi?id=429387 for a
175
+ * description of this ABI; this is a function provided at a fixed
176
+ * location by the kernel in the memory space of each process.
177
+ */
178
+ typedef int (__kernel_cmpxchg_t)(int oldval, int newval, volatile int *ptr);
179
+ #define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0)
180
+
181
+ JS_STATIC_ASSERT(sizeof(jsword) == sizeof(int));
182
+
183
+ static JS_ALWAYS_INLINE int
184
+ NativeCompareAndSwap(jsword *w, jsword ov, jsword nv)
185
+ {
186
+ volatile int *vp = (volatile int *) w;
187
+ PRInt32 failed = 1;
188
+
189
+ /* Loop until a __kernel_cmpxchg succeeds. See bug 446169 */
190
+ do {
191
+ failed = __kernel_cmpxchg(ov, nv, vp);
192
+ } while (failed && *vp == ov);
193
+ return !failed;
194
+ }
195
+
196
+ #elif JS_HAS_NATIVE_COMPARE_AND_SWAP
197
+
198
+ #error "JS_HAS_NATIVE_COMPARE_AND_SWAP should be 0 if your platform lacks a compare-and-swap instruction."
199
+
200
+ #endif /* arch-tests */
201
+
202
+ #if JS_HAS_NATIVE_COMPARE_AND_SWAP
203
+
204
+ JSBool
205
+ js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
206
+ {
207
+ return !!NativeCompareAndSwap(w, ov, nv);
208
+ }
209
+
210
+ #elif defined(NSPR_LOCK)
211
+
212
+ # ifdef __GNUC__
213
+ # warning "js_CompareAndSwap is implemented using NSSP lock"
214
+ # endif
215
+
216
+ JSBool
217
+ js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
218
+ {
219
+ int result;
220
+ static PRLock *CompareAndSwapLock = JS_NEW_LOCK();
221
+
222
+ JS_ACQUIRE_LOCK(CompareAndSwapLock);
223
+ result = (*w == ov);
224
+ if (result)
225
+ *w = nv;
226
+ JS_RELEASE_LOCK(CompareAndSwapLock);
227
+ return result;
228
+ }
229
+
230
+ #else /* !defined(NSPR_LOCK) */
231
+
232
+ #error "NSPR_LOCK should be on when the platform lacks native compare-and-swap."
233
+
234
+ #endif
235
+
236
+ void
237
+ js_AtomicSetMask(jsword *w, jsword mask)
238
+ {
239
+ jsword ov, nv;
240
+
241
+ do {
242
+ ov = *w;
243
+ nv = ov | mask;
244
+ } while (!js_CompareAndSwap(w, ov, nv));
245
+ }
246
+
247
+ #ifndef NSPR_LOCK
248
+
249
+ struct JSFatLock {
250
+ int susp;
251
+ PRLock *slock;
252
+ PRCondVar *svar;
253
+ JSFatLock *next;
254
+ JSFatLock **prevp;
255
+ };
256
+
257
+ typedef struct JSFatLockTable {
258
+ JSFatLock *free;
259
+ JSFatLock *taken;
260
+ } JSFatLockTable;
261
+
262
+ #define GLOBAL_LOCK_INDEX(id) (((uint32)(jsuword)(id)>>2) & global_locks_mask)
263
+
264
+ static void
265
+ js_Dequeue(JSThinLock *);
266
+
267
+ static PRLock **global_locks;
268
+ static uint32 global_lock_count = 1;
269
+ static uint32 global_locks_log2 = 0;
270
+ static uint32 global_locks_mask = 0;
271
+
272
+ static void
273
+ js_LockGlobal(void *id)
274
+ {
275
+ uint32 i = GLOBAL_LOCK_INDEX(id);
276
+ PR_Lock(global_locks[i]);
277
+ }
278
+
279
+ static void
280
+ js_UnlockGlobal(void *id)
281
+ {
282
+ uint32 i = GLOBAL_LOCK_INDEX(id);
283
+ PR_Unlock(global_locks[i]);
284
+ }
285
+
286
+ #endif /* !NSPR_LOCK */
287
+
288
+ void
289
+ js_InitLock(JSThinLock *tl)
290
+ {
291
+ #ifdef NSPR_LOCK
292
+ tl->owner = 0;
293
+ tl->fat = (JSFatLock*)JS_NEW_LOCK();
294
+ #else
295
+ memset(tl, 0, sizeof(JSThinLock));
296
+ #endif
297
+ }
298
+
299
+ void
300
+ js_FinishLock(JSThinLock *tl)
301
+ {
302
+ #ifdef NSPR_LOCK
303
+ tl->owner = 0xdeadbeef;
304
+ if (tl->fat)
305
+ JS_DESTROY_LOCK(((JSLock*)tl->fat));
306
+ #else
307
+ JS_ASSERT(tl->owner == 0);
308
+ JS_ASSERT(tl->fat == NULL);
309
+ #endif
310
+ }
311
+
312
+ #ifdef DEBUG_SCOPE_COUNT
313
+
314
+ #include <stdio.h>
315
+ #include "jsdhash.h"
316
+
317
+ static FILE *logfp = NULL;
318
+ static JSDHashTable logtbl;
319
+
320
+ typedef struct logentry {
321
+ JSDHashEntryStub stub;
322
+ char op;
323
+ const char *file;
324
+ int line;
325
+ } logentry;
326
+
327
+ static void
328
+ logit(JSTitle *title, char op, const char *file, int line)
329
+ {
330
+ logentry *entry;
331
+
332
+ if (!logfp) {
333
+ logfp = fopen("/tmp/scope.log", "w");
334
+ if (!logfp)
335
+ return;
336
+ setvbuf(logfp, NULL, _IONBF, 0);
337
+ }
338
+ fprintf(logfp, "%p %d %c %s %d\n", title, title->u.count, op, file, line);
339
+
340
+ if (!logtbl.entryStore &&
341
+ !JS_DHashTableInit(&logtbl, JS_DHashGetStubOps(), NULL,
342
+ sizeof(logentry), 100)) {
343
+ return;
344
+ }
345
+ entry = (logentry *) JS_DHashTableOperate(&logtbl, title, JS_DHASH_ADD);
346
+ if (!entry)
347
+ return;
348
+ entry->stub.key = title;
349
+ entry->op = op;
350
+ entry->file = file;
351
+ entry->line = line;
352
+ }
353
+
354
+ void
355
+ js_unlog_title(JSTitle *title)
356
+ {
357
+ if (!logtbl.entryStore)
358
+ return;
359
+ (void) JS_DHashTableOperate(&logtbl, title, JS_DHASH_REMOVE);
360
+ }
361
+
362
+ # define LOGIT(title,op) logit(title, op, __FILE__, __LINE__)
363
+
364
+ #else
365
+
366
+ # define LOGIT(title, op) /* nothing */
367
+
368
+ #endif /* DEBUG_SCOPE_COUNT */
369
+
370
+ /*
371
+ * Return true if we would deadlock waiting in ClaimTitle on
372
+ * rt->titleSharingDone until ownercx finishes its request and shares a title.
373
+ *
374
+ * (i) rt->gcLock held
375
+ */
376
+ static bool
377
+ WillDeadlock(JSContext *ownercx, JSThread *thread)
378
+ {
379
+ JS_ASSERT(CURRENT_THREAD_IS_ME(thread));
380
+ JS_ASSERT(ownercx->thread != thread);
381
+
382
+ for (;;) {
383
+ JS_ASSERT(ownercx->thread);
384
+ JS_ASSERT(ownercx->requestDepth > 0);
385
+ JSTitle *title = ownercx->thread->titleToShare;
386
+ if (!title || !title->ownercx) {
387
+ /*
388
+ * ownercx->thread doesn't wait or has just been notified that the
389
+ * title became shared.
390
+ */
391
+ return false;
392
+ }
393
+
394
+ /*
395
+ * ownercx->thread is waiting in ClaimTitle for a context from some
396
+ * thread to finish its request. If that thread is the current thread,
397
+ * we would deadlock. Otherwise we must recursively check if that
398
+ * thread waits for the current thread.
399
+ */
400
+ if (title->ownercx->thread == thread) {
401
+ JS_RUNTIME_METER(ownercx->runtime, deadlocksAvoided);
402
+ return true;
403
+ }
404
+ ownercx = title->ownercx;
405
+ }
406
+ }
407
+
408
+ static void
409
+ FinishSharingTitle(JSContext *cx, JSTitle *title);
410
+
411
+ /*
412
+ * Make title multi-threaded, i.e. share its ownership among contexts in rt
413
+ * using a "thin" or (if necessary due to contention) "fat" lock. Called only
414
+ * from ClaimTitle, immediately below, when we detect deadlock were we to wait
415
+ * for title's lock, because its ownercx is waiting on a title owned by the
416
+ * calling cx.
417
+ *
418
+ * (i) rt->gcLock held
419
+ */
420
+ static void
421
+ ShareTitle(JSContext *cx, JSTitle *title)
422
+ {
423
+ JSRuntime *rt;
424
+ JSTitle **todop;
425
+
426
+ rt = cx->runtime;
427
+ if (title->u.link) {
428
+ for (todop = &rt->titleSharingTodo; *todop != title;
429
+ todop = &(*todop)->u.link) {
430
+ JS_ASSERT(*todop != NO_TITLE_SHARING_TODO);
431
+ }
432
+ *todop = title->u.link;
433
+ title->u.link = NULL; /* null u.link for sanity ASAP */
434
+ JS_NOTIFY_ALL_CONDVAR(rt->titleSharingDone);
435
+ }
436
+ FinishSharingTitle(cx, title);
437
+ }
438
+
439
+ /*
440
+ * FinishSharingTitle is the tail part of ShareTitle, split out to become a
441
+ * subroutine of js_ShareWaitingTitles too. The bulk of the work here involves
442
+ * making mutable strings in the title's object's slots be immutable. We have
443
+ * to do this because such strings will soon be available to multiple threads,
444
+ * so their buffers can't be realloc'd any longer in js_ConcatStrings, and
445
+ * their members can't be modified by js_ConcatStrings, js_UndependString or
446
+ * js_MinimizeDependentStrings.
447
+ *
448
+ * The last bit of work done by this function nulls title->ownercx and updates
449
+ * rt->sharedTitles.
450
+ */
451
+ static void
452
+ FinishSharingTitle(JSContext *cx, JSTitle *title)
453
+ {
454
+ JSScope *scope;
455
+ JSObject *obj;
456
+ uint32 nslots, i;
457
+ jsval v;
458
+
459
+ js_InitLock(&title->lock);
460
+ title->u.count = 0; /* NULL may not pun as 0 */
461
+ scope = TITLE_TO_SCOPE(title);
462
+ obj = scope->object;
463
+ if (obj) {
464
+ nslots = scope->freeslot;
465
+ for (i = 0; i != nslots; ++i) {
466
+ v = STOBJ_GET_SLOT(obj, i);
467
+ if (JSVAL_IS_STRING(v) &&
468
+ !js_MakeStringImmutable(cx, JSVAL_TO_STRING(v))) {
469
+ /*
470
+ * FIXME bug 363059: The following error recovery changes
471
+ * runtime execution semantics, arbitrarily and silently
472
+ * ignoring errors except out-of-memory, which should have been
473
+ * reported through JS_ReportOutOfMemory at this point.
474
+ */
475
+ STOBJ_SET_SLOT(obj, i, JSVAL_VOID);
476
+ }
477
+ }
478
+ }
479
+
480
+ title->ownercx = NULL; /* NB: set last, after lock init */
481
+ JS_RUNTIME_METER(cx->runtime, sharedTitles);
482
+ }
483
+
484
+ /*
485
+ * Notify all contexts that are currently in a request, which will give them a
486
+ * chance to yield their current request.
487
+ */
488
+ void
489
+ js_NudgeOtherContexts(JSContext *cx)
490
+ {
491
+ JSRuntime *rt = cx->runtime;
492
+ JSContext *acx = NULL;
493
+
494
+ while ((acx = js_NextActiveContext(rt, acx)) != NULL) {
495
+ if (cx != acx)
496
+ JS_TriggerOperationCallback(acx);
497
+ }
498
+ }
499
+
500
+ /*
501
+ * Notify all contexts that are currently in a request and execute on this
502
+ * specific thread.
503
+ */
504
+ static void
505
+ NudgeThread(JSThread *thread)
506
+ {
507
+ JSCList *link;
508
+ JSContext *acx;
509
+
510
+ link = &thread->contextList;
511
+ while ((link = link->next) != &thread->contextList) {
512
+ acx = CX_FROM_THREAD_LINKS(link);
513
+ JS_ASSERT(acx->thread == thread);
514
+ if (acx->requestDepth)
515
+ JS_TriggerOperationCallback(acx);
516
+ }
517
+ }
518
+
519
+ /*
520
+ * Given a title with apparently non-null ownercx different from cx, try to
521
+ * set ownercx to cx, claiming exclusive (single-threaded) ownership of title.
522
+ * If we claim ownership, return true. Otherwise, we wait for ownercx to be
523
+ * set to null (indicating that title is multi-threaded); or if waiting would
524
+ * deadlock, we set ownercx to null ourselves via ShareTitle. In any case,
525
+ * once ownercx is null we return false.
526
+ */
527
+ static JSBool
528
+ ClaimTitle(JSTitle *title, JSContext *cx)
529
+ {
530
+ JSRuntime *rt;
531
+ JSContext *ownercx;
532
+ uint32 requestDebit;
533
+
534
+ rt = cx->runtime;
535
+ JS_RUNTIME_METER(rt, claimAttempts);
536
+ JS_LOCK_GC(rt);
537
+
538
+ /* Reload in case ownercx went away while we blocked on the lock. */
539
+ while ((ownercx = title->ownercx) != NULL) {
540
+ /*
541
+ * Avoid selflock if ownercx is dead, or is not running a request, or
542
+ * has the same thread as cx. Set title->ownercx to cx so that the
543
+ * matching JS_UNLOCK_SCOPE or JS_UNLOCK_OBJ macro call will take the
544
+ * fast path around the corresponding js_UnlockTitle or js_UnlockObj
545
+ * function call.
546
+ *
547
+ * If title->u.link is non-null, title has already been inserted on
548
+ * the rt->titleSharingTodo list, because another thread's context
549
+ * already wanted to lock title while ownercx was running a request.
550
+ * That context must still be in request and cannot be dead. We can
551
+ * claim it if its thread matches ours but only if cx itself is in a
552
+ * request.
553
+ *
554
+ * The latter check covers the case when the embedding triggers a call
555
+ * to js_GC on a cx outside a request while having ownercx running a
556
+ * request on the same thread, and then js_GC calls a mark hook or a
557
+ * finalizer accessing the title. In this case we cannot claim the
558
+ * title but must share it now as no title-sharing JS_EndRequest will
559
+ * follow.
560
+ */
561
+ bool canClaim;
562
+ if (title->u.link) {
563
+ JS_ASSERT(js_ValidContextPointer(rt, ownercx));
564
+ JS_ASSERT(ownercx->requestDepth > 0);
565
+ JS_ASSERT_IF(cx->requestDepth == 0, cx->thread == rt->gcThread);
566
+ canClaim = (ownercx->thread == cx->thread &&
567
+ cx->requestDepth > 0);
568
+ } else {
569
+ canClaim = (!js_ValidContextPointer(rt, ownercx) ||
570
+ !ownercx->requestDepth ||
571
+ ownercx->thread == cx->thread);
572
+ }
573
+ if (canClaim) {
574
+ title->ownercx = cx;
575
+ JS_UNLOCK_GC(rt);
576
+ JS_RUNTIME_METER(rt, claimedTitles);
577
+ return JS_TRUE;
578
+ }
579
+
580
+ /*
581
+ * Avoid deadlock if title's owner thread is waiting on a title that
582
+ * the current thread owns, by revoking title's ownership. This
583
+ * approach to deadlock avoidance works because the engine never nests
584
+ * title locks.
585
+ *
586
+ * If cx->thread could hold locks on ownercx->thread->titleToShare, or
587
+ * if ownercx->thread could hold locks on title, we would need to keep
588
+ * reentrancy counts for all such "flyweight" (ownercx != NULL) locks,
589
+ * so that control would unwind properly once these locks became
590
+ * "thin" or "fat". The engine promotes a title from exclusive to
591
+ * shared access only when locking, never when holding or unlocking.
592
+ *
593
+ * Avoid deadlock before any of this title/context cycle detection if
594
+ * cx is on the active GC's thread, because in that case, no requests
595
+ * will run until the GC completes. Any title wanted by the GC (from
596
+ * a finalizer or a mark hook) that can't be claimed must become
597
+ * shared.
598
+ */
599
+ if (rt->gcThread == cx->thread || WillDeadlock(ownercx, cx->thread)) {
600
+ ShareTitle(cx, title);
601
+ break;
602
+ }
603
+
604
+ /*
605
+ * Thanks to the non-zero NO_TITLE_SHARING_TODO link terminator, we
606
+ * can decide whether title is on rt->titleSharingTodo with a single
607
+ * non-null test, and avoid double-insertion bugs.
608
+ */
609
+ if (!title->u.link) {
610
+ js_HoldScope(TITLE_TO_SCOPE(title));
611
+ title->u.link = rt->titleSharingTodo;
612
+ rt->titleSharingTodo = title;
613
+ }
614
+
615
+ /*
616
+ * Discount all the requests running on the current thread so a
617
+ * possible GC can proceed on another thread while we wait on
618
+ * rt->titleSharingDone.
619
+ */
620
+ requestDebit = js_DiscountRequestsForGC(cx);
621
+ if (title->ownercx != ownercx) {
622
+ /*
623
+ * js_DiscountRequestsForGC released and reacquired the GC lock,
624
+ * and the title was taken or shared. Start over.
625
+ */
626
+ js_RecountRequestsAfterGC(rt, requestDebit);
627
+ continue;
628
+ }
629
+
630
+ /*
631
+ * We know that some other thread's context owns title, which is now
632
+ * linked onto rt->titleSharingTodo, awaiting the end of that other
633
+ * thread's request. So it is safe to wait on rt->titleSharingDone.
634
+ * But before waiting, we force the operation callback for that other
635
+ * thread so it can quickly suspend.
636
+ */
637
+ NudgeThread(ownercx->thread);
638
+
639
+ JS_ASSERT(!cx->thread->titleToShare);
640
+ cx->thread->titleToShare = title;
641
+ #ifdef DEBUG
642
+ PRStatus stat =
643
+ #endif
644
+ PR_WaitCondVar(rt->titleSharingDone, PR_INTERVAL_NO_TIMEOUT);
645
+ JS_ASSERT(stat != PR_FAILURE);
646
+
647
+ js_RecountRequestsAfterGC(rt, requestDebit);
648
+
649
+ /*
650
+ * Don't clear titleToShare until after we're through waiting on
651
+ * all condition variables protected by rt->gcLock -- that includes
652
+ * rt->titleSharingDone *and* rt->gcDone (hidden in the call to
653
+ * js_RecountRequestsAfterGC immediately above).
654
+ *
655
+ * Otherwise, the GC could easily deadlock with another thread that
656
+ * owns a title wanted by a finalizer. By keeping cx->titleToShare
657
+ * set till here, we ensure that such deadlocks are detected, which
658
+ * results in the finalized object's title being shared (it must, of
659
+ * course, have other, live objects sharing it).
660
+ */
661
+ cx->thread->titleToShare = NULL;
662
+ }
663
+
664
+ JS_UNLOCK_GC(rt);
665
+ return JS_FALSE;
666
+ }
667
+
668
+ void
669
+ js_ShareWaitingTitles(JSContext *cx)
670
+ {
671
+ JSTitle *title, **todop;
672
+ bool shared;
673
+
674
+ /* See whether cx has any single-threaded titles to start sharing. */
675
+ todop = &cx->runtime->titleSharingTodo;
676
+ shared = false;
677
+ while ((title = *todop) != NO_TITLE_SHARING_TODO) {
678
+ if (title->ownercx != cx) {
679
+ todop = &title->u.link;
680
+ continue;
681
+ }
682
+ *todop = title->u.link;
683
+ title->u.link = NULL; /* null u.link for sanity ASAP */
684
+
685
+ /*
686
+ * If js_DropScope returns false, we held the last ref to scope. The
687
+ * waiting thread(s) must have been killed, after which the GC
688
+ * collected the object that held this scope. Unlikely, because it
689
+ * requires that the GC ran (e.g., from an operation callback)
690
+ * during this request, but possible.
691
+ */
692
+ if (js_DropScope(cx, TITLE_TO_SCOPE(title), NULL)) {
693
+ FinishSharingTitle(cx, title); /* set ownercx = NULL */
694
+ shared = true;
695
+ }
696
+ }
697
+ if (shared)
698
+ JS_NOTIFY_ALL_CONDVAR(cx->runtime->titleSharingDone);
699
+ }
700
+
701
+ /* Exported to js.c, which calls it via OBJ_GET_* and JSVAL_IS_* macros. */
702
+ JS_FRIEND_API(jsval)
703
+ js_GetSlotThreadSafe(JSContext *cx, JSObject *obj, uint32 slot)
704
+ {
705
+ jsval v;
706
+ JSScope *scope;
707
+ JSTitle *title;
708
+ #ifndef NSPR_LOCK
709
+ JSThinLock *tl;
710
+ jsword me;
711
+ #endif
712
+
713
+ /*
714
+ * We handle non-native objects via JSObjectOps.getRequiredSlot, treating
715
+ * all slots starting from 0 as required slots. A property definition or
716
+ * some prior arrangement must have allocated slot.
717
+ *
718
+ * Note once again (see jspubtd.h, before JSGetRequiredSlotOp's typedef)
719
+ * the crucial distinction between a |required slot number| that's passed
720
+ * to the get/setRequiredSlot JSObjectOps, and a |reserved slot index|
721
+ * passed to the JS_Get/SetReservedSlot APIs.
722
+ */
723
+ if (!OBJ_IS_NATIVE(obj))
724
+ return OBJ_GET_REQUIRED_SLOT(cx, obj, slot);
725
+
726
+ /*
727
+ * Native object locking is inlined here to optimize the single-threaded
728
+ * and contention-free multi-threaded cases.
729
+ */
730
+ scope = OBJ_SCOPE(obj);
731
+ title = &scope->title;
732
+ JS_ASSERT(title->ownercx != cx);
733
+ JS_ASSERT(slot < scope->freeslot);
734
+
735
+ /*
736
+ * Avoid locking if called from the GC. Also avoid locking an object
737
+ * owning a sealed scope. If neither of those special cases applies, try
738
+ * to claim scope's flyweight lock from whatever context may have had it in
739
+ * an earlier request.
740
+ */
741
+ if (CX_THREAD_IS_RUNNING_GC(cx) ||
742
+ (SCOPE_IS_SEALED(scope) && scope->object == obj) ||
743
+ (title->ownercx && ClaimTitle(title, cx))) {
744
+ return STOBJ_GET_SLOT(obj, slot);
745
+ }
746
+
747
+ #ifndef NSPR_LOCK
748
+ tl = &title->lock;
749
+ me = CX_THINLOCK_ID(cx);
750
+ JS_ASSERT(CURRENT_THREAD_IS_ME(me));
751
+ if (NativeCompareAndSwap(&tl->owner, 0, me)) {
752
+ /*
753
+ * Got the lock with one compare-and-swap. Even so, someone else may
754
+ * have mutated obj so it now has its own scope and lock, which would
755
+ * require either a restart from the top of this routine, or a thin
756
+ * lock release followed by fat lock acquisition.
757
+ */
758
+ if (scope == OBJ_SCOPE(obj)) {
759
+ v = STOBJ_GET_SLOT(obj, slot);
760
+ if (!NativeCompareAndSwap(&tl->owner, me, 0)) {
761
+ /* Assert that scope locks never revert to flyweight. */
762
+ JS_ASSERT(title->ownercx != cx);
763
+ LOGIT(title, '1');
764
+ title->u.count = 1;
765
+ js_UnlockObj(cx, obj);
766
+ }
767
+ return v;
768
+ }
769
+ if (!NativeCompareAndSwap(&tl->owner, me, 0))
770
+ js_Dequeue(tl);
771
+ }
772
+ else if (Thin_RemoveWait(ReadWord(tl->owner)) == me) {
773
+ return STOBJ_GET_SLOT(obj, slot);
774
+ }
775
+ #endif
776
+
777
+ js_LockObj(cx, obj);
778
+ v = STOBJ_GET_SLOT(obj, slot);
779
+
780
+ /*
781
+ * Test whether cx took ownership of obj's scope during js_LockObj.
782
+ *
783
+ * This does not mean that a given scope reverted to flyweight from "thin"
784
+ * or "fat" -- it does mean that obj's map pointer changed due to another
785
+ * thread setting a property, requiring obj to cease sharing a prototype
786
+ * object's scope (whose lock was not flyweight, else we wouldn't be here
787
+ * in the first place!).
788
+ */
789
+ title = &OBJ_SCOPE(obj)->title;
790
+ if (title->ownercx != cx)
791
+ js_UnlockTitle(cx, title);
792
+ return v;
793
+ }
794
+
795
+ void
796
+ js_SetSlotThreadSafe(JSContext *cx, JSObject *obj, uint32 slot, jsval v)
797
+ {
798
+ JSTitle *title;
799
+ JSScope *scope;
800
+ #ifndef NSPR_LOCK
801
+ JSThinLock *tl;
802
+ jsword me;
803
+ #endif
804
+
805
+ /* Any string stored in a thread-safe object must be immutable. */
806
+ if (JSVAL_IS_STRING(v) &&
807
+ !js_MakeStringImmutable(cx, JSVAL_TO_STRING(v))) {
808
+ /* FIXME bug 363059: See comments in js_FinishSharingScope. */
809
+ v = JSVAL_NULL;
810
+ }
811
+
812
+ /*
813
+ * We handle non-native objects via JSObjectOps.setRequiredSlot, as above
814
+ * for the Get case.
815
+ */
816
+ if (!OBJ_IS_NATIVE(obj)) {
817
+ OBJ_SET_REQUIRED_SLOT(cx, obj, slot, v);
818
+ return;
819
+ }
820
+
821
+ /*
822
+ * Native object locking is inlined here to optimize the single-threaded
823
+ * and contention-free multi-threaded cases.
824
+ */
825
+ scope = OBJ_SCOPE(obj);
826
+ title = &scope->title;
827
+ JS_ASSERT(title->ownercx != cx);
828
+ JS_ASSERT(slot < scope->freeslot);
829
+
830
+ /*
831
+ * Avoid locking if called from the GC. Also avoid locking an object
832
+ * owning a sealed scope. If neither of those special cases applies, try
833
+ * to claim scope's flyweight lock from whatever context may have had it in
834
+ * an earlier request.
835
+ */
836
+ if (CX_THREAD_IS_RUNNING_GC(cx) ||
837
+ (SCOPE_IS_SEALED(scope) && scope->object == obj) ||
838
+ (title->ownercx && ClaimTitle(title, cx))) {
839
+ LOCKED_OBJ_WRITE_BARRIER(cx, obj, slot, v);
840
+ return;
841
+ }
842
+
843
+ #ifndef NSPR_LOCK
844
+ tl = &title->lock;
845
+ me = CX_THINLOCK_ID(cx);
846
+ JS_ASSERT(CURRENT_THREAD_IS_ME(me));
847
+ if (NativeCompareAndSwap(&tl->owner, 0, me)) {
848
+ if (scope == OBJ_SCOPE(obj)) {
849
+ LOCKED_OBJ_WRITE_BARRIER(cx, obj, slot, v);
850
+ if (!NativeCompareAndSwap(&tl->owner, me, 0)) {
851
+ /* Assert that scope locks never revert to flyweight. */
852
+ JS_ASSERT(title->ownercx != cx);
853
+ LOGIT(title, '1');
854
+ title->u.count = 1;
855
+ js_UnlockObj(cx, obj);
856
+ }
857
+ return;
858
+ }
859
+ if (!NativeCompareAndSwap(&tl->owner, me, 0))
860
+ js_Dequeue(tl);
861
+ }
862
+ else if (Thin_RemoveWait(ReadWord(tl->owner)) == me) {
863
+ LOCKED_OBJ_WRITE_BARRIER(cx, obj, slot, v);
864
+ return;
865
+ }
866
+ #endif
867
+
868
+ js_LockObj(cx, obj);
869
+ LOCKED_OBJ_WRITE_BARRIER(cx, obj, slot, v);
870
+
871
+ /*
872
+ * Same drill as above, in js_GetSlotThreadSafe.
873
+ */
874
+ title = &OBJ_SCOPE(obj)->title;
875
+ if (title->ownercx != cx)
876
+ js_UnlockTitle(cx, title);
877
+ }
878
+
879
+ #ifndef NSPR_LOCK
880
+
881
+ static JSFatLock *
882
+ NewFatlock()
883
+ {
884
+ JSFatLock *fl = (JSFatLock *)malloc(sizeof(JSFatLock)); /* for now */
885
+ if (!fl) return NULL;
886
+ fl->susp = 0;
887
+ fl->next = NULL;
888
+ fl->prevp = NULL;
889
+ fl->slock = PR_NewLock();
890
+ fl->svar = PR_NewCondVar(fl->slock);
891
+ return fl;
892
+ }
893
+
894
+ static void
895
+ DestroyFatlock(JSFatLock *fl)
896
+ {
897
+ PR_DestroyLock(fl->slock);
898
+ PR_DestroyCondVar(fl->svar);
899
+ free(fl);
900
+ }
901
+
902
+ static JSFatLock *
903
+ ListOfFatlocks(int listc)
904
+ {
905
+ JSFatLock *m;
906
+ JSFatLock *m0;
907
+ int i;
908
+
909
+ JS_ASSERT(listc>0);
910
+ m0 = m = NewFatlock();
911
+ for (i=1; i<listc; i++) {
912
+ m->next = NewFatlock();
913
+ m = m->next;
914
+ }
915
+ return m0;
916
+ }
917
+
918
+ static void
919
+ DeleteListOfFatlocks(JSFatLock *m)
920
+ {
921
+ JSFatLock *m0;
922
+ for (; m; m=m0) {
923
+ m0 = m->next;
924
+ DestroyFatlock(m);
925
+ }
926
+ }
927
+
928
+ static JSFatLockTable *fl_list_table = NULL;
929
+ static uint32 fl_list_table_len = 0;
930
+ static uint32 fl_list_chunk_len = 0;
931
+
932
+ static JSFatLock *
933
+ GetFatlock(void *id)
934
+ {
935
+ JSFatLock *m;
936
+
937
+ uint32 i = GLOBAL_LOCK_INDEX(id);
938
+ if (fl_list_table[i].free == NULL) {
939
+ #ifdef DEBUG
940
+ if (fl_list_table[i].taken)
941
+ printf("Ran out of fat locks!\n");
942
+ #endif
943
+ fl_list_table[i].free = ListOfFatlocks(fl_list_chunk_len);
944
+ }
945
+ m = fl_list_table[i].free;
946
+ fl_list_table[i].free = m->next;
947
+ m->susp = 0;
948
+ m->next = fl_list_table[i].taken;
949
+ m->prevp = &fl_list_table[i].taken;
950
+ if (fl_list_table[i].taken)
951
+ fl_list_table[i].taken->prevp = &m->next;
952
+ fl_list_table[i].taken = m;
953
+ return m;
954
+ }
955
+
956
+ static void
957
+ PutFatlock(JSFatLock *m, void *id)
958
+ {
959
+ uint32 i;
960
+ if (m == NULL)
961
+ return;
962
+
963
+ /* Unlink m from fl_list_table[i].taken. */
964
+ *m->prevp = m->next;
965
+ if (m->next)
966
+ m->next->prevp = m->prevp;
967
+
968
+ /* Insert m in fl_list_table[i].free. */
969
+ i = GLOBAL_LOCK_INDEX(id);
970
+ m->next = fl_list_table[i].free;
971
+ fl_list_table[i].free = m;
972
+ }
973
+
974
+ #endif /* !NSPR_LOCK */
975
+
976
+ JSBool
977
+ js_SetupLocks(int listc, int globc)
978
+ {
979
+ #ifndef NSPR_LOCK
980
+ uint32 i;
981
+
982
+ if (global_locks)
983
+ return JS_TRUE;
984
+ #ifdef DEBUG
985
+ if (listc > 10000 || listc < 0) /* listc == fat lock list chunk length */
986
+ printf("Bad number %d in js_SetupLocks()!\n", listc);
987
+ if (globc > 100 || globc < 0) /* globc == number of global locks */
988
+ printf("Bad number %d in js_SetupLocks()!\n", listc);
989
+ #endif
990
+ global_locks_log2 = JS_CeilingLog2(globc);
991
+ global_locks_mask = JS_BITMASK(global_locks_log2);
992
+ global_lock_count = JS_BIT(global_locks_log2);
993
+ global_locks = (PRLock **) malloc(global_lock_count * sizeof(PRLock*));
994
+ if (!global_locks)
995
+ return JS_FALSE;
996
+ for (i = 0; i < global_lock_count; i++) {
997
+ global_locks[i] = PR_NewLock();
998
+ if (!global_locks[i]) {
999
+ global_lock_count = i;
1000
+ js_CleanupLocks();
1001
+ return JS_FALSE;
1002
+ }
1003
+ }
1004
+ fl_list_table = (JSFatLockTable *) malloc(i * sizeof(JSFatLockTable));
1005
+ if (!fl_list_table) {
1006
+ js_CleanupLocks();
1007
+ return JS_FALSE;
1008
+ }
1009
+ fl_list_table_len = global_lock_count;
1010
+ for (i = 0; i < global_lock_count; i++)
1011
+ fl_list_table[i].free = fl_list_table[i].taken = NULL;
1012
+ fl_list_chunk_len = listc;
1013
+ #endif /* !NSPR_LOCK */
1014
+ return JS_TRUE;
1015
+ }
1016
+
1017
+ void
1018
+ js_CleanupLocks()
1019
+ {
1020
+ #ifndef NSPR_LOCK
1021
+ uint32 i;
1022
+
1023
+ if (global_locks) {
1024
+ for (i = 0; i < global_lock_count; i++)
1025
+ PR_DestroyLock(global_locks[i]);
1026
+ free(global_locks);
1027
+ global_locks = NULL;
1028
+ global_lock_count = 1;
1029
+ global_locks_log2 = 0;
1030
+ global_locks_mask = 0;
1031
+ }
1032
+ if (fl_list_table) {
1033
+ for (i = 0; i < fl_list_table_len; i++) {
1034
+ DeleteListOfFatlocks(fl_list_table[i].free);
1035
+ fl_list_table[i].free = NULL;
1036
+ DeleteListOfFatlocks(fl_list_table[i].taken);
1037
+ fl_list_table[i].taken = NULL;
1038
+ }
1039
+ free(fl_list_table);
1040
+ fl_list_table = NULL;
1041
+ fl_list_table_len = 0;
1042
+ }
1043
+ #endif /* !NSPR_LOCK */
1044
+ }
1045
+
1046
+ #ifdef NSPR_LOCK
1047
+
1048
+ static JS_ALWAYS_INLINE void
1049
+ ThinLock(JSThinLock *tl, jsword me)
1050
+ {
1051
+ JS_ACQUIRE_LOCK((JSLock *) tl->fat);
1052
+ tl->owner = me;
1053
+ }
1054
+
1055
+ static JS_ALWAYS_INLINE void
1056
+ ThinUnlock(JSThinLock *tl, jsword /*me*/)
1057
+ {
1058
+ tl->owner = 0;
1059
+ JS_RELEASE_LOCK((JSLock *) tl->fat);
1060
+ }
1061
+
1062
+ #else
1063
+
1064
+ /*
1065
+ * Fast locking and unlocking is implemented by delaying the allocation of a
1066
+ * system lock (fat lock) until contention. As long as a locking thread A
1067
+ * runs uncontended, the lock is represented solely by storing A's identity in
1068
+ * the object being locked.
1069
+ *
1070
+ * If another thread B tries to lock the object currently locked by A, B is
1071
+ * enqueued into a fat lock structure (which might have to be allocated and
1072
+ * pointed to by the object), and suspended using NSPR conditional variables
1073
+ * (wait). A wait bit (Bacon bit) is set in the lock word of the object,
1074
+ * signalling to A that when releasing the lock, B must be dequeued and
1075
+ * notified.
1076
+ *
1077
+ * The basic operation of the locking primitives (js_Lock, js_Unlock,
1078
+ * js_Enqueue, and js_Dequeue) is compare-and-swap. Hence, when locking into
1079
+ * the word pointed at by p, compare-and-swap(p, 0, A) success implies that p
1080
+ * is unlocked. Similarly, when unlocking p, if compare-and-swap(p, A, 0)
1081
+ * succeeds this implies that p is uncontended (no one is waiting because the
1082
+ * wait bit is not set).
1083
+ *
1084
+ * When dequeueing, the lock is released, and one of the threads suspended on
1085
+ * the lock is notified. If other threads still are waiting, the wait bit is
1086
+ * kept (in js_Enqueue), and if not, the fat lock is deallocated.
1087
+ *
1088
+ * The functions js_Enqueue, js_Dequeue, js_SuspendThread, and js_ResumeThread
1089
+ * are serialized using a global lock. For scalability, a hashtable of global
1090
+ * locks is used, which is indexed modulo the thin lock pointer.
1091
+ */
1092
+
1093
+ /*
1094
+ * Invariants:
1095
+ * (i) global lock is held
1096
+ * (ii) fl->susp >= 0
1097
+ */
1098
+ static int
1099
+ js_SuspendThread(JSThinLock *tl)
1100
+ {
1101
+ JSFatLock *fl;
1102
+ PRStatus stat;
1103
+
1104
+ if (tl->fat == NULL)
1105
+ fl = tl->fat = GetFatlock(tl);
1106
+ else
1107
+ fl = tl->fat;
1108
+ JS_ASSERT(fl->susp >= 0);
1109
+ fl->susp++;
1110
+ PR_Lock(fl->slock);
1111
+ js_UnlockGlobal(tl);
1112
+ stat = PR_WaitCondVar(fl->svar, PR_INTERVAL_NO_TIMEOUT);
1113
+ JS_ASSERT(stat != PR_FAILURE);
1114
+ PR_Unlock(fl->slock);
1115
+ js_LockGlobal(tl);
1116
+ fl->susp--;
1117
+ if (fl->susp == 0) {
1118
+ PutFatlock(fl, tl);
1119
+ tl->fat = NULL;
1120
+ }
1121
+ return tl->fat == NULL;
1122
+ }
1123
+
1124
+ /*
1125
+ * (i) global lock is held
1126
+ * (ii) fl->susp > 0
1127
+ */
1128
+ static void
1129
+ js_ResumeThread(JSThinLock *tl)
1130
+ {
1131
+ JSFatLock *fl = tl->fat;
1132
+ PRStatus stat;
1133
+
1134
+ JS_ASSERT(fl != NULL);
1135
+ JS_ASSERT(fl->susp > 0);
1136
+ PR_Lock(fl->slock);
1137
+ js_UnlockGlobal(tl);
1138
+ stat = PR_NotifyCondVar(fl->svar);
1139
+ JS_ASSERT(stat != PR_FAILURE);
1140
+ PR_Unlock(fl->slock);
1141
+ }
1142
+
1143
+ static void
1144
+ js_Enqueue(JSThinLock *tl, jsword me)
1145
+ {
1146
+ jsword o, n;
1147
+
1148
+ js_LockGlobal(tl);
1149
+ for (;;) {
1150
+ o = ReadWord(tl->owner);
1151
+ n = Thin_SetWait(o);
1152
+ if (o != 0 && NativeCompareAndSwap(&tl->owner, o, n)) {
1153
+ if (js_SuspendThread(tl))
1154
+ me = Thin_RemoveWait(me);
1155
+ else
1156
+ me = Thin_SetWait(me);
1157
+ }
1158
+ else if (NativeCompareAndSwap(&tl->owner, 0, me)) {
1159
+ js_UnlockGlobal(tl);
1160
+ return;
1161
+ }
1162
+ }
1163
+ }
1164
+
1165
+ static void
1166
+ js_Dequeue(JSThinLock *tl)
1167
+ {
1168
+ jsword o;
1169
+
1170
+ js_LockGlobal(tl);
1171
+ o = ReadWord(tl->owner);
1172
+ JS_ASSERT(Thin_GetWait(o) != 0);
1173
+ JS_ASSERT(tl->fat != NULL);
1174
+ if (!NativeCompareAndSwap(&tl->owner, o, 0)) /* release it */
1175
+ JS_ASSERT(0);
1176
+ js_ResumeThread(tl);
1177
+ }
1178
+
1179
+ static JS_ALWAYS_INLINE void
1180
+ ThinLock(JSThinLock *tl, jsword me)
1181
+ {
1182
+ JS_ASSERT(CURRENT_THREAD_IS_ME(me));
1183
+ if (NativeCompareAndSwap(&tl->owner, 0, me))
1184
+ return;
1185
+ if (Thin_RemoveWait(ReadWord(tl->owner)) != me)
1186
+ js_Enqueue(tl, me);
1187
+ #ifdef DEBUG
1188
+ else
1189
+ JS_ASSERT(0);
1190
+ #endif
1191
+ }
1192
+
1193
+ static JS_ALWAYS_INLINE void
1194
+ ThinUnlock(JSThinLock *tl, jsword me)
1195
+ {
1196
+ JS_ASSERT(CURRENT_THREAD_IS_ME(me));
1197
+
1198
+ /*
1199
+ * Since we can race with the NativeCompareAndSwap in js_Enqueue, we need
1200
+ * to use a C_A_S here as well -- Arjan van de Ven 30/1/08
1201
+ */
1202
+ if (NativeCompareAndSwap(&tl->owner, me, 0))
1203
+ return;
1204
+
1205
+ JS_ASSERT(Thin_GetWait(tl->owner));
1206
+ if (Thin_RemoveWait(ReadWord(tl->owner)) == me)
1207
+ js_Dequeue(tl);
1208
+ #ifdef DEBUG
1209
+ else
1210
+ JS_ASSERT(0); /* unbalanced unlock */
1211
+ #endif
1212
+ }
1213
+
1214
+ #endif /* !NSPR_LOCK */
1215
+
1216
+ void
1217
+ js_Lock(JSContext *cx, JSThinLock *tl)
1218
+ {
1219
+ ThinLock(tl, CX_THINLOCK_ID(cx));
1220
+ }
1221
+
1222
+ void
1223
+ js_Unlock(JSContext *cx, JSThinLock *tl)
1224
+ {
1225
+ ThinUnlock(tl, CX_THINLOCK_ID(cx));
1226
+ }
1227
+
1228
+ void
1229
+ js_LockRuntime(JSRuntime *rt)
1230
+ {
1231
+ PR_Lock(rt->rtLock);
1232
+ #ifdef DEBUG
1233
+ rt->rtLockOwner = js_CurrentThreadId();
1234
+ #endif
1235
+ }
1236
+
1237
+ void
1238
+ js_UnlockRuntime(JSRuntime *rt)
1239
+ {
1240
+ #ifdef DEBUG
1241
+ rt->rtLockOwner = 0;
1242
+ #endif
1243
+ PR_Unlock(rt->rtLock);
1244
+ }
1245
+
1246
+ void
1247
+ js_LockTitle(JSContext *cx, JSTitle *title)
1248
+ {
1249
+ jsword me = CX_THINLOCK_ID(cx);
1250
+
1251
+ JS_ASSERT(CURRENT_THREAD_IS_ME(me));
1252
+ JS_ASSERT(title->ownercx != cx);
1253
+ if (CX_THREAD_IS_RUNNING_GC(cx))
1254
+ return;
1255
+ if (title->ownercx && ClaimTitle(title, cx))
1256
+ return;
1257
+
1258
+ if (Thin_RemoveWait(ReadWord(title->lock.owner)) == me) {
1259
+ JS_ASSERT(title->u.count > 0);
1260
+ LOGIT(scope, '+');
1261
+ title->u.count++;
1262
+ } else {
1263
+ ThinLock(&title->lock, me);
1264
+ JS_ASSERT(title->u.count == 0);
1265
+ LOGIT(scope, '1');
1266
+ title->u.count = 1;
1267
+ }
1268
+ }
1269
+
1270
+ void
1271
+ js_UnlockTitle(JSContext *cx, JSTitle *title)
1272
+ {
1273
+ jsword me = CX_THINLOCK_ID(cx);
1274
+
1275
+ /* We hope compilers use me instead of reloading cx->thread in the macro. */
1276
+ if (CX_THREAD_IS_RUNNING_GC(cx))
1277
+ return;
1278
+ if (cx->lockedSealedTitle == title) {
1279
+ cx->lockedSealedTitle = NULL;
1280
+ return;
1281
+ }
1282
+
1283
+ /*
1284
+ * If title->ownercx is not null, it's likely that two contexts not using
1285
+ * requests nested locks for title. The first context, cx here, claimed
1286
+ * title; the second, title->ownercx here, re-claimed it because the first
1287
+ * was not in a request, or was on the same thread. We don't want to keep
1288
+ * track of such nesting, because it penalizes the common non-nested case.
1289
+ * Instead of asserting here and silently coping, we simply re-claim title
1290
+ * for cx and return.
1291
+ *
1292
+ * See http://bugzilla.mozilla.org/show_bug.cgi?id=229200 for a real world
1293
+ * case where an asymmetric thread model (Mozilla's main thread is known
1294
+ * to be the only thread that runs the GC) combined with multiple contexts
1295
+ * per thread has led to such request-less nesting.
1296
+ */
1297
+ if (title->ownercx) {
1298
+ JS_ASSERT(title->u.count == 0);
1299
+ JS_ASSERT(title->lock.owner == 0);
1300
+ title->ownercx = cx;
1301
+ return;
1302
+ }
1303
+
1304
+ JS_ASSERT(title->u.count > 0);
1305
+ if (Thin_RemoveWait(ReadWord(title->lock.owner)) != me) {
1306
+ JS_ASSERT(0); /* unbalanced unlock */
1307
+ return;
1308
+ }
1309
+ LOGIT(title, '-');
1310
+ if (--title->u.count == 0)
1311
+ ThinUnlock(&title->lock, me);
1312
+ }
1313
+
1314
+ /*
1315
+ * NB: oldtitle may be null if our caller is js_GetMutableScope and it just
1316
+ * dropped the last reference to oldtitle.
1317
+ */
1318
+ void
1319
+ js_TransferTitle(JSContext *cx, JSTitle *oldtitle, JSTitle *newtitle)
1320
+ {
1321
+ JS_ASSERT(JS_IS_TITLE_LOCKED(cx, newtitle));
1322
+
1323
+ /*
1324
+ * If the last reference to oldtitle went away, newtitle needs no lock
1325
+ * state update.
1326
+ */
1327
+ if (!oldtitle)
1328
+ return;
1329
+ JS_ASSERT(JS_IS_TITLE_LOCKED(cx, oldtitle));
1330
+
1331
+ /*
1332
+ * Special case in js_LockTitle and js_UnlockTitle for the GC calling
1333
+ * code that locks, unlocks, or mutates. Nothing to do in these cases,
1334
+ * because title and newtitle were "locked" by the GC thread, so neither
1335
+ * was actually locked.
1336
+ */
1337
+ if (CX_THREAD_IS_RUNNING_GC(cx))
1338
+ return;
1339
+
1340
+ /*
1341
+ * Special case in js_LockObj and js_UnlockTitle for locking the sealed
1342
+ * scope of an object that owns that scope (the prototype or mutated obj
1343
+ * for which OBJ_SCOPE(obj)->object == obj), and unlocking it.
1344
+ */
1345
+ JS_ASSERT(cx->lockedSealedTitle != newtitle);
1346
+ if (cx->lockedSealedTitle == oldtitle) {
1347
+ JS_ASSERT(newtitle->ownercx == cx ||
1348
+ (!newtitle->ownercx && newtitle->u.count == 1));
1349
+ cx->lockedSealedTitle = NULL;
1350
+ return;
1351
+ }
1352
+
1353
+ /*
1354
+ * If oldtitle is single-threaded, there's nothing to do.
1355
+ */
1356
+ if (oldtitle->ownercx) {
1357
+ JS_ASSERT(oldtitle->ownercx == cx);
1358
+ JS_ASSERT(newtitle->ownercx == cx ||
1359
+ (!newtitle->ownercx && newtitle->u.count == 1));
1360
+ return;
1361
+ }
1362
+
1363
+ /*
1364
+ * We transfer oldtitle->u.count only if newtitle is not single-threaded.
1365
+ * Flow unwinds from here through some number of JS_UNLOCK_TITLE and/or
1366
+ * JS_UNLOCK_OBJ macro calls, which will decrement newtitle->u.count only
1367
+ * if they find newtitle->ownercx != cx.
1368
+ */
1369
+ if (newtitle->ownercx != cx) {
1370
+ JS_ASSERT(!newtitle->ownercx);
1371
+ newtitle->u.count = oldtitle->u.count;
1372
+ }
1373
+
1374
+ /*
1375
+ * Reset oldtitle's lock state so that it is completely unlocked.
1376
+ */
1377
+ LOGIT(oldtitle, '0');
1378
+ oldtitle->u.count = 0;
1379
+ ThinUnlock(&oldtitle->lock, CX_THINLOCK_ID(cx));
1380
+ }
1381
+
1382
+ void
1383
+ js_LockObj(JSContext *cx, JSObject *obj)
1384
+ {
1385
+ JSScope *scope;
1386
+ JSTitle *title;
1387
+
1388
+ JS_ASSERT(OBJ_IS_NATIVE(obj));
1389
+
1390
+ /*
1391
+ * We must test whether the GC is calling and return without mutating any
1392
+ * state, especially cx->lockedSealedScope. Note asymmetry with respect to
1393
+ * js_UnlockObj, which is a thin-layer on top of js_UnlockTitle.
1394
+ */
1395
+ if (CX_THREAD_IS_RUNNING_GC(cx))
1396
+ return;
1397
+
1398
+ for (;;) {
1399
+ scope = OBJ_SCOPE(obj);
1400
+ title = &scope->title;
1401
+ if (SCOPE_IS_SEALED(scope) && scope->object == obj &&
1402
+ !cx->lockedSealedTitle) {
1403
+ cx->lockedSealedTitle = title;
1404
+ return;
1405
+ }
1406
+
1407
+ js_LockTitle(cx, title);
1408
+
1409
+ /* If obj still has this scope, we're done. */
1410
+ if (scope == OBJ_SCOPE(obj))
1411
+ return;
1412
+
1413
+ /* Lost a race with a mutator; retry with obj's new scope. */
1414
+ js_UnlockTitle(cx, title);
1415
+ }
1416
+ }
1417
+
1418
+ void
1419
+ js_UnlockObj(JSContext *cx, JSObject *obj)
1420
+ {
1421
+ JS_ASSERT(OBJ_IS_NATIVE(obj));
1422
+ js_UnlockTitle(cx, &OBJ_SCOPE(obj)->title);
1423
+ }
1424
+
1425
+ void
1426
+ js_InitTitle(JSContext *cx, JSTitle *title)
1427
+ {
1428
+ #ifdef JS_THREADSAFE
1429
+ title->ownercx = cx;
1430
+ memset(&title->lock, 0, sizeof title->lock);
1431
+
1432
+ /*
1433
+ * Set u.link = NULL, not u.count = 0, in case the target architecture's
1434
+ * null pointer has a non-zero integer representation.
1435
+ */
1436
+ title->u.link = NULL;
1437
+
1438
+ #ifdef JS_DEBUG_TITLE_LOCKS
1439
+ title->file[0] = title->file[1] = title->file[2] = title->file[3] = NULL;
1440
+ title->line[0] = title->line[1] = title->line[2] = title->line[3] = 0;
1441
+ #endif
1442
+ #endif
1443
+ }
1444
+
1445
+ void
1446
+ js_FinishTitle(JSContext *cx, JSTitle *title)
1447
+ {
1448
+ #ifdef DEBUG_SCOPE_COUNT
1449
+ js_unlog_title(title);
1450
+ #endif
1451
+
1452
+ #ifdef JS_THREADSAFE
1453
+ /* Title must be single-threaded at this point, so set ownercx. */
1454
+ JS_ASSERT(title->u.count == 0);
1455
+ title->ownercx = cx;
1456
+ js_FinishLock(&title->lock);
1457
+ #endif
1458
+ }
1459
+
1460
+ #ifdef DEBUG
1461
+
1462
+ JSBool
1463
+ js_IsRuntimeLocked(JSRuntime *rt)
1464
+ {
1465
+ return js_CurrentThreadId() == rt->rtLockOwner;
1466
+ }
1467
+
1468
+ JSBool
1469
+ js_IsObjLocked(JSContext *cx, JSObject *obj)
1470
+ {
1471
+ return js_IsTitleLocked(cx, &OBJ_SCOPE(obj)->title);
1472
+ }
1473
+
1474
+ JSBool
1475
+ js_IsTitleLocked(JSContext *cx, JSTitle *title)
1476
+ {
1477
+ /* Special case: the GC locking any object's title, see js_LockTitle. */
1478
+ if (CX_THREAD_IS_RUNNING_GC(cx))
1479
+ return JS_TRUE;
1480
+
1481
+ /* Special case: locked object owning a sealed scope, see js_LockObj. */
1482
+ if (cx->lockedSealedTitle == title)
1483
+ return JS_TRUE;
1484
+
1485
+ /*
1486
+ * General case: the title is either exclusively owned (by cx), or it has
1487
+ * a thin or fat lock to cope with shared (concurrent) ownership.
1488
+ */
1489
+ if (title->ownercx) {
1490
+ JS_ASSERT(title->ownercx == cx || title->ownercx->thread == cx->thread);
1491
+ return JS_TRUE;
1492
+ }
1493
+ return js_CurrentThreadId() ==
1494
+ ((JSThread *)Thin_RemoveWait(ReadWord(title->lock.owner)))->id;
1495
+ }
1496
+
1497
+ #ifdef JS_DEBUG_TITLE_LOCKS
1498
+ void
1499
+ js_SetScopeInfo(JSScope *scope, const char *file, int line)
1500
+ {
1501
+ JSTitle *title = &scope->title;
1502
+ if (!title->ownercx) {
1503
+ jsrefcount count = title->u.count;
1504
+ JS_ASSERT_IF(!SCOPE_IS_SEALED(scope), count > 0);
1505
+ JS_ASSERT(count <= 4);
1506
+ title->file[count - 1] = file;
1507
+ title->line[count - 1] = line;
1508
+ }
1509
+ }
1510
+ #endif /* JS_DEBUG_TITLE_LOCKS */
1511
+ #endif /* DEBUG */
1512
+ #endif /* JS_THREADSAFE */