distil 0.7.0

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 (552) hide show
  1. data/Rakefile +28 -0
  2. data/VERSION +1 -0
  3. data/bin/distil +45 -0
  4. data/distil.gemspec +586 -0
  5. data/lib/bootstrap-template.js +56 -0
  6. data/lib/configurable.rb +125 -0
  7. data/lib/file-set.rb +42 -0
  8. data/lib/file-types/css-file.rb +75 -0
  9. data/lib/file-types/html-file.rb +11 -0
  10. data/lib/file-types/javascript-file.rb +98 -0
  11. data/lib/file-types/json-file.rb +14 -0
  12. data/lib/file-types/nib-file.rb +9 -0
  13. data/lib/jsdoc.conf +18 -0
  14. data/lib/jsl.conf +121 -0
  15. data/lib/project.rb +96 -0
  16. data/lib/source-file.rb +181 -0
  17. data/lib/target.rb +96 -0
  18. data/lib/task.rb +239 -0
  19. data/lib/tasks/copy-task.rb +21 -0
  20. data/lib/tasks/css-task.rb +18 -0
  21. data/lib/tasks/javascript-task.rb +125 -0
  22. data/lib/tasks/multiple-output-task.rb +134 -0
  23. data/lib/tasks/nib-task.rb +83 -0
  24. data/lib/tasks/output-task.rb +73 -0
  25. data/lib/tasks/single-output-task.rb +83 -0
  26. data/lib/tasks/test-task.rb +280 -0
  27. data/lib/test/HtmlTestReporter.js +127 -0
  28. data/lib/test/Test.js +248 -0
  29. data/lib/test/TestReporter.js +79 -0
  30. data/lib/test/TestRunner.js +132 -0
  31. data/lib/test/browser.rb +97 -0
  32. data/lib/test/scriptwrapper.html +10 -0
  33. data/lib/test/unittest.html +127 -0
  34. data/vendor/Makefile +35 -0
  35. data/vendor/extconf.rb +3 -0
  36. data/vendor/jsdoc-extras/plugins/distil-plugin.js +142 -0
  37. data/vendor/jsdoc-extras/plugins/interface-plugin.js +36 -0
  38. data/vendor/jsdoc-extras/templates/coherent/allclasses.tmpl +17 -0
  39. data/vendor/jsdoc-extras/templates/coherent/allfiles.tmpl +53 -0
  40. data/vendor/jsdoc-extras/templates/coherent/class.tmpl +803 -0
  41. data/vendor/jsdoc-extras/templates/coherent/index.tmpl +37 -0
  42. data/vendor/jsdoc-extras/templates/coherent/publish.js +242 -0
  43. data/vendor/jsdoc-extras/templates/coherent/showdown.js +421 -0
  44. data/vendor/jsdoc-extras/templates/coherent/static/code-footer.html +3 -0
  45. data/vendor/jsdoc-extras/templates/coherent/static/code-header.html +7 -0
  46. data/vendor/jsdoc-extras/templates/coherent/static/default.css +297 -0
  47. data/vendor/jsdoc-extras/templates/coherent/static/header.html +2 -0
  48. data/vendor/jsdoc-extras/templates/coherent/static/index.html +19 -0
  49. data/vendor/jsdoc-extras/templates/coherent/symbol.tmpl +35 -0
  50. data/vendor/jsdoc-toolkit/README.txt +183 -0
  51. data/vendor/jsdoc-toolkit/app/frame/Chain.js +102 -0
  52. data/vendor/jsdoc-toolkit/app/frame/Dumper.js +144 -0
  53. data/vendor/jsdoc-toolkit/app/frame/Hash.js +84 -0
  54. data/vendor/jsdoc-toolkit/app/frame/Link.js +171 -0
  55. data/vendor/jsdoc-toolkit/app/frame/Namespace.js +10 -0
  56. data/vendor/jsdoc-toolkit/app/frame/Opt.js +134 -0
  57. data/vendor/jsdoc-toolkit/app/frame/Reflection.js +26 -0
  58. data/vendor/jsdoc-toolkit/app/frame/String.js +93 -0
  59. data/vendor/jsdoc-toolkit/app/frame/Testrun.js +129 -0
  60. data/vendor/jsdoc-toolkit/app/frame.js +33 -0
  61. data/vendor/jsdoc-toolkit/app/handlers/FOODOC.js +26 -0
  62. data/vendor/jsdoc-toolkit/app/handlers/XMLDOC/DomReader.js +159 -0
  63. data/vendor/jsdoc-toolkit/app/handlers/XMLDOC/XMLDoc.js +16 -0
  64. data/vendor/jsdoc-toolkit/app/handlers/XMLDOC/XMLParse.js +292 -0
  65. data/vendor/jsdoc-toolkit/app/handlers/XMLDOC.js +26 -0
  66. data/vendor/jsdoc-toolkit/app/lib/JSDOC/DocComment.js +204 -0
  67. data/vendor/jsdoc-toolkit/app/lib/JSDOC/DocTag.js +300 -0
  68. data/vendor/jsdoc-toolkit/app/lib/JSDOC/JsDoc.js +126 -0
  69. data/vendor/jsdoc-toolkit/app/lib/JSDOC/JsPlate.js +109 -0
  70. data/vendor/jsdoc-toolkit/app/lib/JSDOC/Lang.js +144 -0
  71. data/vendor/jsdoc-toolkit/app/lib/JSDOC/Parser.js +144 -0
  72. data/vendor/jsdoc-toolkit/app/lib/JSDOC/PluginManager.js +33 -0
  73. data/vendor/jsdoc-toolkit/app/lib/JSDOC/Symbol.js +644 -0
  74. data/vendor/jsdoc-toolkit/app/lib/JSDOC/SymbolSet.js +241 -0
  75. data/vendor/jsdoc-toolkit/app/lib/JSDOC/TextStream.js +41 -0
  76. data/vendor/jsdoc-toolkit/app/lib/JSDOC/Token.js +18 -0
  77. data/vendor/jsdoc-toolkit/app/lib/JSDOC/TokenReader.js +332 -0
  78. data/vendor/jsdoc-toolkit/app/lib/JSDOC/TokenStream.js +133 -0
  79. data/vendor/jsdoc-toolkit/app/lib/JSDOC/Util.js +32 -0
  80. data/vendor/jsdoc-toolkit/app/lib/JSDOC/Walker.js +499 -0
  81. data/vendor/jsdoc-toolkit/app/lib/JSDOC.js +106 -0
  82. data/vendor/jsdoc-toolkit/app/main.js +129 -0
  83. data/vendor/jsdoc-toolkit/app/plugins/commentSrcJson.js +20 -0
  84. data/vendor/jsdoc-toolkit/app/plugins/frameworkPrototype.js +16 -0
  85. data/vendor/jsdoc-toolkit/app/plugins/functionCall.js +10 -0
  86. data/vendor/jsdoc-toolkit/app/plugins/publishSrcHilite.js +54 -0
  87. data/vendor/jsdoc-toolkit/app/plugins/symbolLink.js +10 -0
  88. data/vendor/jsdoc-toolkit/app/plugins/tagParamConfig.js +31 -0
  89. data/vendor/jsdoc-toolkit/app/plugins/tagSynonyms.js +43 -0
  90. data/vendor/jsdoc-toolkit/app/run.js +348 -0
  91. data/vendor/jsdoc-toolkit/app/t/TestDoc.js +144 -0
  92. data/vendor/jsdoc-toolkit/app/t/runner.js +13 -0
  93. data/vendor/jsdoc-toolkit/app/test/addon.js +24 -0
  94. data/vendor/jsdoc-toolkit/app/test/anon_inner.js +14 -0
  95. data/vendor/jsdoc-toolkit/app/test/augments.js +31 -0
  96. data/vendor/jsdoc-toolkit/app/test/augments2.js +26 -0
  97. data/vendor/jsdoc-toolkit/app/test/borrows.js +46 -0
  98. data/vendor/jsdoc-toolkit/app/test/borrows2.js +23 -0
  99. data/vendor/jsdoc-toolkit/app/test/config.js +22 -0
  100. data/vendor/jsdoc-toolkit/app/test/constructs.js +18 -0
  101. data/vendor/jsdoc-toolkit/app/test/encoding.js +10 -0
  102. data/vendor/jsdoc-toolkit/app/test/encoding_other.js +12 -0
  103. data/vendor/jsdoc-toolkit/app/test/event.js +54 -0
  104. data/vendor/jsdoc-toolkit/app/test/exports.js +14 -0
  105. data/vendor/jsdoc-toolkit/app/test/functions_anon.js +39 -0
  106. data/vendor/jsdoc-toolkit/app/test/functions_nested.js +33 -0
  107. data/vendor/jsdoc-toolkit/app/test/global.js +13 -0
  108. data/vendor/jsdoc-toolkit/app/test/globals.js +25 -0
  109. data/vendor/jsdoc-toolkit/app/test/ignore.js +10 -0
  110. data/vendor/jsdoc-toolkit/app/test/inner.js +16 -0
  111. data/vendor/jsdoc-toolkit/app/test/jsdoc_test.js +477 -0
  112. data/vendor/jsdoc-toolkit/app/test/lend.js +33 -0
  113. data/vendor/jsdoc-toolkit/app/test/memberof.js +19 -0
  114. data/vendor/jsdoc-toolkit/app/test/memberof2.js +38 -0
  115. data/vendor/jsdoc-toolkit/app/test/memberof3.js +33 -0
  116. data/vendor/jsdoc-toolkit/app/test/memberof_constructor.js +17 -0
  117. data/vendor/jsdoc-toolkit/app/test/module.js +17 -0
  118. data/vendor/jsdoc-toolkit/app/test/name.js +19 -0
  119. data/vendor/jsdoc-toolkit/app/test/namespace_nested.js +23 -0
  120. data/vendor/jsdoc-toolkit/app/test/nocode.js +13 -0
  121. data/vendor/jsdoc-toolkit/app/test/oblit_anon.js +20 -0
  122. data/vendor/jsdoc-toolkit/app/test/overview.js +20 -0
  123. data/vendor/jsdoc-toolkit/app/test/param_inline.js +37 -0
  124. data/vendor/jsdoc-toolkit/app/test/params_optional.js +8 -0
  125. data/vendor/jsdoc-toolkit/app/test/prototype.js +17 -0
  126. data/vendor/jsdoc-toolkit/app/test/prototype_nested.js +9 -0
  127. data/vendor/jsdoc-toolkit/app/test/prototype_oblit.js +13 -0
  128. data/vendor/jsdoc-toolkit/app/test/prototype_oblit_constructor.js +24 -0
  129. data/vendor/jsdoc-toolkit/app/test/public.js +10 -0
  130. data/vendor/jsdoc-toolkit/app/test/scripts/code.js +5 -0
  131. data/vendor/jsdoc-toolkit/app/test/scripts/notcode.txt +5 -0
  132. data/vendor/jsdoc-toolkit/app/test/shared.js +42 -0
  133. data/vendor/jsdoc-toolkit/app/test/shared2.js +2 -0
  134. data/vendor/jsdoc-toolkit/app/test/shortcuts.js +22 -0
  135. data/vendor/jsdoc-toolkit/app/test/static_this.js +13 -0
  136. data/vendor/jsdoc-toolkit/app/test/synonyms.js +31 -0
  137. data/vendor/jsdoc-toolkit/app/test/tosource.js +23 -0
  138. data/vendor/jsdoc-toolkit/app/test/variable_redefine.js +14 -0
  139. data/vendor/jsdoc-toolkit/app/test.js +342 -0
  140. data/vendor/jsdoc-toolkit/changes.txt +116 -0
  141. data/vendor/jsdoc-toolkit/conf/sample.conf +31 -0
  142. data/vendor/jsdoc-toolkit/java/build.xml +36 -0
  143. data/vendor/jsdoc-toolkit/java/build_1.4.xml +36 -0
  144. data/vendor/jsdoc-toolkit/java/classes/js.jar +0 -0
  145. data/vendor/jsdoc-toolkit/java/src/JsDebugRun.java +21 -0
  146. data/vendor/jsdoc-toolkit/java/src/JsRun.java +21 -0
  147. data/vendor/jsdoc-toolkit/jsdebug.jar +0 -0
  148. data/vendor/jsdoc-toolkit/jsrun.jar +0 -0
  149. data/vendor/jsdoc-toolkit/jsrun.sh +53 -0
  150. data/vendor/jsdoc-toolkit/templates/jsdoc/allclasses.tmpl +17 -0
  151. data/vendor/jsdoc-toolkit/templates/jsdoc/allfiles.tmpl +56 -0
  152. data/vendor/jsdoc-toolkit/templates/jsdoc/class.tmpl +649 -0
  153. data/vendor/jsdoc-toolkit/templates/jsdoc/index.tmpl +39 -0
  154. data/vendor/jsdoc-toolkit/templates/jsdoc/publish.js +201 -0
  155. data/vendor/jsdoc-toolkit/templates/jsdoc/static/code-footer.html +3 -0
  156. data/vendor/jsdoc-toolkit/templates/jsdoc/static/code-header.html +14 -0
  157. data/vendor/jsdoc-toolkit/templates/jsdoc/static/default.css +162 -0
  158. data/vendor/jsdoc-toolkit/templates/jsdoc/static/header.html +2 -0
  159. data/vendor/jsdoc-toolkit/templates/jsdoc/static/index.html +19 -0
  160. data/vendor/jsdoc-toolkit/templates/jsdoc/symbol.tmpl +35 -0
  161. data/vendor/jsl-0.3.0/src/JavaScriptLintAPI.cpp +333 -0
  162. data/vendor/jsl-0.3.0/src/JavaScriptLintAPI.h +86 -0
  163. data/vendor/jsl-0.3.0/src/Makefile.in +375 -0
  164. data/vendor/jsl-0.3.0/src/Makefile.ref +372 -0
  165. data/vendor/jsl-0.3.0/src/README.html +826 -0
  166. data/vendor/jsl-0.3.0/src/SpiderMonkey.rsp +12 -0
  167. data/vendor/jsl-0.3.0/src/_jsl_online.php +223 -0
  168. data/vendor/jsl-0.3.0/src/config/AIX4.1.mk +65 -0
  169. data/vendor/jsl-0.3.0/src/config/AIX4.2.mk +64 -0
  170. data/vendor/jsl-0.3.0/src/config/AIX4.3.mk +65 -0
  171. data/vendor/jsl-0.3.0/src/config/Darwin.mk +81 -0
  172. data/vendor/jsl-0.3.0/src/config/Darwin1.3.mk +81 -0
  173. data/vendor/jsl-0.3.0/src/config/Darwin1.4.mk +41 -0
  174. data/vendor/jsl-0.3.0/src/config/Darwin5.2.mk +81 -0
  175. data/vendor/jsl-0.3.0/src/config/Darwin5.3.mk +81 -0
  176. data/vendor/jsl-0.3.0/src/config/HP-UXB.10.10.mk +77 -0
  177. data/vendor/jsl-0.3.0/src/config/HP-UXB.10.20.mk +77 -0
  178. data/vendor/jsl-0.3.0/src/config/HP-UXB.11.00.mk +80 -0
  179. data/vendor/jsl-0.3.0/src/config/IRIX.mk +87 -0
  180. data/vendor/jsl-0.3.0/src/config/IRIX5.3.mk +44 -0
  181. data/vendor/jsl-0.3.0/src/config/IRIX6.1.mk +44 -0
  182. data/vendor/jsl-0.3.0/src/config/IRIX6.2.mk +44 -0
  183. data/vendor/jsl-0.3.0/src/config/IRIX6.3.mk +44 -0
  184. data/vendor/jsl-0.3.0/src/config/IRIX6.5.mk +44 -0
  185. data/vendor/jsl-0.3.0/src/config/Linux_All.mk +103 -0
  186. data/vendor/jsl-0.3.0/src/config/Mac_OS10.0.mk +82 -0
  187. data/vendor/jsl-0.3.0/src/config/OSF1V4.0.mk +72 -0
  188. data/vendor/jsl-0.3.0/src/config/OSF1V5.0.mk +69 -0
  189. data/vendor/jsl-0.3.0/src/config/SunOS4.1.4.mk +101 -0
  190. data/vendor/jsl-0.3.0/src/config/SunOS5.3.mk +91 -0
  191. data/vendor/jsl-0.3.0/src/config/SunOS5.4.mk +92 -0
  192. data/vendor/jsl-0.3.0/src/config/SunOS5.5.1.mk +44 -0
  193. data/vendor/jsl-0.3.0/src/config/SunOS5.5.mk +87 -0
  194. data/vendor/jsl-0.3.0/src/config/SunOS5.6.mk +89 -0
  195. data/vendor/jsl-0.3.0/src/config/SunOS5.7.mk +44 -0
  196. data/vendor/jsl-0.3.0/src/config/SunOS5.8.mk +44 -0
  197. data/vendor/jsl-0.3.0/src/config/SunOS5.9.mk +44 -0
  198. data/vendor/jsl-0.3.0/src/config/WINNT4.0.mk +112 -0
  199. data/vendor/jsl-0.3.0/src/config/WINNT5.0.mk +112 -0
  200. data/vendor/jsl-0.3.0/src/config/WINNT5.1.mk +112 -0
  201. data/vendor/jsl-0.3.0/src/config/WINNT5.2.mk +112 -0
  202. data/vendor/jsl-0.3.0/src/config/dgux.mk +64 -0
  203. data/vendor/jsl-0.3.0/src/config.mk +166 -0
  204. data/vendor/jsl-0.3.0/src/editline/Makefile.ref +144 -0
  205. data/vendor/jsl-0.3.0/src/editline/README +83 -0
  206. data/vendor/jsl-0.3.0/src/editline/editline.3 +175 -0
  207. data/vendor/jsl-0.3.0/src/editline/editline.c +1369 -0
  208. data/vendor/jsl-0.3.0/src/editline/editline.h +135 -0
  209. data/vendor/jsl-0.3.0/src/editline/sysunix.c +182 -0
  210. data/vendor/jsl-0.3.0/src/editline/unix.h +82 -0
  211. data/vendor/jsl-0.3.0/src/fdlibm/Makefile.in +127 -0
  212. data/vendor/jsl-0.3.0/src/fdlibm/Makefile.ref +192 -0
  213. data/vendor/jsl-0.3.0/src/fdlibm/e_acos.c +147 -0
  214. data/vendor/jsl-0.3.0/src/fdlibm/e_acosh.c +105 -0
  215. data/vendor/jsl-0.3.0/src/fdlibm/e_asin.c +156 -0
  216. data/vendor/jsl-0.3.0/src/fdlibm/e_atan2.c +165 -0
  217. data/vendor/jsl-0.3.0/src/fdlibm/e_atanh.c +110 -0
  218. data/vendor/jsl-0.3.0/src/fdlibm/e_cosh.c +133 -0
  219. data/vendor/jsl-0.3.0/src/fdlibm/e_exp.c +202 -0
  220. data/vendor/jsl-0.3.0/src/fdlibm/e_fmod.c +184 -0
  221. data/vendor/jsl-0.3.0/src/fdlibm/e_gamma.c +71 -0
  222. data/vendor/jsl-0.3.0/src/fdlibm/e_gamma_r.c +70 -0
  223. data/vendor/jsl-0.3.0/src/fdlibm/e_hypot.c +173 -0
  224. data/vendor/jsl-0.3.0/src/fdlibm/e_j0.c +524 -0
  225. data/vendor/jsl-0.3.0/src/fdlibm/e_j1.c +523 -0
  226. data/vendor/jsl-0.3.0/src/fdlibm/e_jn.c +315 -0
  227. data/vendor/jsl-0.3.0/src/fdlibm/e_lgamma.c +71 -0
  228. data/vendor/jsl-0.3.0/src/fdlibm/e_lgamma_r.c +347 -0
  229. data/vendor/jsl-0.3.0/src/fdlibm/e_log.c +184 -0
  230. data/vendor/jsl-0.3.0/src/fdlibm/e_log10.c +134 -0
  231. data/vendor/jsl-0.3.0/src/fdlibm/e_pow.c +386 -0
  232. data/vendor/jsl-0.3.0/src/fdlibm/e_rem_pio2.c +221 -0
  233. data/vendor/jsl-0.3.0/src/fdlibm/e_remainder.c +120 -0
  234. data/vendor/jsl-0.3.0/src/fdlibm/e_scalb.c +89 -0
  235. data/vendor/jsl-0.3.0/src/fdlibm/e_sinh.c +122 -0
  236. data/vendor/jsl-0.3.0/src/fdlibm/e_sqrt.c +497 -0
  237. data/vendor/jsl-0.3.0/src/fdlibm/fdlibm.dsp +160 -0
  238. data/vendor/jsl-0.3.0/src/fdlibm/fdlibm.h +273 -0
  239. data/vendor/jsl-0.3.0/src/fdlibm/fdlibm.mak +1453 -0
  240. data/vendor/jsl-0.3.0/src/fdlibm/fdlibm.mdp +0 -0
  241. data/vendor/jsl-0.3.0/src/fdlibm/k_cos.c +134 -0
  242. data/vendor/jsl-0.3.0/src/fdlibm/k_rem_pio2.c +354 -0
  243. data/vendor/jsl-0.3.0/src/fdlibm/k_sin.c +114 -0
  244. data/vendor/jsl-0.3.0/src/fdlibm/k_standard.c +785 -0
  245. data/vendor/jsl-0.3.0/src/fdlibm/k_tan.c +170 -0
  246. data/vendor/jsl-0.3.0/src/fdlibm/s_asinh.c +101 -0
  247. data/vendor/jsl-0.3.0/src/fdlibm/s_atan.c +175 -0
  248. data/vendor/jsl-0.3.0/src/fdlibm/s_cbrt.c +133 -0
  249. data/vendor/jsl-0.3.0/src/fdlibm/s_ceil.c +120 -0
  250. data/vendor/jsl-0.3.0/src/fdlibm/s_copysign.c +72 -0
  251. data/vendor/jsl-0.3.0/src/fdlibm/s_cos.c +118 -0
  252. data/vendor/jsl-0.3.0/src/fdlibm/s_erf.c +356 -0
  253. data/vendor/jsl-0.3.0/src/fdlibm/s_expm1.c +267 -0
  254. data/vendor/jsl-0.3.0/src/fdlibm/s_fabs.c +70 -0
  255. data/vendor/jsl-0.3.0/src/fdlibm/s_finite.c +71 -0
  256. data/vendor/jsl-0.3.0/src/fdlibm/s_floor.c +121 -0
  257. data/vendor/jsl-0.3.0/src/fdlibm/s_frexp.c +99 -0
  258. data/vendor/jsl-0.3.0/src/fdlibm/s_ilogb.c +85 -0
  259. data/vendor/jsl-0.3.0/src/fdlibm/s_isnan.c +74 -0
  260. data/vendor/jsl-0.3.0/src/fdlibm/s_ldexp.c +66 -0
  261. data/vendor/jsl-0.3.0/src/fdlibm/s_lib_version.c +73 -0
  262. data/vendor/jsl-0.3.0/src/fdlibm/s_log1p.c +211 -0
  263. data/vendor/jsl-0.3.0/src/fdlibm/s_logb.c +79 -0
  264. data/vendor/jsl-0.3.0/src/fdlibm/s_matherr.c +64 -0
  265. data/vendor/jsl-0.3.0/src/fdlibm/s_modf.c +132 -0
  266. data/vendor/jsl-0.3.0/src/fdlibm/s_nextafter.c +124 -0
  267. data/vendor/jsl-0.3.0/src/fdlibm/s_rint.c +131 -0
  268. data/vendor/jsl-0.3.0/src/fdlibm/s_scalbn.c +107 -0
  269. data/vendor/jsl-0.3.0/src/fdlibm/s_signgam.c +40 -0
  270. data/vendor/jsl-0.3.0/src/fdlibm/s_significand.c +68 -0
  271. data/vendor/jsl-0.3.0/src/fdlibm/s_sin.c +118 -0
  272. data/vendor/jsl-0.3.0/src/fdlibm/s_tan.c +112 -0
  273. data/vendor/jsl-0.3.0/src/fdlibm/s_tanh.c +122 -0
  274. data/vendor/jsl-0.3.0/src/fdlibm/w_acos.c +78 -0
  275. data/vendor/jsl-0.3.0/src/fdlibm/w_acosh.c +78 -0
  276. data/vendor/jsl-0.3.0/src/fdlibm/w_asin.c +80 -0
  277. data/vendor/jsl-0.3.0/src/fdlibm/w_atan2.c +79 -0
  278. data/vendor/jsl-0.3.0/src/fdlibm/w_atanh.c +81 -0
  279. data/vendor/jsl-0.3.0/src/fdlibm/w_cosh.c +77 -0
  280. data/vendor/jsl-0.3.0/src/fdlibm/w_exp.c +88 -0
  281. data/vendor/jsl-0.3.0/src/fdlibm/w_fmod.c +78 -0
  282. data/vendor/jsl-0.3.0/src/fdlibm/w_gamma.c +85 -0
  283. data/vendor/jsl-0.3.0/src/fdlibm/w_gamma_r.c +81 -0
  284. data/vendor/jsl-0.3.0/src/fdlibm/w_hypot.c +78 -0
  285. data/vendor/jsl-0.3.0/src/fdlibm/w_j0.c +105 -0
  286. data/vendor/jsl-0.3.0/src/fdlibm/w_j1.c +106 -0
  287. data/vendor/jsl-0.3.0/src/fdlibm/w_jn.c +128 -0
  288. data/vendor/jsl-0.3.0/src/fdlibm/w_lgamma.c +85 -0
  289. data/vendor/jsl-0.3.0/src/fdlibm/w_lgamma_r.c +81 -0
  290. data/vendor/jsl-0.3.0/src/fdlibm/w_log.c +78 -0
  291. data/vendor/jsl-0.3.0/src/fdlibm/w_log10.c +81 -0
  292. data/vendor/jsl-0.3.0/src/fdlibm/w_pow.c +99 -0
  293. data/vendor/jsl-0.3.0/src/fdlibm/w_remainder.c +77 -0
  294. data/vendor/jsl-0.3.0/src/fdlibm/w_scalb.c +95 -0
  295. data/vendor/jsl-0.3.0/src/fdlibm/w_sinh.c +77 -0
  296. data/vendor/jsl-0.3.0/src/fdlibm/w_sqrt.c +77 -0
  297. data/vendor/jsl-0.3.0/src/js.c +2447 -0
  298. data/vendor/jsl-0.3.0/src/js.dsp +420 -0
  299. data/vendor/jsl-0.3.0/src/js.mak +4025 -0
  300. data/vendor/jsl-0.3.0/src/js.mdp +0 -0
  301. data/vendor/jsl-0.3.0/src/js.msg +291 -0
  302. data/vendor/jsl-0.3.0/src/js.pkg +2 -0
  303. data/vendor/jsl-0.3.0/src/js3240.rc +79 -0
  304. data/vendor/jsl-0.3.0/src/jsOS240.def +654 -0
  305. data/vendor/jsl-0.3.0/src/jsapi.c +4405 -0
  306. data/vendor/jsl-0.3.0/src/jsapi.h +1856 -0
  307. data/vendor/jsl-0.3.0/src/jsarena.c +567 -0
  308. data/vendor/jsl-0.3.0/src/jsarena.h +302 -0
  309. data/vendor/jsl-0.3.0/src/jsarray.c +1428 -0
  310. data/vendor/jsl-0.3.0/src/jsarray.h +77 -0
  311. data/vendor/jsl-0.3.0/src/jsatom.c +927 -0
  312. data/vendor/jsl-0.3.0/src/jsatom.h +426 -0
  313. data/vendor/jsl-0.3.0/src/jsbit.h +113 -0
  314. data/vendor/jsl-0.3.0/src/jsbool.c +220 -0
  315. data/vendor/jsl-0.3.0/src/jsbool.h +62 -0
  316. data/vendor/jsl-0.3.0/src/jsclist.h +139 -0
  317. data/vendor/jsl-0.3.0/src/jscntxt.c +1036 -0
  318. data/vendor/jsl-0.3.0/src/jscntxt.h +608 -0
  319. data/vendor/jsl-0.3.0/src/jscompat.h +57 -0
  320. data/vendor/jsl-0.3.0/src/jsconfig.h +489 -0
  321. data/vendor/jsl-0.3.0/src/jsconfig.mk +181 -0
  322. data/vendor/jsl-0.3.0/src/jscpucfg.c +377 -0
  323. data/vendor/jsl-0.3.0/src/jscpucfg.h +204 -0
  324. data/vendor/jsl-0.3.0/src/jsdate.c +2238 -0
  325. data/vendor/jsl-0.3.0/src/jsdate.h +118 -0
  326. data/vendor/jsl-0.3.0/src/jsdbgapi.c +1260 -0
  327. data/vendor/jsl-0.3.0/src/jsdbgapi.h +345 -0
  328. data/vendor/jsl-0.3.0/src/jsdhash.c +763 -0
  329. data/vendor/jsl-0.3.0/src/jsdhash.h +579 -0
  330. data/vendor/jsl-0.3.0/src/jsdtoa.c +3135 -0
  331. data/vendor/jsl-0.3.0/src/jsdtoa.h +130 -0
  332. data/vendor/jsl-0.3.0/src/jsemit.c +4851 -0
  333. data/vendor/jsl-0.3.0/src/jsemit.h +576 -0
  334. data/vendor/jsl-0.3.0/src/jsexn.c +1084 -0
  335. data/vendor/jsl-0.3.0/src/jsexn.h +102 -0
  336. data/vendor/jsl-0.3.0/src/jsfile.c +2610 -0
  337. data/vendor/jsl-0.3.0/src/jsfile.h +50 -0
  338. data/vendor/jsl-0.3.0/src/jsfile.msg +89 -0
  339. data/vendor/jsl-0.3.0/src/jsfun.c +2015 -0
  340. data/vendor/jsl-0.3.0/src/jsfun.h +158 -0
  341. data/vendor/jsl-0.3.0/src/jsgc.c +1441 -0
  342. data/vendor/jsl-0.3.0/src/jsgc.h +230 -0
  343. data/vendor/jsl-0.3.0/src/jshash.c +471 -0
  344. data/vendor/jsl-0.3.0/src/jshash.h +152 -0
  345. data/vendor/jsl-0.3.0/src/jsify.pl +485 -0
  346. data/vendor/jsl-0.3.0/src/jsinterp.c +4797 -0
  347. data/vendor/jsl-0.3.0/src/jsinterp.h +302 -0
  348. data/vendor/jsl-0.3.0/src/jsl-test.js +28 -0
  349. data/vendor/jsl-0.3.0/src/jsl.c +2371 -0
  350. data/vendor/jsl-0.3.0/src/jsl.conf +127 -0
  351. data/vendor/jsl-0.3.0/src/jsl.conf.old +124 -0
  352. data/vendor/jsl-0.3.0/src/jsl.dsp +242 -0
  353. data/vendor/jsl-0.3.0/src/jsl.dsw +59 -0
  354. data/vendor/jsl-0.3.0/src/jslibmath.h +290 -0
  355. data/vendor/jsl-0.3.0/src/jslock.c +1261 -0
  356. data/vendor/jsl-0.3.0/src/jslock.h +289 -0
  357. data/vendor/jsl-0.3.0/src/jslocko.asm +59 -0
  358. data/vendor/jsl-0.3.0/src/jslog2.c +83 -0
  359. data/vendor/jsl-0.3.0/src/jslong.c +281 -0
  360. data/vendor/jsl-0.3.0/src/jslong.h +437 -0
  361. data/vendor/jsl-0.3.0/src/jsmath.c +477 -0
  362. data/vendor/jsl-0.3.0/src/jsmath.h +55 -0
  363. data/vendor/jsl-0.3.0/src/jsnum.c +1148 -0
  364. data/vendor/jsl-0.3.0/src/jsnum.h +257 -0
  365. data/vendor/jsl-0.3.0/src/jsobj.c +4066 -0
  366. data/vendor/jsl-0.3.0/src/jsobj.h +475 -0
  367. data/vendor/jsl-0.3.0/src/jsopcode.c +2730 -0
  368. data/vendor/jsl-0.3.0/src/jsopcode.h +275 -0
  369. data/vendor/jsl-0.3.0/src/jsopcode.tbl +344 -0
  370. data/vendor/jsl-0.3.0/src/jsosdep.h +127 -0
  371. data/vendor/jsl-0.3.0/src/jsotypes.h +211 -0
  372. data/vendor/jsl-0.3.0/src/jsparse.c +4438 -0
  373. data/vendor/jsl-0.3.0/src/jsparse.h +345 -0
  374. data/vendor/jsl-0.3.0/src/jsprf.c +1212 -0
  375. data/vendor/jsl-0.3.0/src/jsprf.h +148 -0
  376. data/vendor/jsl-0.3.0/src/jsprvtd.h +174 -0
  377. data/vendor/jsl-0.3.0/src/jspubtd.h +586 -0
  378. data/vendor/jsl-0.3.0/src/jsregexp.c +3831 -0
  379. data/vendor/jsl-0.3.0/src/jsregexp.h +180 -0
  380. data/vendor/jsl-0.3.0/src/jsscan.c +1814 -0
  381. data/vendor/jsl-0.3.0/src/jsscan.h +267 -0
  382. data/vendor/jsl-0.3.0/src/jsscope.c +1639 -0
  383. data/vendor/jsl-0.3.0/src/jsscope.h +389 -0
  384. data/vendor/jsl-0.3.0/src/jsscript.c +1284 -0
  385. data/vendor/jsl-0.3.0/src/jsscript.h +179 -0
  386. data/vendor/jsl-0.3.0/src/jsshell.msg +50 -0
  387. data/vendor/jsl-0.3.0/src/jsstddef.h +83 -0
  388. data/vendor/jsl-0.3.0/src/jsstr.c +4502 -0
  389. data/vendor/jsl-0.3.0/src/jsstr.h +448 -0
  390. data/vendor/jsl-0.3.0/src/jstypes.h +391 -0
  391. data/vendor/jsl-0.3.0/src/jsutil.c +157 -0
  392. data/vendor/jsl-0.3.0/src/jsutil.h +75 -0
  393. data/vendor/jsl-0.3.0/src/jsxdrapi.c +686 -0
  394. data/vendor/jsl-0.3.0/src/jsxdrapi.h +193 -0
  395. data/vendor/jsl-0.3.0/src/liveconnect/LiveConnect.dsp +157 -0
  396. data/vendor/jsl-0.3.0/src/liveconnect/LiveConnectShell.dsp +120 -0
  397. data/vendor/jsl-0.3.0/src/liveconnect/LiveConnectShell.dsw +44 -0
  398. data/vendor/jsl-0.3.0/src/liveconnect/Makefile.in +106 -0
  399. data/vendor/jsl-0.3.0/src/liveconnect/Makefile.ref +169 -0
  400. data/vendor/jsl-0.3.0/src/liveconnect/README.html +719 -0
  401. data/vendor/jsl-0.3.0/src/liveconnect/_jni/netscape_javascript_JSException.h +14 -0
  402. data/vendor/jsl-0.3.0/src/liveconnect/_jni/netscape_javascript_JSObject.h +155 -0
  403. data/vendor/jsl-0.3.0/src/liveconnect/classes/Makefile.in +89 -0
  404. data/vendor/jsl-0.3.0/src/liveconnect/classes/Makefile.ref +57 -0
  405. data/vendor/jsl-0.3.0/src/liveconnect/classes/netscape/Makefile.ref +47 -0
  406. data/vendor/jsl-0.3.0/src/liveconnect/classes/netscape/javascript/JSException.java +140 -0
  407. data/vendor/jsl-0.3.0/src/liveconnect/classes/netscape/javascript/JSObject.java +183 -0
  408. data/vendor/jsl-0.3.0/src/liveconnect/classes/netscape/javascript/JSProxy.java +58 -0
  409. data/vendor/jsl-0.3.0/src/liveconnect/classes/netscape/javascript/JSRunnable.java +70 -0
  410. data/vendor/jsl-0.3.0/src/liveconnect/classes/netscape/javascript/JSUtil.java +59 -0
  411. data/vendor/jsl-0.3.0/src/liveconnect/classes/netscape/javascript/Makefile.ref +53 -0
  412. data/vendor/jsl-0.3.0/src/liveconnect/config/AIX4.1.mk +45 -0
  413. data/vendor/jsl-0.3.0/src/liveconnect/config/AIX4.2.mk +45 -0
  414. data/vendor/jsl-0.3.0/src/liveconnect/config/AIX4.3.mk +50 -0
  415. data/vendor/jsl-0.3.0/src/liveconnect/config/HP-UXB.10.10.mk +43 -0
  416. data/vendor/jsl-0.3.0/src/liveconnect/config/HP-UXB.10.20.mk +43 -0
  417. data/vendor/jsl-0.3.0/src/liveconnect/config/HP-UXB.11.00.mk +43 -0
  418. data/vendor/jsl-0.3.0/src/liveconnect/config/IRIX6.2.mk +43 -0
  419. data/vendor/jsl-0.3.0/src/liveconnect/config/IRIX6.3.mk +43 -0
  420. data/vendor/jsl-0.3.0/src/liveconnect/config/IRIX6.5.mk +43 -0
  421. data/vendor/jsl-0.3.0/src/liveconnect/config/Linux_All.mk +73 -0
  422. data/vendor/jsl-0.3.0/src/liveconnect/config/OSF1V4.0.mk +65 -0
  423. data/vendor/jsl-0.3.0/src/liveconnect/config/OSF1V5.0.mk +62 -0
  424. data/vendor/jsl-0.3.0/src/liveconnect/config/SunOS5.5.1.mk +55 -0
  425. data/vendor/jsl-0.3.0/src/liveconnect/config/SunOS5.6.mk +39 -0
  426. data/vendor/jsl-0.3.0/src/liveconnect/config/SunOS5.7.mk +39 -0
  427. data/vendor/jsl-0.3.0/src/liveconnect/config/SunOS5.8.mk +39 -0
  428. data/vendor/jsl-0.3.0/src/liveconnect/config/WINNT4.0.mk +53 -0
  429. data/vendor/jsl-0.3.0/src/liveconnect/jsj.c +884 -0
  430. data/vendor/jsl-0.3.0/src/liveconnect/jsj.msg +98 -0
  431. data/vendor/jsl-0.3.0/src/liveconnect/jsj_JSObject.c +1379 -0
  432. data/vendor/jsl-0.3.0/src/liveconnect/jsj_JavaArray.c +481 -0
  433. data/vendor/jsl-0.3.0/src/liveconnect/jsj_JavaClass.c +749 -0
  434. data/vendor/jsl-0.3.0/src/liveconnect/jsj_JavaMember.c +186 -0
  435. data/vendor/jsl-0.3.0/src/liveconnect/jsj_JavaObject.c +1099 -0
  436. data/vendor/jsl-0.3.0/src/liveconnect/jsj_JavaPackage.c +548 -0
  437. data/vendor/jsl-0.3.0/src/liveconnect/jsj_array.c +207 -0
  438. data/vendor/jsl-0.3.0/src/liveconnect/jsj_class.c +765 -0
  439. data/vendor/jsl-0.3.0/src/liveconnect/jsj_convert.c +954 -0
  440. data/vendor/jsl-0.3.0/src/liveconnect/jsj_field.c +421 -0
  441. data/vendor/jsl-0.3.0/src/liveconnect/jsj_hash.c +504 -0
  442. data/vendor/jsl-0.3.0/src/liveconnect/jsj_hash.h +161 -0
  443. data/vendor/jsl-0.3.0/src/liveconnect/jsj_method.c +1823 -0
  444. data/vendor/jsl-0.3.0/src/liveconnect/jsj_nodl.c +1 -0
  445. data/vendor/jsl-0.3.0/src/liveconnect/jsj_private.h +689 -0
  446. data/vendor/jsl-0.3.0/src/liveconnect/jsj_simpleapi.c +219 -0
  447. data/vendor/jsl-0.3.0/src/liveconnect/jsj_utils.c +513 -0
  448. data/vendor/jsl-0.3.0/src/liveconnect/jsjava.h +313 -0
  449. data/vendor/jsl-0.3.0/src/liveconnect/liveconnect.pkg +3 -0
  450. data/vendor/jsl-0.3.0/src/liveconnect/netscape_javascript_JSObject.h +155 -0
  451. data/vendor/jsl-0.3.0/src/liveconnect/nsCLiveconnect.cpp +785 -0
  452. data/vendor/jsl-0.3.0/src/liveconnect/nsCLiveconnect.h +197 -0
  453. data/vendor/jsl-0.3.0/src/liveconnect/nsCLiveconnectFactory.cpp +163 -0
  454. data/vendor/jsl-0.3.0/src/liveconnect/nsCLiveconnectFactory.h +76 -0
  455. data/vendor/jsl-0.3.0/src/liveconnect/nsILiveconnect.h +195 -0
  456. data/vendor/jsl-0.3.0/src/liveconnect/nsISecureLiveconnect.h +84 -0
  457. data/vendor/jsl-0.3.0/src/liveconnect/nsISecurityContext.h +135 -0
  458. data/vendor/jsl-0.3.0/src/liveconnect/win32.order +6 -0
  459. data/vendor/jsl-0.3.0/src/lock_SunOS.s +114 -0
  460. data/vendor/jsl-0.3.0/src/perfect.js +39 -0
  461. data/vendor/jsl-0.3.0/src/perlconnect/JS.def +6 -0
  462. data/vendor/jsl-0.3.0/src/perlconnect/JS.dsp +107 -0
  463. data/vendor/jsl-0.3.0/src/perlconnect/JS.pm +318 -0
  464. data/vendor/jsl-0.3.0/src/perlconnect/JS.xs +1050 -0
  465. data/vendor/jsl-0.3.0/src/perlconnect/Makefile.PL +67 -0
  466. data/vendor/jsl-0.3.0/src/perlconnect/Makefile.ref +152 -0
  467. data/vendor/jsl-0.3.0/src/perlconnect/PerlConnect.dsp +103 -0
  468. data/vendor/jsl-0.3.0/src/perlconnect/PerlConnect.dsw +59 -0
  469. data/vendor/jsl-0.3.0/src/perlconnect/PerlConnect.pm +126 -0
  470. data/vendor/jsl-0.3.0/src/perlconnect/PerlConnectShell.dsp +89 -0
  471. data/vendor/jsl-0.3.0/src/perlconnect/README.html +345 -0
  472. data/vendor/jsl-0.3.0/src/perlconnect/bg.jpg +0 -0
  473. data/vendor/jsl-0.3.0/src/perlconnect/jsperl.c +1100 -0
  474. data/vendor/jsl-0.3.0/src/perlconnect/jsperl.h +52 -0
  475. data/vendor/jsl-0.3.0/src/perlconnect/jsperlbuild.pl +81 -0
  476. data/vendor/jsl-0.3.0/src/perlconnect/jsperlpvt.h +57 -0
  477. data/vendor/jsl-0.3.0/src/perlconnect/test.js +73 -0
  478. data/vendor/jsl-0.3.0/src/perlconnect/test.pl +244 -0
  479. data/vendor/jsl-0.3.0/src/perlconnect/typemap +121 -0
  480. data/vendor/jsl-0.3.0/src/plify_jsdhash.sed +31 -0
  481. data/vendor/jsl-0.3.0/src/prmjtime.c +646 -0
  482. data/vendor/jsl-0.3.0/src/prmjtime.h +95 -0
  483. data/vendor/jsl-0.3.0/src/resource.h +15 -0
  484. data/vendor/jsl-0.3.0/src/rules.mk +193 -0
  485. data/vendor/jsl-0.3.0/src/win32.order +391 -0
  486. data/vendor/jsl-0.3.0/tests/conf/always_use_option_explicit.js +4 -0
  487. data/vendor/jsl-0.3.0/tests/conf/define.js +8 -0
  488. data/vendor/jsl-0.3.0/tests/conf/jscript_function_extensions-1.js +7 -0
  489. data/vendor/jsl-0.3.0/tests/conf/jscript_function_extensions-2.js +8 -0
  490. data/vendor/jsl-0.3.0/tests/conf/jscript_function_extensions-3.js +27 -0
  491. data/vendor/jsl-0.3.0/tests/conf/jscript_function_extensions-4.js +4 -0
  492. data/vendor/jsl-0.3.0/tests/conf/lambda_assign_requires_semicolon.js +24 -0
  493. data/vendor/jsl-0.3.0/tests/conf/legacy_control_comments.js +8 -0
  494. data/vendor/jsl-0.3.0/tests/control_comments/control_comments.js +33 -0
  495. data/vendor/jsl-0.3.0/tests/control_comments/declare.js +26 -0
  496. data/vendor/jsl-0.3.0/tests/control_comments/import-overflow.js +9 -0
  497. data/vendor/jsl-0.3.0/tests/control_comments/import.js +5 -0
  498. data/vendor/jsl-0.3.0/tests/control_comments/import2.js +2 -0
  499. data/vendor/jsl-0.3.0/tests/control_comments/invalid_fallthru.js +13 -0
  500. data/vendor/jsl-0.3.0/tests/control_comments/option_explicit-with.js +12 -0
  501. data/vendor/jsl-0.3.0/tests/control_comments/option_explicit.js +64 -0
  502. data/vendor/jsl-0.3.0/tests/errors/unterminated_comment.js +8 -0
  503. data/vendor/jsl-0.3.0/tests/html/script_tag_in_js_literal.html +14 -0
  504. data/vendor/jsl-0.3.0/tests/run_tests.pl +71 -0
  505. data/vendor/jsl-0.3.0/tests/warnings/ambiguous_else_stmt.js +21 -0
  506. data/vendor/jsl-0.3.0/tests/warnings/ambiguous_nested_stmt.js +66 -0
  507. data/vendor/jsl-0.3.0/tests/warnings/ambiguous_newline.js +261 -0
  508. data/vendor/jsl-0.3.0/tests/warnings/anon_no_return_value.js +26 -0
  509. data/vendor/jsl-0.3.0/tests/warnings/assign_to_function_call.js +16 -0
  510. data/vendor/jsl-0.3.0/tests/warnings/block_without_braces.js +13 -0
  511. data/vendor/jsl-0.3.0/tests/warnings/comma_separated_stmts.js +17 -0
  512. data/vendor/jsl-0.3.0/tests/warnings/comparison_type_conv.js +44 -0
  513. data/vendor/jsl-0.3.0/tests/warnings/default_not_at_end.js +15 -0
  514. data/vendor/jsl-0.3.0/tests/warnings/dup_option_explicit.js +5 -0
  515. data/vendor/jsl-0.3.0/tests/warnings/duplicate_case_in_switch.js +62 -0
  516. data/vendor/jsl-0.3.0/tests/warnings/duplicate_formal.js +5 -0
  517. data/vendor/jsl-0.3.0/tests/warnings/empty_statement.js +29 -0
  518. data/vendor/jsl-0.3.0/tests/warnings/equal_as_assign.js +7 -0
  519. data/vendor/jsl-0.3.0/tests/warnings/inc_dec_within_stmt-ignore.js +21 -0
  520. data/vendor/jsl-0.3.0/tests/warnings/inc_dec_within_stmt.js +63 -0
  521. data/vendor/jsl-0.3.0/tests/warnings/jsl_cc_not_understood.js +5 -0
  522. data/vendor/jsl-0.3.0/tests/warnings/leading_decimal_point.js +7 -0
  523. data/vendor/jsl-0.3.0/tests/warnings/legacy_cc_not_understood.js +9 -0
  524. data/vendor/jsl-0.3.0/tests/warnings/meaningless_block.js +12 -0
  525. data/vendor/jsl-0.3.0/tests/warnings/misplaced_regex.js +20 -0
  526. data/vendor/jsl-0.3.0/tests/warnings/missing_break.js +87 -0
  527. data/vendor/jsl-0.3.0/tests/warnings/missing_break_for_last_case.js +19 -0
  528. data/vendor/jsl-0.3.0/tests/warnings/missing_default_case.js +51 -0
  529. data/vendor/jsl-0.3.0/tests/warnings/missing_option_explicit.js +5 -0
  530. data/vendor/jsl-0.3.0/tests/warnings/missing_semicolon.js +19 -0
  531. data/vendor/jsl-0.3.0/tests/warnings/multiple_plus_minus.js +10 -0
  532. data/vendor/jsl-0.3.0/tests/warnings/nested_comment.js +6 -0
  533. data/vendor/jsl-0.3.0/tests/warnings/no_return_value.js +25 -0
  534. data/vendor/jsl-0.3.0/tests/warnings/octal_number.js +5 -0
  535. data/vendor/jsl-0.3.0/tests/warnings/parseint_missing_radix.js +15 -0
  536. data/vendor/jsl-0.3.0/tests/warnings/partial_option_explicit.js +5 -0
  537. data/vendor/jsl-0.3.0/tests/warnings/redeclared_var.js +10 -0
  538. data/vendor/jsl-0.3.0/tests/warnings/spidermonkey/bad_backref.js +5 -0
  539. data/vendor/jsl-0.3.0/tests/warnings/spidermonkey/deprecated_usage.js +11 -0
  540. data/vendor/jsl-0.3.0/tests/warnings/spidermonkey/invalid_backref.js +5 -0
  541. data/vendor/jsl-0.3.0/tests/warnings/spidermonkey/trailing_comma.js +5 -0
  542. data/vendor/jsl-0.3.0/tests/warnings/trailing_comma_in_array.js +8 -0
  543. data/vendor/jsl-0.3.0/tests/warnings/trailing_decimal_point.js +7 -0
  544. data/vendor/jsl-0.3.0/tests/warnings/unreachable_code.js +29 -0
  545. data/vendor/jsl-0.3.0/tests/warnings/use_of_label.js +19 -0
  546. data/vendor/jsl-0.3.0/tests/warnings/useless_assign.js +20 -0
  547. data/vendor/jsl-0.3.0/tests/warnings/useless_comparison.js +55 -0
  548. data/vendor/jsl-0.3.0/tests/warnings/useless_void.js +6 -0
  549. data/vendor/jsl-0.3.0/tests/warnings/var_hides_arg.js +4 -0
  550. data/vendor/jsl-0.3.0/tests/warnings/with_statement.js +7 -0
  551. data/vendor/yuicompressor-2.4.2.jar +0 -0
  552. metadata +605 -0
@@ -0,0 +1,2730 @@
1
+ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2
+ *
3
+ * ***** BEGIN LICENSE BLOCK *****
4
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5
+ *
6
+ * The contents of this file are subject to the Mozilla Public License Version
7
+ * 1.1 (the "License"); you may not use this file except in compliance with
8
+ * the License. You may obtain a copy of the License at
9
+ * http://www.mozilla.org/MPL/
10
+ *
11
+ * Software distributed under the License is distributed on an "AS IS" basis,
12
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13
+ * for the specific language governing rights and limitations under the
14
+ * License.
15
+ *
16
+ * The Original Code is Mozilla Communicator client code, released
17
+ * March 31, 1998.
18
+ *
19
+ * The Initial Developer of the Original Code is
20
+ * Netscape Communications Corporation.
21
+ * Portions created by the Initial Developer are Copyright (C) 1998
22
+ * the Initial Developer. All Rights Reserved.
23
+ *
24
+ * Contributor(s):
25
+ *
26
+ * Alternatively, the contents of this file may be used under the terms of
27
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
28
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29
+ * in which case the provisions of the GPL or the LGPL are applicable instead
30
+ * of those above. If you wish to allow use of your version of this file only
31
+ * under the terms of either the GPL or the LGPL, and not to allow others to
32
+ * use your version of this file under the terms of the MPL, indicate your
33
+ * decision by deleting the provisions above and replace them with the notice
34
+ * and other provisions required by the GPL or the LGPL. If you do not delete
35
+ * the provisions above, a recipient may use your version of this file under
36
+ * the terms of any one of the MPL, the GPL or the LGPL.
37
+ *
38
+ * ***** END LICENSE BLOCK ***** */
39
+
40
+ /*
41
+ * JS bytecode descriptors, disassemblers, and decompilers.
42
+ */
43
+ #include "jsstddef.h"
44
+ #ifdef HAVE_MEMORY_H
45
+ #include <memory.h>
46
+ #endif
47
+ #include <stdarg.h>
48
+ #include <stdio.h>
49
+ #include <stdlib.h>
50
+ #include <string.h>
51
+ #include "jstypes.h"
52
+ #include "jsarena.h" /* Added by JSIFY */
53
+ #include "jsutil.h" /* Added by JSIFY */
54
+ #include "jsdtoa.h"
55
+ #include "jsprf.h"
56
+ #include "jsapi.h"
57
+ #include "jsarray.h"
58
+ #include "jsatom.h"
59
+ #include "jscntxt.h"
60
+ #include "jsconfig.h"
61
+ #include "jsdbgapi.h"
62
+ #include "jsemit.h"
63
+ #include "jsfun.h"
64
+ #include "jslock.h"
65
+ #include "jsobj.h"
66
+ #include "jsopcode.h"
67
+ #include "jsregexp.h"
68
+ #include "jsscope.h"
69
+ #include "jsscript.h"
70
+ #include "jsstr.h"
71
+
72
+ const char js_const_str[] = "const";
73
+ const char js_var_str[] = "var";
74
+ const char js_function_str[] = "function";
75
+ const char js_in_str[] = "in";
76
+ const char js_instanceof_str[] = "instanceof";
77
+ const char js_new_str[] = "new";
78
+ const char js_delete_str[] = "delete";
79
+ const char js_typeof_str[] = "typeof";
80
+ const char js_void_str[] = "void";
81
+ const char js_null_str[] = "null";
82
+ const char js_this_str[] = "this";
83
+ const char js_false_str[] = "false";
84
+ const char js_true_str[] = "true";
85
+
86
+ const char *js_incop_str[] = {"++", "--"};
87
+
88
+ /* Pollute the namespace locally for MSVC Win16, but not for WatCom. */
89
+ #ifdef __WINDOWS_386__
90
+ #ifdef FAR
91
+ #undef FAR
92
+ #endif
93
+ #else /* !__WINDOWS_386__ */
94
+ #ifndef FAR
95
+ #define FAR
96
+ #endif
97
+ #endif /* !__WINDOWS_386__ */
98
+
99
+ const JSCodeSpec FAR js_CodeSpec[] = {
100
+ #define OPDEF(op,val,name,token,length,nuses,ndefs,prec,format) \
101
+ {name,token,length,nuses,ndefs,prec,format},
102
+ #include "jsopcode.tbl"
103
+ #undef OPDEF
104
+ };
105
+
106
+ uintN js_NumCodeSpecs = sizeof (js_CodeSpec) / sizeof js_CodeSpec[0];
107
+
108
+ /************************************************************************/
109
+
110
+ static ptrdiff_t
111
+ GetJumpOffset(jsbytecode *pc, jsbytecode *pc2)
112
+ {
113
+ uint32 type;
114
+
115
+ type = (js_CodeSpec[*pc].format & JOF_TYPEMASK);
116
+ if (JOF_TYPE_IS_EXTENDED_JUMP(type))
117
+ return GET_JUMPX_OFFSET(pc2);
118
+ return GET_JUMP_OFFSET(pc2);
119
+ }
120
+
121
+ #ifdef DEBUG
122
+
123
+ JS_FRIEND_API(void)
124
+ js_Disassemble(JSContext *cx, JSScript *script, JSBool lines, FILE *fp)
125
+ {
126
+ jsbytecode *pc, *end;
127
+ uintN len;
128
+
129
+ pc = script->code;
130
+ end = pc + script->length;
131
+ while (pc < end) {
132
+ if (pc == script->main)
133
+ fputs("main:\n", fp);
134
+ len = js_Disassemble1(cx, script, pc,
135
+ PTRDIFF(pc, script->code, jsbytecode),
136
+ lines, fp);
137
+ if (!len)
138
+ return;
139
+ pc += len;
140
+ }
141
+ }
142
+
143
+ JS_FRIEND_API(uintN)
144
+ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc, uintN loc,
145
+ JSBool lines, FILE *fp)
146
+ {
147
+ JSOp op;
148
+ const JSCodeSpec *cs;
149
+ ptrdiff_t len, off, jmplen;
150
+ uint32 type;
151
+ JSAtom *atom;
152
+ JSString *str;
153
+ char *cstr;
154
+
155
+ op = (JSOp)*pc;
156
+ if (op >= JSOP_LIMIT) {
157
+ char numBuf1[12], numBuf2[12];
158
+ JS_snprintf(numBuf1, sizeof numBuf1, "%d", op);
159
+ JS_snprintf(numBuf2, sizeof numBuf2, "%d", JSOP_LIMIT);
160
+ JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
161
+ JSMSG_BYTECODE_TOO_BIG, numBuf1, numBuf2);
162
+ return 0;
163
+ }
164
+ cs = &js_CodeSpec[op];
165
+ len = (ptrdiff_t) cs->length;
166
+ fprintf(fp, "%05u:", loc);
167
+ if (lines)
168
+ fprintf(fp, "%4u", JS_PCToLineNumber(cx, script, pc));
169
+ fprintf(fp, " %s", cs->name);
170
+ type = cs->format & JOF_TYPEMASK;
171
+ switch (type) {
172
+ case JOF_BYTE:
173
+ if (op == JSOP_TRAP) {
174
+ op = JS_GetTrapOpcode(cx, script, pc);
175
+ if (op == JSOP_LIMIT)
176
+ return 0;
177
+ len = (ptrdiff_t) js_CodeSpec[op].length;
178
+ }
179
+ break;
180
+
181
+ case JOF_JUMP:
182
+ case JOF_JUMPX:
183
+ off = GetJumpOffset(pc, pc);
184
+ fprintf(fp, " %u (%d)", loc + off, off);
185
+ break;
186
+
187
+ case JOF_CONST:
188
+ atom = GET_ATOM(cx, script, pc);
189
+ str = js_ValueToSource(cx, ATOM_KEY(atom));
190
+ if (!str)
191
+ return 0;
192
+ cstr = js_DeflateString(cx, JSSTRING_CHARS(str), JSSTRING_LENGTH(str));
193
+ if (!cstr)
194
+ return 0;
195
+ fprintf(fp, " %s", cstr);
196
+ JS_free(cx, cstr);
197
+ break;
198
+
199
+ case JOF_UINT16:
200
+ fprintf(fp, " %u", GET_ARGC(pc));
201
+ break;
202
+
203
+ #if JS_HAS_SWITCH_STATEMENT
204
+ case JOF_TABLESWITCH:
205
+ case JOF_TABLESWITCHX:
206
+ {
207
+ jsbytecode *pc2;
208
+ jsint i, low, high;
209
+
210
+ jmplen = (type == JOF_TABLESWITCH) ? JUMP_OFFSET_LEN
211
+ : JUMPX_OFFSET_LEN;
212
+ pc2 = pc;
213
+ off = GetJumpOffset(pc, pc2);
214
+ pc2 += jmplen;
215
+ low = GET_JUMP_OFFSET(pc2);
216
+ pc2 += JUMP_OFFSET_LEN;
217
+ high = GET_JUMP_OFFSET(pc2);
218
+ pc2 += JUMP_OFFSET_LEN;
219
+ fprintf(fp, " defaultOffset %d low %d high %d", off, low, high);
220
+ for (i = low; i <= high; i++) {
221
+ off = GetJumpOffset(pc, pc2);
222
+ fprintf(fp, "\n\t%d: %d", i, off);
223
+ pc2 += jmplen;
224
+ }
225
+ len = 1 + pc2 - pc;
226
+ break;
227
+ }
228
+
229
+ case JOF_LOOKUPSWITCH:
230
+ case JOF_LOOKUPSWITCHX:
231
+ {
232
+ jsbytecode *pc2;
233
+ jsatomid npairs;
234
+
235
+ jmplen = (type == JOF_LOOKUPSWITCH) ? JUMP_OFFSET_LEN
236
+ : JUMPX_OFFSET_LEN;
237
+ pc2 = pc;
238
+ off = GetJumpOffset(pc, pc2);
239
+ pc2 += jmplen;
240
+ npairs = GET_ATOM_INDEX(pc2);
241
+ pc2 += ATOM_INDEX_LEN;
242
+ fprintf(fp, " offset %d npairs %u", off, (uintN) npairs);
243
+ while (npairs) {
244
+ atom = GET_ATOM(cx, script, pc2);
245
+ pc2 += ATOM_INDEX_LEN;
246
+ off = GetJumpOffset(pc, pc2);
247
+ pc2 += jmplen;
248
+
249
+ str = js_ValueToSource(cx, ATOM_KEY(atom));
250
+ if (!str)
251
+ return 0;
252
+ cstr = js_DeflateString(cx, JSSTRING_CHARS(str),
253
+ JSSTRING_LENGTH(str));
254
+ if (!cstr)
255
+ return 0;
256
+ fprintf(fp, "\n\t%s: %d", cstr, off);
257
+ JS_free(cx, cstr);
258
+ npairs--;
259
+ }
260
+ len = 1 + pc2 - pc;
261
+ break;
262
+ }
263
+ #endif /* JS_HAS_SWITCH_STATEMENT */
264
+
265
+ case JOF_QARG:
266
+ fprintf(fp, " %u", GET_ARGNO(pc));
267
+ break;
268
+
269
+ case JOF_QVAR:
270
+ fprintf(fp, " %u", GET_VARNO(pc));
271
+ break;
272
+
273
+ #if JS_HAS_LEXICAL_CLOSURE
274
+ case JOF_DEFLOCALVAR:
275
+ fprintf(fp, " %u", GET_VARNO(pc));
276
+ pc += VARNO_LEN;
277
+ atom = GET_ATOM(cx, script, pc);
278
+ str = js_ValueToSource(cx, ATOM_KEY(atom));
279
+ if (!str)
280
+ return 0;
281
+ cstr = js_DeflateString(cx, JSSTRING_CHARS(str), JSSTRING_LENGTH(str));
282
+ if (!cstr)
283
+ return 0;
284
+ fprintf(fp, " %s", cstr);
285
+ JS_free(cx, cstr);
286
+ break;
287
+ #endif
288
+
289
+ default: {
290
+ char numBuf[12];
291
+ JS_snprintf(numBuf, sizeof numBuf, "%lx", (unsigned long) cs->format);
292
+ JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
293
+ JSMSG_UNKNOWN_FORMAT, numBuf);
294
+ return 0;
295
+ }
296
+ }
297
+ fputs("\n", fp);
298
+ return len;
299
+ }
300
+
301
+ #endif /* DEBUG */
302
+
303
+ /************************************************************************/
304
+
305
+ /*
306
+ * Sprintf, but with unlimited and automatically allocated buffering.
307
+ */
308
+ typedef struct Sprinter {
309
+ JSContext *context; /* context executing the decompiler */
310
+ JSArenaPool *pool; /* string allocation pool */
311
+ char *base; /* base address of buffer in pool */
312
+ size_t size; /* size of buffer allocated at base */
313
+ ptrdiff_t offset; /* offset of next free char in buffer */
314
+ } Sprinter;
315
+
316
+ #define INIT_SPRINTER(cx, sp, ap, off) \
317
+ ((sp)->context = cx, (sp)->pool = ap, (sp)->base = NULL, (sp)->size = 0, \
318
+ (sp)->offset = off)
319
+
320
+ #define OFF2STR(sp,off) ((sp)->base + (off))
321
+ #define STR2OFF(sp,str) ((str) - (sp)->base)
322
+ #define RETRACT(sp,str) ((sp)->offset = STR2OFF(sp, str))
323
+
324
+ static JSBool
325
+ SprintAlloc(Sprinter *sp, size_t nb)
326
+ {
327
+ if (!sp->base) {
328
+ JS_ARENA_ALLOCATE_CAST(sp->base, char *, sp->pool, nb);
329
+ } else {
330
+ JS_ARENA_GROW_CAST(sp->base, char *, sp->pool, sp->size, nb);
331
+ }
332
+ if (!sp->base) {
333
+ JS_ReportOutOfMemory(sp->context);
334
+ return JS_FALSE;
335
+ }
336
+ sp->size += nb;
337
+ return JS_TRUE;
338
+ }
339
+
340
+ static ptrdiff_t
341
+ SprintPut(Sprinter *sp, const char *s, size_t len)
342
+ {
343
+ ptrdiff_t nb, offset;
344
+ char *bp;
345
+
346
+ /* Allocate space for s, including the '\0' at the end. */
347
+ nb = (sp->offset + len + 1) - sp->size;
348
+ if (nb > 0 && !SprintAlloc(sp, nb))
349
+ return -1;
350
+
351
+ /* Advance offset and copy s into sp's buffer. */
352
+ offset = sp->offset;
353
+ sp->offset += len;
354
+ bp = sp->base + offset;
355
+ memmove(bp, s, len);
356
+ bp[len] = 0;
357
+ return offset;
358
+ }
359
+
360
+ static ptrdiff_t
361
+ Sprint(Sprinter *sp, const char *format, ...)
362
+ {
363
+ va_list ap;
364
+ char *bp;
365
+ ptrdiff_t offset;
366
+
367
+ va_start(ap, format);
368
+ bp = JS_vsmprintf(format, ap); /* XXX vsaprintf */
369
+ va_end(ap);
370
+ if (!bp) {
371
+ JS_ReportOutOfMemory(sp->context);
372
+ return -1;
373
+ }
374
+ offset = SprintPut(sp, bp, strlen(bp));
375
+ free(bp);
376
+ return offset;
377
+ }
378
+
379
+ const jschar js_EscapeMap[] = {
380
+ '\b', 'b',
381
+ '\f', 'f',
382
+ '\n', 'n',
383
+ '\r', 'r',
384
+ '\t', 't',
385
+ '\v', 'v',
386
+ '"', '"',
387
+ '\'', '\'',
388
+ '\\', '\\',
389
+ 0
390
+ };
391
+
392
+ static char *
393
+ QuoteString(Sprinter *sp, JSString *str, jschar quote)
394
+ {
395
+ ptrdiff_t off, len, nb;
396
+ const jschar *s, *t, *u, *z;
397
+ char *bp;
398
+ jschar c;
399
+ JSBool ok;
400
+
401
+ /* Sample off first for later return value pointer computation. */
402
+ off = sp->offset;
403
+ if (quote && Sprint(sp, "%c", (char)quote) < 0)
404
+ return NULL;
405
+
406
+ /* Loop control variables: z points at end of string sentinel. */
407
+ s = JSSTRING_CHARS(str);
408
+ z = s + JSSTRING_LENGTH(str);
409
+ for (t = s; t < z; s = ++t) {
410
+ /* Move t forward from s past un-quote-worthy characters. */
411
+ c = *t;
412
+ while (JS_ISPRINT(c) && c != quote && c != '\\' && !(c >> 8)) {
413
+ c = *++t;
414
+ if (t == z)
415
+ break;
416
+ }
417
+ len = PTRDIFF(t, s, jschar);
418
+
419
+ /* Allocate space for s, including the '\0' at the end. */
420
+ nb = (sp->offset + len + 1) - sp->size;
421
+ if (nb > 0 && !SprintAlloc(sp, nb))
422
+ return NULL;
423
+
424
+ /* Advance sp->offset and copy s into sp's buffer. */
425
+ bp = sp->base + sp->offset;
426
+ sp->offset += len;
427
+ while (--len >= 0)
428
+ *bp++ = (char) *s++;
429
+ *bp = '\0';
430
+
431
+ if (t == z)
432
+ break;
433
+
434
+ /* Use js_EscapeMap, \u, or \x only if necessary. */
435
+ if ((u = js_strchr(js_EscapeMap, c)) != NULL)
436
+ ok = Sprint(sp, "\\%c", (char)u[1]) >= 0;
437
+ else
438
+ ok = Sprint(sp, (c >> 8) ? "\\u%04X" : "\\x%02X", c) >= 0;
439
+ if (!ok)
440
+ return NULL;
441
+ }
442
+
443
+ /* Sprint the closing quote and return the quoted string. */
444
+ if (quote && Sprint(sp, "%c", (char)quote) < 0)
445
+ return NULL;
446
+ return OFF2STR(sp, off);
447
+ }
448
+
449
+ JSString *
450
+ js_QuoteString(JSContext *cx, JSString *str, jschar quote)
451
+ {
452
+ void *mark;
453
+ Sprinter sprinter;
454
+ char *bytes;
455
+ JSString *escstr;
456
+
457
+ mark = JS_ARENA_MARK(&cx->tempPool);
458
+ INIT_SPRINTER(cx, &sprinter, &cx->tempPool, 0);
459
+ bytes = QuoteString(&sprinter, str, quote);
460
+ escstr = bytes ? JS_NewStringCopyZ(cx, bytes) : NULL;
461
+ JS_ARENA_RELEASE(&cx->tempPool, mark);
462
+ return escstr;
463
+ }
464
+
465
+ /************************************************************************/
466
+
467
+ struct JSPrinter {
468
+ Sprinter sprinter; /* base class state */
469
+ JSArenaPool pool; /* string allocation pool */
470
+ uintN indent; /* indentation in spaces */
471
+ JSPackedBool pretty; /* pretty-print: indent, use newlines */
472
+ JSPackedBool grouped; /* in parenthesized expression context */
473
+ JSScript *script; /* script being printed */
474
+ JSScope *scope; /* script function scope */
475
+ };
476
+
477
+ /*
478
+ * Hack another flag, a la JS_DONT_PRETTY_PRINT, into uintN indent parameters
479
+ * to functions such as js_DecompileFunction and js_NewPrinter. This time, as
480
+ * opposed to JS_DONT_PRETTY_PRINT back in the dark ages, we can assume that a
481
+ * uintN is at least 32 bits.
482
+ */
483
+ #define JS_IN_GROUP_CONTEXT 0x10000
484
+
485
+ JSPrinter *
486
+ js_NewPrinter(JSContext *cx, const char *name, uintN indent, JSBool pretty)
487
+ {
488
+ JSPrinter *jp;
489
+
490
+ jp = (JSPrinter *) JS_malloc(cx, sizeof(JSPrinter));
491
+ if (!jp)
492
+ return NULL;
493
+ INIT_SPRINTER(cx, &jp->sprinter, &jp->pool, 0);
494
+ JS_InitArenaPool(&jp->pool, name, 256, 1);
495
+ jp->indent = indent & ~JS_IN_GROUP_CONTEXT;
496
+ jp->pretty = pretty;
497
+ jp->grouped = (indent & JS_IN_GROUP_CONTEXT) != 0;
498
+ jp->script = NULL;
499
+ jp->scope = NULL;
500
+ return jp;
501
+ }
502
+
503
+ void
504
+ js_DestroyPrinter(JSPrinter *jp)
505
+ {
506
+ JS_FinishArenaPool(&jp->pool);
507
+ JS_free(jp->sprinter.context, jp);
508
+ }
509
+
510
+ JSString *
511
+ js_GetPrinterOutput(JSPrinter *jp)
512
+ {
513
+ JSContext *cx;
514
+ JSString *str;
515
+
516
+ cx = jp->sprinter.context;
517
+ if (!jp->sprinter.base)
518
+ return cx->runtime->emptyString;
519
+ str = JS_NewStringCopyZ(cx, jp->sprinter.base);
520
+ if (!str)
521
+ return NULL;
522
+ JS_FreeArenaPool(&jp->pool);
523
+ INIT_SPRINTER(cx, &jp->sprinter, &jp->pool, 0);
524
+ return str;
525
+ }
526
+
527
+ int
528
+ js_printf(JSPrinter *jp, const char *format, ...)
529
+ {
530
+ va_list ap;
531
+ char *bp, *fp;
532
+ int cc;
533
+
534
+ if (*format == '\0')
535
+ return 0;
536
+
537
+ va_start(ap, format);
538
+
539
+ /* If pretty-printing, expand magic tab into a run of jp->indent spaces. */
540
+ if (*format == '\t') {
541
+ if (jp->pretty && Sprint(&jp->sprinter, "%*s", jp->indent, "") < 0)
542
+ return -1;
543
+ format++;
544
+ }
545
+
546
+ /* Suppress newlines (must be once per format, at the end) if not pretty. */
547
+ fp = NULL;
548
+ if (!jp->pretty && format[cc = strlen(format)-1] == '\n') {
549
+ fp = JS_strdup(jp->sprinter.context, format);
550
+ if (!fp)
551
+ return -1;
552
+ fp[cc] = '\0';
553
+ format = fp;
554
+ }
555
+
556
+ /* Allocate temp space, convert format, and put. */
557
+ bp = JS_vsmprintf(format, ap); /* XXX vsaprintf */
558
+ if (fp) {
559
+ JS_free(jp->sprinter.context, fp);
560
+ format = NULL;
561
+ }
562
+ if (!bp) {
563
+ JS_ReportOutOfMemory(jp->sprinter.context);
564
+ return -1;
565
+ }
566
+
567
+ cc = strlen(bp);
568
+ if (SprintPut(&jp->sprinter, bp, (size_t)cc) < 0)
569
+ cc = -1;
570
+ free(bp);
571
+
572
+ va_end(ap);
573
+ return cc;
574
+ }
575
+
576
+ JSBool
577
+ js_puts(JSPrinter *jp, const char *s)
578
+ {
579
+ return SprintPut(&jp->sprinter, s, strlen(s)) >= 0;
580
+ }
581
+
582
+ /************************************************************************/
583
+
584
+ typedef struct SprintStack {
585
+ Sprinter sprinter; /* sprinter for postfix to infix buffering */
586
+ ptrdiff_t *offsets; /* stack of postfix string offsets */
587
+ jsbytecode *opcodes; /* parallel stack of JS opcodes */
588
+ uintN top; /* top of stack index */
589
+ JSPrinter *printer; /* permanent output goes here */
590
+ } SprintStack;
591
+
592
+ /* Gap between stacked strings to allow for insertion of parens and commas. */
593
+ #define PAREN_SLOP (2 + 1)
594
+
595
+ /*
596
+ * These pseudo-ops help js_DecompileValueGenerator decompile JSOP_SETNAME,
597
+ * JSOP_SETPROP, and JSOP_SETELEM, respectively. See the first assertion in
598
+ * PushOff.
599
+ */
600
+ #define JSOP_GETPROP2 254
601
+ #define JSOP_GETELEM2 255
602
+
603
+ static JSBool
604
+ PushOff(SprintStack *ss, ptrdiff_t off, JSOp op)
605
+ {
606
+ uintN top;
607
+
608
+ #if JSOP_LIMIT > JSOP_GETPROP2
609
+ #error JSOP_LIMIT must be <= JSOP_GETPROP2
610
+ #endif
611
+ if (!SprintAlloc(&ss->sprinter, PAREN_SLOP))
612
+ return JS_FALSE;
613
+
614
+ /* ss->top points to the next free slot; be paranoid about overflow. */
615
+ top = ss->top;
616
+ JS_ASSERT(top < ss->printer->script->depth);
617
+ if (top >= ss->printer->script->depth) {
618
+ JS_ReportOutOfMemory(ss->sprinter.context);
619
+ return JS_FALSE;
620
+ }
621
+
622
+ /* The opcodes stack must contain real bytecodes that index js_CodeSpec. */
623
+ ss->offsets[top] = off;
624
+ ss->opcodes[top] = (op == JSOP_GETPROP2) ? JSOP_GETPROP
625
+ : (op == JSOP_GETELEM2) ? JSOP_GETELEM
626
+ : (jsbytecode) op;
627
+ ss->top = ++top;
628
+ ss->sprinter.offset += PAREN_SLOP;
629
+ return JS_TRUE;
630
+ }
631
+
632
+ static ptrdiff_t
633
+ PopOff(SprintStack *ss, JSOp op)
634
+ {
635
+ uintN top;
636
+ const JSCodeSpec *cs, *topcs;
637
+ ptrdiff_t off;
638
+
639
+ /* ss->top points to the next free slot; be paranoid about underflow. */
640
+ top = ss->top;
641
+ JS_ASSERT(top != 0);
642
+ if (top == 0)
643
+ return 0;
644
+
645
+ ss->top = --top;
646
+ topcs = &js_CodeSpec[ss->opcodes[top]];
647
+ cs = &js_CodeSpec[op];
648
+ if (topcs->prec != 0 && topcs->prec < cs->prec) {
649
+ ss->offsets[top] -= 2;
650
+ ss->sprinter.offset = ss->offsets[top];
651
+ off = Sprint(&ss->sprinter, "(%s)",
652
+ OFF2STR(&ss->sprinter, ss->sprinter.offset + 2));
653
+ } else {
654
+ off = ss->sprinter.offset = ss->offsets[top];
655
+ }
656
+ return off;
657
+ }
658
+
659
+ #if JS_HAS_SWITCH_STATEMENT
660
+ typedef struct TableEntry {
661
+ jsval key;
662
+ ptrdiff_t offset;
663
+ JSAtom *label;
664
+ jsint order; /* source order for stable tableswitch sort */
665
+ } TableEntry;
666
+
667
+ static int
668
+ CompareOffsets(const void *v1, const void *v2, void *arg)
669
+ {
670
+ const TableEntry *te1 = (const TableEntry *) v1,
671
+ *te2 = (const TableEntry *) v2;
672
+
673
+ if (te1->offset == te2->offset)
674
+ return (int) (te1->order - te2->order);
675
+ return (int) (te1->offset - te2->offset);
676
+ }
677
+
678
+ static JSBool
679
+ Decompile(SprintStack *ss, jsbytecode *pc, intN nb);
680
+
681
+ static JSBool
682
+ DecompileSwitch(SprintStack *ss, TableEntry *table, uintN tableLength,
683
+ jsbytecode *pc, ptrdiff_t switchLength,
684
+ ptrdiff_t defaultOffset, JSBool isCondSwitch)
685
+ {
686
+ JSContext *cx;
687
+ JSPrinter *jp;
688
+ char *lval, *rval;
689
+ uintN i;
690
+ ptrdiff_t diff, off, off2, caseExprOff;
691
+ jsval key;
692
+ JSString *str;
693
+
694
+ cx = ss->sprinter.context;
695
+ jp = ss->printer;
696
+
697
+ lval = OFF2STR(&ss->sprinter, PopOff(ss, JSOP_NOP));
698
+ js_printf(jp, "\tswitch (%s) {\n", lval);
699
+
700
+ if (tableLength) {
701
+ diff = table[0].offset - defaultOffset;
702
+ if (diff > 0) {
703
+ jp->indent += 2;
704
+ js_printf(jp, "\tdefault:\n");
705
+ jp->indent += 2;
706
+ if (!Decompile(ss, pc + defaultOffset, diff))
707
+ return JS_FALSE;
708
+ jp->indent -= 4;
709
+ }
710
+
711
+ caseExprOff = isCondSwitch
712
+ ? (ptrdiff_t) js_CodeSpec[JSOP_CONDSWITCH].length
713
+ : 0;
714
+
715
+ for (i = 0; i < tableLength; i++) {
716
+ off = table[i].offset;
717
+ off2 = (i + 1 < tableLength) ? table[i + 1].offset : switchLength;
718
+
719
+ key = table[i].key;
720
+ if (isCondSwitch) {
721
+ ptrdiff_t nextCaseExprOff;
722
+
723
+ /*
724
+ * key encodes the JSOP_CASE bytecode's offset from switchtop.
725
+ * The next case expression follows immediately, unless we are
726
+ * at the last case.
727
+ */
728
+ nextCaseExprOff = (ptrdiff_t)JSVAL_TO_INT(key);
729
+ nextCaseExprOff += js_CodeSpec[pc[nextCaseExprOff]].length;
730
+ jp->indent += 2;
731
+ if (!Decompile(ss, pc + caseExprOff,
732
+ nextCaseExprOff - caseExprOff)) {
733
+ return JS_FALSE;
734
+ }
735
+ caseExprOff = nextCaseExprOff;
736
+ } else {
737
+ /*
738
+ * key comes from an atom, not the decompiler, so we need to
739
+ * quote it if it's a string literal. But if table[i].label
740
+ * is non-null, key was constant-propagated and label is the
741
+ * name of the const we should show as the case label. We set
742
+ * key to undefined so this identifier is escaped, if required
743
+ * by non-ASCII characters, but not quoted, by QuoteString.
744
+ */
745
+ if (table[i].label) {
746
+ str = ATOM_TO_STRING(table[i].label);
747
+ key = JSVAL_VOID;
748
+ } else {
749
+ str = js_ValueToString(cx, key);
750
+ if (!str)
751
+ return JS_FALSE;
752
+ }
753
+ rval = QuoteString(&ss->sprinter, str,
754
+ JSVAL_IS_STRING(key) ? (jschar)'"' : 0);
755
+ if (!rval)
756
+ return JS_FALSE;
757
+ RETRACT(&ss->sprinter, rval);
758
+ jp->indent += 2;
759
+ js_printf(jp, "\tcase %s:\n", rval);
760
+ }
761
+
762
+ jp->indent += 2;
763
+ if (off <= defaultOffset && defaultOffset < off2) {
764
+ diff = defaultOffset - off;
765
+ if (diff != 0) {
766
+ if (!Decompile(ss, pc + off, diff))
767
+ return JS_FALSE;
768
+ off = defaultOffset;
769
+ }
770
+ jp->indent -= 2;
771
+ js_printf(jp, "\tdefault:\n");
772
+ jp->indent += 2;
773
+ }
774
+ if (!Decompile(ss, pc + off, off2 - off))
775
+ return JS_FALSE;
776
+ jp->indent -= 4;
777
+ }
778
+ }
779
+
780
+ if (defaultOffset == switchLength) {
781
+ jp->indent += 2;
782
+ js_printf(jp, "\tdefault:;\n");
783
+ jp->indent -= 2;
784
+ }
785
+ js_printf(jp, "\t}\n");
786
+ return JS_TRUE;
787
+ }
788
+ #endif
789
+
790
+ static JSAtom *
791
+ GetSlotAtom(JSPrinter *jp, JSPropertyOp getter, uintN slot)
792
+ {
793
+ JSScope *scope;
794
+ JSScopeProperty *sprop;
795
+ JSObject *obj, *proto;
796
+
797
+ scope = jp->scope;
798
+ while (scope) {
799
+ for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) {
800
+ if (sprop->getter != getter)
801
+ continue;
802
+ JS_ASSERT(sprop->flags & SPROP_HAS_SHORTID);
803
+ JS_ASSERT(!JSVAL_IS_INT(sprop->id));
804
+ if ((uintN) sprop->shortid == slot)
805
+ return (JSAtom *) sprop->id;
806
+ }
807
+ obj = scope->object;
808
+ if (!obj)
809
+ break;
810
+ proto = OBJ_GET_PROTO(jp->sprinter.context, obj);
811
+ if (!proto)
812
+ break;
813
+ scope = OBJ_SCOPE(proto);
814
+ }
815
+ return NULL;
816
+ }
817
+
818
+ static const char *
819
+ VarPrefix(jssrcnote *sn)
820
+ {
821
+ const char *kw;
822
+ static char buf[8];
823
+
824
+ kw = NULL;
825
+ if (sn) {
826
+ if (SN_TYPE(sn) == SRC_VAR)
827
+ kw = js_var_str;
828
+ else if (SN_TYPE(sn) == SRC_CONST)
829
+ kw = js_const_str;
830
+ }
831
+ if (!kw)
832
+ return "";
833
+ JS_snprintf(buf, sizeof buf, "%s ", kw);
834
+ return buf;
835
+ }
836
+
837
+ static JSBool
838
+ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
839
+ {
840
+ JSContext *cx;
841
+ JSPrinter *jp, *jp2;
842
+ jsbytecode *endpc, *done, *forelem_tail, *forelem_done;
843
+ ptrdiff_t tail, todo, len, oplen, cond, next;
844
+ JSOp op, lastop, saveop;
845
+ const JSCodeSpec *cs, *topcs;
846
+ jssrcnote *sn, *sn2;
847
+ const char *lval, *rval, *xval, *fmt;
848
+ jsint i, argc;
849
+ char **argv;
850
+ JSAtom *atom;
851
+ JSObject *obj;
852
+ JSFunction *fun;
853
+ JSString *str;
854
+ JSBool ok;
855
+ jsval val;
856
+ static const char catch_cookie[] = "/*CATCH*/";
857
+ static const char with_cookie[] = "/*WITH*/";
858
+
859
+ /*
860
+ * Local macros
861
+ */
862
+ #define DECOMPILE_CODE(pc,nb) if (!Decompile(ss, pc, nb)) return JS_FALSE
863
+ #define POP_STR() OFF2STR(&ss->sprinter, PopOff(ss, op))
864
+ #define LOCAL_ASSERT(expr) JS_ASSERT(expr); if (!(expr)) return JS_FALSE
865
+
866
+ /*
867
+ * Callers know that ATOM_IS_STRING(atom), and we leave it to the optimizer to
868
+ * common ATOM_TO_STRING(atom) here and near the call sites.
869
+ */
870
+ #define ATOM_IS_IDENTIFIER(atom) \
871
+ (!ATOM_KEYWORD(atom) && js_IsIdentifier(ATOM_TO_STRING(atom)))
872
+
873
+ /*
874
+ * Get atom from script's atom map, quote/escape its string appropriately into
875
+ * rval, and select fmt from the quoted and unquoted alternatives.
876
+ */
877
+ #define GET_ATOM_QUOTE_AND_FMT(qfmt, ufmt, rval) \
878
+ JS_BEGIN_MACRO \
879
+ jschar quote_; \
880
+ atom = GET_ATOM(cx, jp->script, pc); \
881
+ if (!ATOM_IS_IDENTIFIER(atom)) { \
882
+ quote_ = '\''; \
883
+ fmt = qfmt; \
884
+ } else { \
885
+ quote_ = 0; \
886
+ fmt = ufmt; \
887
+ } \
888
+ rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), quote_); \
889
+ if (!rval) \
890
+ return JS_FALSE; \
891
+ JS_END_MACRO
892
+
893
+ cx = ss->sprinter.context;
894
+ jp = ss->printer;
895
+ endpc = pc + nb;
896
+ forelem_tail = forelem_done = NULL;
897
+ tail = -1;
898
+ todo = -2; /* NB: different from Sprint() error return. */
899
+ op = JSOP_NOP;
900
+ sn = NULL;
901
+ rval = NULL;
902
+
903
+ while (pc < endpc) {
904
+ lastop = op;
905
+ op = saveop = (JSOp) *pc;
906
+ if (op >= JSOP_LIMIT) {
907
+ switch (op) {
908
+ case JSOP_GETPROP2:
909
+ saveop = JSOP_GETPROP;
910
+ break;
911
+ case JSOP_GETELEM2:
912
+ saveop = JSOP_GETELEM;
913
+ break;
914
+ default:;
915
+ }
916
+ }
917
+ cs = &js_CodeSpec[saveop];
918
+ len = oplen = cs->length;
919
+
920
+ if (cs->token) {
921
+ switch (cs->nuses) {
922
+ case 2:
923
+ rval = POP_STR();
924
+ lval = POP_STR();
925
+ sn = js_GetSrcNote(jp->script, pc);
926
+ if (sn && SN_TYPE(sn) == SRC_ASSIGNOP) {
927
+ /* Print only the right operand of the assignment-op. */
928
+ todo = SprintPut(&ss->sprinter, rval, strlen(rval));
929
+ } else {
930
+ todo = Sprint(&ss->sprinter, "%s %s %s",
931
+ lval, cs->token, rval);
932
+ }
933
+ break;
934
+
935
+ case 1:
936
+ rval = POP_STR();
937
+ todo = Sprint(&ss->sprinter, "%s%s", cs->token, rval);
938
+ break;
939
+
940
+ case 0:
941
+ #if JS_HAS_GETTER_SETTER
942
+ if (op == JSOP_GETTER || op == JSOP_SETTER) {
943
+ todo = -2;
944
+ break;
945
+ }
946
+ #endif
947
+ todo = SprintPut(&ss->sprinter, cs->token, strlen(cs->token));
948
+ break;
949
+
950
+ default:
951
+ todo = -2;
952
+ break;
953
+ }
954
+ } else {
955
+ switch (op) {
956
+ case JSOP_NOP:
957
+ /*
958
+ * Check for a do-while loop, a for-loop with an empty
959
+ * initializer part, a labeled statement, a function
960
+ * definition, or try/finally.
961
+ */
962
+ sn = js_GetSrcNote(jp->script, pc);
963
+ todo = -2;
964
+ switch (sn ? SN_TYPE(sn) : SRC_NULL) {
965
+ #if JS_HAS_DO_WHILE_LOOP
966
+ case SRC_WHILE:
967
+ js_printf(jp, "\tdo {\n");
968
+ jp->indent += 4;
969
+ break;
970
+ #endif /* JS_HAS_DO_WHILE_LOOP */
971
+
972
+ case SRC_FOR:
973
+ rval = "";
974
+
975
+ do_forloop:
976
+ /* Skip the JSOP_NOP or JSOP_POP bytecode. */
977
+ pc++;
978
+
979
+ /* Get the cond, next, and loop-closing tail offsets. */
980
+ cond = js_GetSrcNoteOffset(sn, 0);
981
+ next = js_GetSrcNoteOffset(sn, 1);
982
+ tail = js_GetSrcNoteOffset(sn, 2);
983
+ LOCAL_ASSERT(tail + GetJumpOffset(pc+tail, pc+tail) == 0);
984
+
985
+ /* Print the keyword and the possibly empty init-part. */
986
+ js_printf(jp, "\tfor (%s;", rval);
987
+
988
+ if (pc[cond] == JSOP_IFEQ || pc[cond] == JSOP_IFEQX) {
989
+ /* Decompile the loop condition. */
990
+ DECOMPILE_CODE(pc, cond);
991
+ js_printf(jp, " %s", POP_STR());
992
+ }
993
+
994
+ /* Need a semicolon whether or not there was a cond. */
995
+ js_puts(jp, ";");
996
+
997
+ if (pc[next] != JSOP_GOTO && pc[next] != JSOP_GOTOX) {
998
+ /* Decompile the loop updater. */
999
+ DECOMPILE_CODE(pc + next, tail - next - 1);
1000
+ js_printf(jp, " %s", POP_STR());
1001
+ }
1002
+
1003
+ /* Do the loop body. */
1004
+ js_printf(jp, ") {\n");
1005
+ jp->indent += 4;
1006
+ oplen = (cond) ? js_CodeSpec[pc[cond]].length : 0;
1007
+ DECOMPILE_CODE(pc + cond + oplen, next - cond - oplen);
1008
+ jp->indent -= 4;
1009
+ js_printf(jp, "\t}\n");
1010
+
1011
+ /* Set len so pc skips over the entire loop. */
1012
+ len = tail + js_CodeSpec[pc[tail]].length;
1013
+ break;
1014
+
1015
+ case SRC_LABEL:
1016
+ atom = js_GetAtom(cx, &jp->script->atomMap,
1017
+ (jsatomid) js_GetSrcNoteOffset(sn, 0));
1018
+ jp->indent -= 4;
1019
+ rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
1020
+ if (!rval)
1021
+ return JS_FALSE;
1022
+ RETRACT(&ss->sprinter, rval);
1023
+ js_printf(jp, "\t%s:\n", rval);
1024
+ jp->indent += 4;
1025
+ break;
1026
+
1027
+ case SRC_LABELBRACE:
1028
+ atom = js_GetAtom(cx, &jp->script->atomMap,
1029
+ (jsatomid) js_GetSrcNoteOffset(sn, 0));
1030
+ rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
1031
+ if (!rval)
1032
+ return JS_FALSE;
1033
+ RETRACT(&ss->sprinter, rval);
1034
+ js_printf(jp, "\t%s: {\n", rval);
1035
+ jp->indent += 4;
1036
+ break;
1037
+
1038
+ case SRC_ENDBRACE:
1039
+ jp->indent -= 4;
1040
+ js_printf(jp, "\t}\n");
1041
+ break;
1042
+
1043
+ case SRC_CATCH:
1044
+ jp->indent -= 4;
1045
+ sn = js_GetSrcNote(jp->script, pc);
1046
+ pc += oplen;
1047
+ js_printf(jp, "\t} catch (");
1048
+
1049
+ LOCAL_ASSERT(*pc == JSOP_NAME);
1050
+ pc += js_CodeSpec[JSOP_NAME].length;
1051
+ LOCAL_ASSERT(*pc == JSOP_PUSHOBJ);
1052
+ pc += js_CodeSpec[JSOP_PUSHOBJ].length;
1053
+ LOCAL_ASSERT(*pc == JSOP_NEWINIT);
1054
+ pc += js_CodeSpec[JSOP_NEWINIT].length;
1055
+ LOCAL_ASSERT(*pc == JSOP_EXCEPTION);
1056
+ pc += js_CodeSpec[JSOP_EXCEPTION].length;
1057
+ LOCAL_ASSERT(*pc == JSOP_INITCATCHVAR);
1058
+ atom = GET_ATOM(cx, jp->script, pc);
1059
+ rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
1060
+ if (!rval)
1061
+ return JS_FALSE;
1062
+ RETRACT(&ss->sprinter, rval);
1063
+ js_printf(jp, "%s", rval);
1064
+ pc += js_CodeSpec[JSOP_INITCATCHVAR].length;
1065
+ LOCAL_ASSERT(*pc == JSOP_ENTERWITH);
1066
+ pc += js_CodeSpec[JSOP_ENTERWITH].length;
1067
+
1068
+ len = js_GetSrcNoteOffset(sn, 0);
1069
+ if (len) {
1070
+ js_printf(jp, " if ");
1071
+ DECOMPILE_CODE(pc, len);
1072
+ js_printf(jp, "%s", POP_STR());
1073
+ pc += len;
1074
+ LOCAL_ASSERT(*pc == JSOP_IFEQ || *pc == JSOP_IFEQX);
1075
+ pc += js_CodeSpec[*pc].length;
1076
+ }
1077
+
1078
+ js_printf(jp, ") {\n");
1079
+ jp->indent += 4;
1080
+ todo = Sprint(&ss->sprinter, catch_cookie);
1081
+ len = 0;
1082
+ break;
1083
+
1084
+ case SRC_FUNCDEF:
1085
+ atom = js_GetAtom(cx, &jp->script->atomMap,
1086
+ (jsatomid) js_GetSrcNoteOffset(sn, 0));
1087
+ JS_ASSERT(ATOM_IS_OBJECT(atom));
1088
+ do_function:
1089
+ obj = ATOM_TO_OBJECT(atom);
1090
+ fun = (JSFunction *) JS_GetPrivate(cx, obj);
1091
+ jp2 = js_NewPrinter(cx, JS_GetFunctionName(fun),
1092
+ jp->indent, jp->pretty);
1093
+ if (!jp2)
1094
+ return JS_FALSE;
1095
+ jp2->scope = jp->scope;
1096
+ if (js_DecompileFunction(jp2, fun)) {
1097
+ str = js_GetPrinterOutput(jp2);
1098
+ if (str)
1099
+ js_printf(jp, "%s\n", JS_GetStringBytes(str));
1100
+ }
1101
+ js_DestroyPrinter(jp2);
1102
+ break;
1103
+
1104
+ default:;
1105
+ }
1106
+ case JSOP_RETRVAL:
1107
+ break;
1108
+
1109
+ case JSOP_GROUP:
1110
+ /* Use last real op so PopOff adds parens if needed. */
1111
+ todo = PopOff(ss, lastop);
1112
+
1113
+ /* Now add user-supplied parens only if PopOff did not. */
1114
+ cs = &js_CodeSpec[lastop];
1115
+ topcs = &js_CodeSpec[ss->opcodes[ss->top]];
1116
+ if (topcs->prec >= cs->prec) {
1117
+ todo = Sprint(&ss->sprinter, "(%s)",
1118
+ OFF2STR(&ss->sprinter, todo));
1119
+ }
1120
+ break;
1121
+
1122
+ case JSOP_PUSH:
1123
+ case JSOP_PUSHOBJ:
1124
+ case JSOP_BINDNAME:
1125
+ todo = Sprint(&ss->sprinter, "");
1126
+ break;
1127
+
1128
+ #if JS_HAS_EXCEPTIONS
1129
+ case JSOP_TRY:
1130
+ js_printf(jp, "\ttry {\n");
1131
+ jp->indent += 4;
1132
+ todo = -2;
1133
+ break;
1134
+
1135
+ {
1136
+ static const char finally_cookie[] = "/*FINALLY*/";
1137
+
1138
+ case JSOP_FINALLY:
1139
+ jp->indent -= 4;
1140
+ js_printf(jp, "\t} finally {\n");
1141
+ jp->indent += 4;
1142
+
1143
+ /*
1144
+ * We must push an empty string placeholder for gosub's return
1145
+ * address, popped by JSOP_RETSUB and counted by script->depth
1146
+ * but not by ss->top (see JSOP_SETSP, below).
1147
+ */
1148
+ todo = Sprint(&ss->sprinter, finally_cookie);
1149
+ break;
1150
+
1151
+ case JSOP_RETSUB:
1152
+ rval = POP_STR();
1153
+ LOCAL_ASSERT(strcmp(rval, finally_cookie) == 0);
1154
+ todo = -2;
1155
+ break;
1156
+ }
1157
+
1158
+ case JSOP_SWAP:
1159
+ /*
1160
+ * We don't generate this opcode currently, and previously we
1161
+ * did not need to decompile it. If old, serialized bytecode
1162
+ * uses it still, we should fall through and set todo = -2.
1163
+ */
1164
+ /* FALL THROUGH */
1165
+
1166
+ case JSOP_GOSUB:
1167
+ case JSOP_GOSUBX:
1168
+ /*
1169
+ * JSOP_GOSUB and GOSUBX have no effect on the decompiler's
1170
+ * string stack because the next op in bytecode order finds
1171
+ * the stack balanced by a JSOP_RETSUB executed elsewhere.
1172
+ */
1173
+ todo = -2;
1174
+ break;
1175
+
1176
+ case JSOP_SETSP:
1177
+ /*
1178
+ * The compiler models operand stack depth and fixes the stack
1179
+ * pointer on entry to a catch clause based on its depth model.
1180
+ * The decompiler must match the code generator's model, which
1181
+ * is why JSOP_FINALLY pushes a cookie that JSOP_RETSUB pops.
1182
+ */
1183
+ LOCAL_ASSERT(ss->top >= (uintN) GET_ATOM_INDEX(pc));
1184
+ ss->top = (uintN) GET_ATOM_INDEX(pc);
1185
+ break;
1186
+
1187
+ case JSOP_EXCEPTION:
1188
+ /*
1189
+ * The only other JSOP_EXCEPTION case occurs as part of a code
1190
+ * sequence that follows a SRC_CATCH-annotated JSOP_NOP.
1191
+ */
1192
+ sn = js_GetSrcNote(jp->script, pc);
1193
+ LOCAL_ASSERT(sn && SN_TYPE(sn) == SRC_HIDDEN);
1194
+ todo = -2;
1195
+ break;
1196
+ #endif /* JS_HAS_EXCEPTIONS */
1197
+
1198
+ case JSOP_POP:
1199
+ case JSOP_POPV:
1200
+ sn = js_GetSrcNote(jp->script, pc);
1201
+ switch (sn ? SN_TYPE(sn) : SRC_NULL) {
1202
+ case SRC_FOR:
1203
+ rval = POP_STR();
1204
+ todo = -2;
1205
+ goto do_forloop;
1206
+
1207
+ case SRC_PCDELTA:
1208
+ /* Pop and save to avoid blowing stack depth budget. */
1209
+ lval = JS_strdup(cx, POP_STR());
1210
+ if (!lval)
1211
+ return JS_FALSE;
1212
+
1213
+ /*
1214
+ * The offset tells distance to the end of the right-hand
1215
+ * operand of the comma operator.
1216
+ */
1217
+ done = pc + len;
1218
+ pc += js_GetSrcNoteOffset(sn, 0);
1219
+ len = 0;
1220
+
1221
+ if (!Decompile(ss, done, pc - done)) {
1222
+ JS_free(cx, (char *)lval);
1223
+ return JS_FALSE;
1224
+ }
1225
+
1226
+ /* Pop Decompile result and print comma expression. */
1227
+ rval = POP_STR();
1228
+ todo = Sprint(&ss->sprinter, "%s, %s", lval, rval);
1229
+ JS_free(cx, (char *)lval);
1230
+ break;
1231
+
1232
+ case SRC_HIDDEN:
1233
+ /* Hide this pop, it's from a goto in a with or for/in. */
1234
+ todo = -2;
1235
+ break;
1236
+
1237
+ default:
1238
+ rval = POP_STR();
1239
+ if (*rval != '\0')
1240
+ js_printf(jp, "\t%s;\n", rval);
1241
+ todo = -2;
1242
+ break;
1243
+ }
1244
+ break;
1245
+
1246
+ case JSOP_POP2:
1247
+ (void) PopOff(ss, op);
1248
+ (void) PopOff(ss, op);
1249
+ todo = -2;
1250
+ break;
1251
+
1252
+ case JSOP_ENTERWITH:
1253
+ JS_ASSERT(!js_GetSrcNote(jp->script, pc));
1254
+ rval = POP_STR();
1255
+ js_printf(jp, "\twith (%s) {\n", rval);
1256
+ jp->indent += 4;
1257
+ todo = Sprint(&ss->sprinter, with_cookie);
1258
+ break;
1259
+
1260
+ case JSOP_LEAVEWITH:
1261
+ sn = js_GetSrcNote(jp->script, pc);
1262
+ todo = -2;
1263
+ if (sn && SN_TYPE(sn) == SRC_HIDDEN)
1264
+ break;
1265
+ rval = POP_STR();
1266
+ if (sn && SN_TYPE(sn) == SRC_CATCH) {
1267
+ LOCAL_ASSERT(strcmp(rval, catch_cookie) == 0);
1268
+ LOCAL_ASSERT((uintN) js_GetSrcNoteOffset(sn, 0) == ss->top);
1269
+ break;
1270
+ }
1271
+ LOCAL_ASSERT(strcmp(rval, with_cookie) == 0);
1272
+ jp->indent -= 4;
1273
+ js_printf(jp, "\t}\n");
1274
+ break;
1275
+
1276
+ case JSOP_SETRVAL:
1277
+ case JSOP_RETURN:
1278
+ lval = js_CodeSpec[JSOP_RETURN].name;
1279
+ rval = POP_STR();
1280
+ if (*rval != '\0')
1281
+ js_printf(jp, "\t%s %s;\n", lval, rval);
1282
+ else
1283
+ js_printf(jp, "\t%s;\n", lval);
1284
+ todo = -2;
1285
+ break;
1286
+
1287
+ #if JS_HAS_EXCEPTIONS
1288
+ case JSOP_THROW:
1289
+ sn = js_GetSrcNote(jp->script, pc);
1290
+ todo = -2;
1291
+ if (sn && SN_TYPE(sn) == SRC_HIDDEN)
1292
+ break;
1293
+ rval = POP_STR();
1294
+ js_printf(jp, "\t%s %s;\n", cs->name, rval);
1295
+ break;
1296
+ #endif /* JS_HAS_EXCEPTIONS */
1297
+
1298
+ case JSOP_GOTO:
1299
+ case JSOP_GOTOX:
1300
+ sn = js_GetSrcNote(jp->script, pc);
1301
+ switch (sn ? SN_TYPE(sn) : SRC_NULL) {
1302
+ case SRC_CONT2LABEL:
1303
+ atom = js_GetAtom(cx, &jp->script->atomMap,
1304
+ (jsatomid) js_GetSrcNoteOffset(sn, 0));
1305
+ rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
1306
+ if (!rval)
1307
+ return JS_FALSE;
1308
+ RETRACT(&ss->sprinter, rval);
1309
+ js_printf(jp, "\tcontinue %s;\n", rval);
1310
+ break;
1311
+ case SRC_CONTINUE:
1312
+ js_printf(jp, "\tcontinue;\n");
1313
+ break;
1314
+ case SRC_BREAK2LABEL:
1315
+ atom = js_GetAtom(cx, &jp->script->atomMap,
1316
+ (jsatomid) js_GetSrcNoteOffset(sn, 0));
1317
+ rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
1318
+ if (!rval)
1319
+ return JS_FALSE;
1320
+ RETRACT(&ss->sprinter, rval);
1321
+ js_printf(jp, "\tbreak %s;\n", rval);
1322
+ break;
1323
+ case SRC_HIDDEN:
1324
+ break;
1325
+ default:
1326
+ js_printf(jp, "\tbreak;\n");
1327
+ break;
1328
+ }
1329
+ todo = -2;
1330
+ break;
1331
+
1332
+ case JSOP_IFEQ:
1333
+ case JSOP_IFEQX:
1334
+ len = GetJumpOffset(pc, pc);
1335
+ sn = js_GetSrcNote(jp->script, pc);
1336
+
1337
+ switch (sn ? SN_TYPE(sn) : SRC_NULL) {
1338
+ case SRC_IF:
1339
+ case SRC_IF_ELSE:
1340
+ rval = POP_STR();
1341
+ js_printf(jp, "\tif (%s) {\n", rval);
1342
+ jp->indent += 4;
1343
+ if (SN_TYPE(sn) == SRC_IF) {
1344
+ DECOMPILE_CODE(pc + oplen, len - oplen);
1345
+ } else {
1346
+ len = js_GetSrcNoteOffset(sn, 0);
1347
+ DECOMPILE_CODE(pc + oplen, len - oplen);
1348
+ jp->indent -= 4;
1349
+ pc += len;
1350
+ LOCAL_ASSERT(*pc == JSOP_GOTO || *pc == JSOP_GOTOX);
1351
+ oplen = js_CodeSpec[*pc].length;
1352
+ len = GetJumpOffset(pc, pc);
1353
+ js_printf(jp, "\t} else {\n");
1354
+ jp->indent += 4;
1355
+ DECOMPILE_CODE(pc + oplen, len - oplen);
1356
+ }
1357
+ jp->indent -= 4;
1358
+ js_printf(jp, "\t}\n");
1359
+ todo = -2;
1360
+ break;
1361
+
1362
+ case SRC_WHILE:
1363
+ rval = POP_STR();
1364
+ js_printf(jp, "\twhile (%s) {\n", rval);
1365
+ jp->indent += 4;
1366
+ tail = js_GetSrcNoteOffset(sn, 0);
1367
+ DECOMPILE_CODE(pc + oplen, tail - oplen);
1368
+ jp->indent -= 4;
1369
+ js_printf(jp, "\t}\n");
1370
+ todo = -2;
1371
+ break;
1372
+
1373
+ case SRC_COND:
1374
+ xval = JS_strdup(cx, POP_STR());
1375
+ if (!xval)
1376
+ return JS_FALSE;
1377
+ len = js_GetSrcNoteOffset(sn, 0);
1378
+ DECOMPILE_CODE(pc + oplen, len - oplen);
1379
+ lval = JS_strdup(cx, POP_STR());
1380
+ if (!lval) {
1381
+ JS_free(cx, (void *)xval);
1382
+ return JS_FALSE;
1383
+ }
1384
+ pc += len;
1385
+ LOCAL_ASSERT(*pc == JSOP_GOTO || *pc == JSOP_GOTOX);
1386
+ oplen = js_CodeSpec[*pc].length;
1387
+ len = GetJumpOffset(pc, pc);
1388
+ DECOMPILE_CODE(pc + oplen, len - oplen);
1389
+ rval = POP_STR();
1390
+ todo = Sprint(&ss->sprinter, "%s ? %s : %s",
1391
+ xval, lval, rval);
1392
+ JS_free(cx, (void *)xval);
1393
+ JS_free(cx, (void *)lval);
1394
+ break;
1395
+
1396
+ default:
1397
+ break;
1398
+ }
1399
+ break;
1400
+
1401
+ case JSOP_IFNE:
1402
+ case JSOP_IFNEX:
1403
+ #if JS_HAS_DO_WHILE_LOOP
1404
+ /* Currently, this must be a do-while loop's upward branch. */
1405
+ jp->indent -= 4;
1406
+ js_printf(jp, "\t} while (%s);\n", POP_STR());
1407
+ todo = -2;
1408
+ #else
1409
+ JS_ASSERT(0);
1410
+ #endif /* JS_HAS_DO_WHILE_LOOP */
1411
+ break;
1412
+
1413
+ case JSOP_OR:
1414
+ case JSOP_ORX:
1415
+ xval = "||";
1416
+
1417
+ do_logical_connective:
1418
+ /* Top of stack is the first clause in a disjunction (||). */
1419
+ lval = JS_strdup(cx, POP_STR());
1420
+ if (!lval)
1421
+ return JS_FALSE;
1422
+ done = pc + GetJumpOffset(pc, pc);
1423
+ pc += len;
1424
+ len = PTRDIFF(done, pc, jsbytecode);
1425
+ DECOMPILE_CODE(pc, len);
1426
+ rval = POP_STR();
1427
+ if (jp->pretty &&
1428
+ jp->indent + 4 + strlen(lval) + 4 + strlen(rval) > 75) {
1429
+ rval = JS_strdup(cx, rval);
1430
+ if (!rval) {
1431
+ tail = -1;
1432
+ } else {
1433
+ todo = Sprint(&ss->sprinter, "%s %s\n", lval, xval);
1434
+ tail = Sprint(&ss->sprinter, "%*s%s",
1435
+ jp->indent + 4, "", rval);
1436
+ JS_free(cx, (char *)rval);
1437
+ }
1438
+ if (tail < 0)
1439
+ todo = -1;
1440
+ } else {
1441
+ todo = Sprint(&ss->sprinter, "%s %s %s", lval, xval, rval);
1442
+ }
1443
+ JS_free(cx, (char *)lval);
1444
+ break;
1445
+
1446
+ case JSOP_AND:
1447
+ case JSOP_ANDX:
1448
+ xval = "&&";
1449
+ goto do_logical_connective;
1450
+
1451
+ case JSOP_FORARG:
1452
+ atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc));
1453
+ LOCAL_ASSERT(atom);
1454
+ goto do_fornameinloop;
1455
+
1456
+ case JSOP_FORVAR:
1457
+ atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc));
1458
+ LOCAL_ASSERT(atom);
1459
+ goto do_fornameinloop;
1460
+
1461
+ case JSOP_FORNAME:
1462
+ atom = GET_ATOM(cx, jp->script, pc);
1463
+
1464
+ do_fornameinloop:
1465
+ sn = js_GetSrcNote(jp->script, pc);
1466
+ xval = NULL;
1467
+ lval = "";
1468
+ goto do_forinloop;
1469
+
1470
+ case JSOP_FORPROP:
1471
+ xval = NULL;
1472
+ atom = GET_ATOM(cx, jp->script, pc);
1473
+ if (!ATOM_IS_IDENTIFIER(atom)) {
1474
+ xval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom),
1475
+ (jschar)'\'');
1476
+ if (!xval)
1477
+ return JS_FALSE;
1478
+ atom = NULL;
1479
+ }
1480
+ lval = POP_STR();
1481
+ sn = NULL;
1482
+
1483
+ do_forinloop:
1484
+ pc += oplen;
1485
+ LOCAL_ASSERT(*pc == JSOP_IFEQ || *pc == JSOP_IFEQX);
1486
+ oplen = js_CodeSpec[*pc].length;
1487
+ len = GetJumpOffset(pc, pc);
1488
+ sn2 = js_GetSrcNote(jp->script, pc);
1489
+ tail = js_GetSrcNoteOffset(sn2, 0);
1490
+
1491
+ do_forinbody:
1492
+ js_printf(jp, "\tfor (%s%s", VarPrefix(sn), lval);
1493
+ if (atom) {
1494
+ xval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
1495
+ if (!xval)
1496
+ return JS_FALSE;
1497
+ RETRACT(&ss->sprinter, xval);
1498
+ js_printf(jp, *lval ? ".%s" : "%s", xval);
1499
+ } else if (xval) {
1500
+ js_printf(jp, "[%s]", xval);
1501
+ }
1502
+ rval = OFF2STR(&ss->sprinter, ss->offsets[ss->top-1]);
1503
+ js_printf(jp, " in %s) {\n", rval);
1504
+ jp->indent += 4;
1505
+ DECOMPILE_CODE(pc + oplen, tail - oplen);
1506
+ jp->indent -= 4;
1507
+ js_printf(jp, "\t}\n");
1508
+ todo = -2;
1509
+ break;
1510
+
1511
+ case JSOP_FORELEM:
1512
+ pc++;
1513
+ LOCAL_ASSERT(*pc == JSOP_IFEQ || *pc == JSOP_IFEQX);
1514
+ len = js_CodeSpec[*pc].length;
1515
+
1516
+ /*
1517
+ * Arrange for the JSOP_ENUMELEM case to set tail for use by
1518
+ * do_forinbody: code that uses on it to find the loop-closing
1519
+ * jump (whatever its format, normal or extended), in order to
1520
+ * bound the recursively decompiled loop body.
1521
+ */
1522
+ sn = js_GetSrcNote(jp->script, pc);
1523
+ JS_ASSERT(!forelem_tail);
1524
+ forelem_tail = pc + js_GetSrcNoteOffset(sn, 0);
1525
+
1526
+ /*
1527
+ * This gets a little wacky. Only the length of the for loop
1528
+ * body PLUS the element-indexing expression is known here, so
1529
+ * we pass the after-loop pc to the JSOP_ENUMELEM case, which
1530
+ * is immediately below, to decompile that helper bytecode via
1531
+ * the 'forelem_done' local.
1532
+ *
1533
+ * Since a for..in loop can't nest in the head of another for
1534
+ * loop, we can use forelem_{tail,done} singletons to remember
1535
+ * state from JSOP_FORELEM to JSOP_ENUMELEM, thence (via goto)
1536
+ * to label do_forinbody.
1537
+ */
1538
+ JS_ASSERT(!forelem_done);
1539
+ forelem_done = pc + GetJumpOffset(pc, pc);
1540
+ break;
1541
+
1542
+ case JSOP_ENUMELEM:
1543
+ /*
1544
+ * The stack has the object under the (top) index expression.
1545
+ * The "rval" property id is underneath those two on the stack.
1546
+ * The for loop body net and gross lengths can now be adjusted
1547
+ * to account for the length of the indexing expression that
1548
+ * came after JSOP_FORELEM and before JSOP_ENUMELEM.
1549
+ */
1550
+ atom = NULL;
1551
+ xval = POP_STR();
1552
+ lval = POP_STR();
1553
+ rval = OFF2STR(&ss->sprinter, ss->offsets[ss->top-1]);
1554
+ JS_ASSERT(forelem_tail > pc);
1555
+ tail = forelem_tail - pc;
1556
+ forelem_tail = NULL;
1557
+ JS_ASSERT(forelem_done > pc);
1558
+ len = forelem_done - pc;
1559
+ forelem_done = NULL;
1560
+ goto do_forinbody;
1561
+
1562
+ case JSOP_DUP2:
1563
+ rval = OFF2STR(&ss->sprinter, ss->offsets[ss->top-2]);
1564
+ todo = SprintPut(&ss->sprinter, rval, strlen(rval));
1565
+ if (todo < 0 || !PushOff(ss, todo, ss->opcodes[ss->top-2]))
1566
+ return JS_FALSE;
1567
+ /* FALL THROUGH */
1568
+
1569
+ case JSOP_DUP:
1570
+ rval = OFF2STR(&ss->sprinter, ss->offsets[ss->top-1]);
1571
+ op = ss->opcodes[ss->top-1];
1572
+ todo = SprintPut(&ss->sprinter, rval, strlen(rval));
1573
+ break;
1574
+
1575
+ case JSOP_SETARG:
1576
+ atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc));
1577
+ LOCAL_ASSERT(atom);
1578
+ goto do_setname;
1579
+
1580
+ case JSOP_SETVAR:
1581
+ atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc));
1582
+ LOCAL_ASSERT(atom);
1583
+ goto do_setname;
1584
+
1585
+ case JSOP_SETCONST:
1586
+ case JSOP_SETNAME:
1587
+ case JSOP_SETGVAR:
1588
+ atom = GET_ATOM(cx, jp->script, pc);
1589
+ do_setname:
1590
+ lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
1591
+ if (!lval)
1592
+ return JS_FALSE;
1593
+ rval = POP_STR();
1594
+ if (op == JSOP_SETNAME)
1595
+ (void) PopOff(ss, op);
1596
+ do_setlval:
1597
+ sn = js_GetSrcNote(jp->script, pc - 1);
1598
+ if (sn && SN_TYPE(sn) == SRC_ASSIGNOP) {
1599
+ todo = Sprint(&ss->sprinter, "%s %s= %s",
1600
+ lval, js_CodeSpec[lastop].token, rval);
1601
+ } else {
1602
+ sn = js_GetSrcNote(jp->script, pc);
1603
+ todo = Sprint(&ss->sprinter, "%s%s = %s",
1604
+ VarPrefix(sn), lval, rval);
1605
+ }
1606
+ break;
1607
+
1608
+ case JSOP_NEW:
1609
+ case JSOP_CALL:
1610
+ case JSOP_EVAL:
1611
+ #if JS_HAS_LVALUE_RETURN
1612
+ case JSOP_SETCALL:
1613
+ #endif
1614
+ saveop = op;
1615
+ op = JSOP_NOP; /* turn off parens */
1616
+ argc = GET_ARGC(pc);
1617
+ argv = (char **)
1618
+ JS_malloc(cx, (size_t)(argc + 1) * sizeof *argv);
1619
+ if (!argv)
1620
+ return JS_FALSE;
1621
+
1622
+ ok = JS_TRUE;
1623
+ for (i = argc; i > 0; i--) {
1624
+ argv[i] = JS_strdup(cx, POP_STR());
1625
+ if (!argv[i]) {
1626
+ ok = JS_FALSE;
1627
+ break;
1628
+ }
1629
+ }
1630
+
1631
+ /* Skip the JSOP_PUSHOBJ-created empty string. */
1632
+ LOCAL_ASSERT(ss->top >= 2);
1633
+ (void) PopOff(ss, op);
1634
+
1635
+ /* Get the callee's decompiled image in argv[0]. */
1636
+ argv[0] = JS_strdup(cx, POP_STR());
1637
+ if (!argv[i])
1638
+ ok = JS_FALSE;
1639
+
1640
+ lval = "(", rval = ")";
1641
+ if (saveop == JSOP_NEW) {
1642
+ todo = Sprint(&ss->sprinter, "%s %s%s",
1643
+ js_new_str, argv[0], lval);
1644
+ } else {
1645
+ todo = Sprint(&ss->sprinter, "%s%s",
1646
+ argv[0], lval);
1647
+ }
1648
+ if (todo < 0)
1649
+ ok = JS_FALSE;
1650
+
1651
+ for (i = 1; i <= argc; i++) {
1652
+ if (!argv[i] ||
1653
+ Sprint(&ss->sprinter, "%s%s",
1654
+ argv[i], (i < argc) ? ", " : "") < 0) {
1655
+ ok = JS_FALSE;
1656
+ break;
1657
+ }
1658
+ }
1659
+ if (Sprint(&ss->sprinter, rval) < 0)
1660
+ ok = JS_FALSE;
1661
+
1662
+ for (i = 0; i <= argc; i++) {
1663
+ if (argv[i])
1664
+ JS_free(cx, argv[i]);
1665
+ }
1666
+ JS_free(cx, argv);
1667
+ if (!ok)
1668
+ return JS_FALSE;
1669
+ op = saveop;
1670
+ #if JS_HAS_LVALUE_RETURN
1671
+ if (op == JSOP_SETCALL) {
1672
+ if (!PushOff(ss, todo, op))
1673
+ return JS_FALSE;
1674
+ todo = Sprint(&ss->sprinter, "");
1675
+ }
1676
+ #endif
1677
+ break;
1678
+
1679
+ case JSOP_DELNAME:
1680
+ atom = GET_ATOM(cx, jp->script, pc);
1681
+ lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
1682
+ if (!lval)
1683
+ return JS_FALSE;
1684
+ RETRACT(&ss->sprinter, lval);
1685
+ todo = Sprint(&ss->sprinter, "%s %s", js_delete_str, lval);
1686
+ break;
1687
+
1688
+ case JSOP_DELPROP:
1689
+ GET_ATOM_QUOTE_AND_FMT("%s %s[%s]", "%s %s.%s", rval);
1690
+ lval = POP_STR();
1691
+ todo = Sprint(&ss->sprinter, fmt, js_delete_str, lval, rval);
1692
+ break;
1693
+
1694
+ case JSOP_DELELEM:
1695
+ xval = POP_STR();
1696
+ lval = POP_STR();
1697
+ todo = Sprint(&ss->sprinter, "%s %s[%s]",
1698
+ js_delete_str, lval, xval);
1699
+ break;
1700
+
1701
+ case JSOP_TYPEOF:
1702
+ case JSOP_VOID:
1703
+ rval = POP_STR();
1704
+ todo = Sprint(&ss->sprinter, "%s %s", cs->name, rval);
1705
+ break;
1706
+
1707
+ case JSOP_INCARG:
1708
+ case JSOP_DECARG:
1709
+ atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc));
1710
+ LOCAL_ASSERT(atom);
1711
+ goto do_incatom;
1712
+
1713
+ case JSOP_INCVAR:
1714
+ case JSOP_DECVAR:
1715
+ atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc));
1716
+ LOCAL_ASSERT(atom);
1717
+ goto do_incatom;
1718
+
1719
+ case JSOP_INCNAME:
1720
+ case JSOP_DECNAME:
1721
+ case JSOP_INCGVAR:
1722
+ case JSOP_DECGVAR:
1723
+ atom = GET_ATOM(cx, jp->script, pc);
1724
+ do_incatom:
1725
+ lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
1726
+ if (!lval)
1727
+ return JS_FALSE;
1728
+ RETRACT(&ss->sprinter, lval);
1729
+ todo = Sprint(&ss->sprinter, "%s%s",
1730
+ js_incop_str[!(cs->format & JOF_INC)], lval);
1731
+ break;
1732
+
1733
+ case JSOP_INCPROP:
1734
+ case JSOP_DECPROP:
1735
+ GET_ATOM_QUOTE_AND_FMT("%s%s[%s]", "%s%s.%s", rval);
1736
+ lval = POP_STR();
1737
+ todo = Sprint(&ss->sprinter, fmt,
1738
+ js_incop_str[!(cs->format & JOF_INC)],
1739
+ lval, rval);
1740
+ break;
1741
+
1742
+ case JSOP_INCELEM:
1743
+ case JSOP_DECELEM:
1744
+ xval = POP_STR();
1745
+ lval = POP_STR();
1746
+ todo = Sprint(&ss->sprinter, "%s%s[%s]",
1747
+ js_incop_str[!(cs->format & JOF_INC)],
1748
+ lval, xval);
1749
+ break;
1750
+
1751
+ case JSOP_ARGINC:
1752
+ case JSOP_ARGDEC:
1753
+ atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc));
1754
+ LOCAL_ASSERT(atom);
1755
+ goto do_atominc;
1756
+
1757
+ case JSOP_VARINC:
1758
+ case JSOP_VARDEC:
1759
+ atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc));
1760
+ LOCAL_ASSERT(atom);
1761
+ goto do_atominc;
1762
+
1763
+ case JSOP_NAMEINC:
1764
+ case JSOP_NAMEDEC:
1765
+ case JSOP_GVARINC:
1766
+ case JSOP_GVARDEC:
1767
+ atom = GET_ATOM(cx, jp->script, pc);
1768
+ do_atominc:
1769
+ lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
1770
+ if (!lval)
1771
+ return JS_FALSE;
1772
+ todo = STR2OFF(&ss->sprinter, lval);
1773
+ SprintPut(&ss->sprinter,
1774
+ js_incop_str[!(cs->format & JOF_INC)],
1775
+ 2);
1776
+ break;
1777
+
1778
+ case JSOP_PROPINC:
1779
+ case JSOP_PROPDEC:
1780
+ GET_ATOM_QUOTE_AND_FMT("%s[%s]%s", "%s.%s%s", rval);
1781
+ lval = POP_STR();
1782
+ todo = Sprint(&ss->sprinter, fmt, lval, rval,
1783
+ js_incop_str[!(cs->format & JOF_INC)]);
1784
+ break;
1785
+
1786
+ case JSOP_ELEMINC:
1787
+ case JSOP_ELEMDEC:
1788
+ xval = POP_STR();
1789
+ lval = POP_STR();
1790
+ todo = Sprint(&ss->sprinter, "%s[%s]%s",
1791
+ lval, xval,
1792
+ js_incop_str[!(cs->format & JOF_INC)]);
1793
+ break;
1794
+
1795
+ case JSOP_GETPROP2:
1796
+ op = JSOP_GETPROP;
1797
+ (void) PopOff(ss, lastop);
1798
+ /* FALL THROUGH */
1799
+
1800
+ case JSOP_GETPROP:
1801
+ GET_ATOM_QUOTE_AND_FMT("%s[%s]", "%s.%s", rval);
1802
+ lval = POP_STR();
1803
+ todo = Sprint(&ss->sprinter, fmt, lval, rval);
1804
+ break;
1805
+
1806
+ case JSOP_SETPROP:
1807
+ GET_ATOM_QUOTE_AND_FMT("%s[%s] %s= %s", "%s.%s %s= %s", xval);
1808
+ rval = POP_STR();
1809
+ lval = POP_STR();
1810
+ sn = js_GetSrcNote(jp->script, pc - 1);
1811
+ todo = Sprint(&ss->sprinter, fmt, lval, xval,
1812
+ (sn && SN_TYPE(sn) == SRC_ASSIGNOP)
1813
+ ? js_CodeSpec[lastop].token
1814
+ : "",
1815
+ rval);
1816
+ break;
1817
+
1818
+ case JSOP_GETELEM2:
1819
+ op = JSOP_GETELEM;
1820
+ (void) PopOff(ss, lastop);
1821
+ /* FALL THROUGH */
1822
+
1823
+ case JSOP_GETELEM:
1824
+ op = JSOP_NOP; /* turn off parens */
1825
+ xval = POP_STR();
1826
+ op = JSOP_GETELEM;
1827
+ lval = POP_STR();
1828
+ if (*xval == '\0')
1829
+ todo = Sprint(&ss->sprinter, "%s", lval);
1830
+ else
1831
+ todo = Sprint(&ss->sprinter, "%s[%s]", lval, xval);
1832
+ break;
1833
+
1834
+ case JSOP_SETELEM:
1835
+ op = JSOP_NOP; /* turn off parens */
1836
+ rval = POP_STR();
1837
+ xval = POP_STR();
1838
+ op = JSOP_SETELEM;
1839
+ lval = POP_STR();
1840
+ if (*xval == '\0')
1841
+ goto do_setlval;
1842
+ sn = js_GetSrcNote(jp->script, pc - 1);
1843
+ todo = Sprint(&ss->sprinter, "%s[%s] %s= %s",
1844
+ lval, xval,
1845
+ (sn && SN_TYPE(sn) == SRC_ASSIGNOP)
1846
+ ? js_CodeSpec[lastop].token
1847
+ : "",
1848
+ rval);
1849
+ break;
1850
+
1851
+ case JSOP_ARGSUB:
1852
+ i = (jsint) GET_ATOM_INDEX(pc);
1853
+ todo = Sprint(&ss->sprinter, "%s[%d]",
1854
+ js_arguments_str, (int) i);
1855
+ break;
1856
+
1857
+ case JSOP_ARGCNT:
1858
+ todo = Sprint(&ss->sprinter, "%s.%s",
1859
+ js_arguments_str, js_length_str);
1860
+ break;
1861
+
1862
+ case JSOP_GETARG:
1863
+ atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc));
1864
+ LOCAL_ASSERT(atom);
1865
+ goto do_name;
1866
+
1867
+ case JSOP_GETVAR:
1868
+ atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc));
1869
+ LOCAL_ASSERT(atom);
1870
+ goto do_name;
1871
+
1872
+ case JSOP_NAME:
1873
+ case JSOP_GETGVAR:
1874
+ atom = GET_ATOM(cx, jp->script, pc);
1875
+ do_name:
1876
+ sn = js_GetSrcNote(jp->script, pc);
1877
+ rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
1878
+ if (!rval)
1879
+ return JS_FALSE;
1880
+ RETRACT(&ss->sprinter, rval);
1881
+ todo = Sprint(&ss->sprinter, "%s%s", VarPrefix(sn), rval);
1882
+ break;
1883
+
1884
+ case JSOP_UINT16:
1885
+ i = (jsint) GET_ATOM_INDEX(pc);
1886
+ todo = Sprint(&ss->sprinter, "%u", (unsigned) i);
1887
+ break;
1888
+
1889
+ case JSOP_NUMBER:
1890
+ atom = GET_ATOM(cx, jp->script, pc);
1891
+ val = ATOM_KEY(atom);
1892
+ if (JSVAL_IS_INT(val)) {
1893
+ long ival = (long)JSVAL_TO_INT(val);
1894
+ todo = Sprint(&ss->sprinter, "%ld", ival);
1895
+ } else {
1896
+ char buf[DTOSTR_STANDARD_BUFFER_SIZE];
1897
+ char *numStr = JS_dtostr(buf, sizeof buf, DTOSTR_STANDARD,
1898
+ 0, *JSVAL_TO_DOUBLE(val));
1899
+ if (!numStr) {
1900
+ JS_ReportOutOfMemory(cx);
1901
+ return JS_FALSE;
1902
+ }
1903
+ todo = Sprint(&ss->sprinter, numStr);
1904
+ }
1905
+ break;
1906
+
1907
+ case JSOP_STRING:
1908
+ atom = GET_ATOM(cx, jp->script, pc);
1909
+ rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom),
1910
+ (jschar)'"');
1911
+ if (!rval)
1912
+ return JS_FALSE;
1913
+ todo = STR2OFF(&ss->sprinter, rval);
1914
+ break;
1915
+
1916
+ case JSOP_OBJECT:
1917
+ case JSOP_REGEXP:
1918
+ case JSOP_ANONFUNOBJ:
1919
+ case JSOP_NAMEDFUNOBJ:
1920
+ atom = GET_ATOM(cx, jp->script, pc);
1921
+ if (op == JSOP_OBJECT || op == JSOP_REGEXP) {
1922
+ if (!js_regexp_toString(cx, ATOM_TO_OBJECT(atom), 0, NULL,
1923
+ &val)) {
1924
+ return JS_FALSE;
1925
+ }
1926
+ } else {
1927
+ if (!js_fun_toString(cx, ATOM_TO_OBJECT(atom),
1928
+ (pc + len < endpc &&
1929
+ pc[len] == JSOP_GROUP)
1930
+ ? JS_IN_GROUP_CONTEXT |
1931
+ JS_DONT_PRETTY_PRINT
1932
+ : JS_DONT_PRETTY_PRINT,
1933
+ 0, NULL, &val)) {
1934
+ return JS_FALSE;
1935
+ }
1936
+ }
1937
+ str = JSVAL_TO_STRING(val);
1938
+ todo = SprintPut(&ss->sprinter, JS_GetStringBytes(str),
1939
+ JSSTRING_LENGTH(str));
1940
+ break;
1941
+
1942
+ #if JS_HAS_SWITCH_STATEMENT
1943
+ case JSOP_TABLESWITCH:
1944
+ case JSOP_TABLESWITCHX:
1945
+ {
1946
+ jsbytecode *pc2;
1947
+ ptrdiff_t jmplen, off, off2;
1948
+ jsint j, n, low, high;
1949
+ TableEntry *table;
1950
+
1951
+ sn = js_GetSrcNote(jp->script, pc);
1952
+ JS_ASSERT(sn && SN_TYPE(sn) == SRC_SWITCH);
1953
+ len = js_GetSrcNoteOffset(sn, 0);
1954
+ jmplen = (op == JSOP_TABLESWITCH) ? JUMP_OFFSET_LEN
1955
+ : JUMPX_OFFSET_LEN;
1956
+ pc2 = pc;
1957
+ off = GetJumpOffset(pc, pc2);
1958
+ pc2 += jmplen;
1959
+ low = GET_JUMP_OFFSET(pc2);
1960
+ pc2 += JUMP_OFFSET_LEN;
1961
+ high = GET_JUMP_OFFSET(pc2);
1962
+ pc2 += JUMP_OFFSET_LEN;
1963
+
1964
+ n = high - low + 1;
1965
+ if (n == 0) {
1966
+ table = NULL;
1967
+ j = 0;
1968
+ } else {
1969
+ table = (TableEntry *)
1970
+ JS_malloc(cx, (size_t)n * sizeof *table);
1971
+ if (!table)
1972
+ return JS_FALSE;
1973
+ for (i = j = 0; i < n; i++) {
1974
+ table[j].label = NULL;
1975
+ off2 = GetJumpOffset(pc, pc2);
1976
+ if (off2) {
1977
+ sn = js_GetSrcNote(jp->script, pc2);
1978
+ if (sn) {
1979
+ JS_ASSERT(SN_TYPE(sn) == SRC_LABEL);
1980
+ table[j].label =
1981
+ js_GetAtom(cx, &jp->script->atomMap,
1982
+ (jsatomid)
1983
+ js_GetSrcNoteOffset(sn, 0));
1984
+ }
1985
+ table[j].key = INT_TO_JSVAL(low + i);
1986
+ table[j].offset = off2;
1987
+ table[j].order = j;
1988
+ j++;
1989
+ }
1990
+ pc2 += jmplen;
1991
+ }
1992
+ js_HeapSort(table, (size_t) j, sizeof(TableEntry),
1993
+ CompareOffsets, NULL);
1994
+ }
1995
+
1996
+ ok = DecompileSwitch(ss, table, (uintN)j, pc, len, off,
1997
+ JS_FALSE);
1998
+ JS_free(cx, table);
1999
+ if (!ok)
2000
+ return ok;
2001
+ todo = -2;
2002
+ break;
2003
+ }
2004
+
2005
+ case JSOP_LOOKUPSWITCH:
2006
+ case JSOP_LOOKUPSWITCHX:
2007
+ {
2008
+ jsbytecode *pc2;
2009
+ ptrdiff_t jmplen, off, off2;
2010
+ jsatomid npairs, k;
2011
+ TableEntry *table;
2012
+
2013
+ sn = js_GetSrcNote(jp->script, pc);
2014
+ JS_ASSERT(sn && SN_TYPE(sn) == SRC_SWITCH);
2015
+ len = js_GetSrcNoteOffset(sn, 0);
2016
+ jmplen = (op == JSOP_LOOKUPSWITCH) ? JUMP_OFFSET_LEN
2017
+ : JUMPX_OFFSET_LEN;
2018
+ pc2 = pc;
2019
+ off = GetJumpOffset(pc, pc2);
2020
+ pc2 += jmplen;
2021
+ npairs = GET_ATOM_INDEX(pc2);
2022
+ pc2 += ATOM_INDEX_LEN;
2023
+
2024
+ table = (TableEntry *)
2025
+ JS_malloc(cx, (size_t)npairs * sizeof *table);
2026
+ if (!table)
2027
+ return JS_FALSE;
2028
+ for (k = 0; k < npairs; k++) {
2029
+ sn = js_GetSrcNote(jp->script, pc2);
2030
+ if (sn) {
2031
+ JS_ASSERT(SN_TYPE(sn) == SRC_LABEL);
2032
+ table[k].label =
2033
+ js_GetAtom(cx, &jp->script->atomMap, (jsatomid)
2034
+ js_GetSrcNoteOffset(sn, 0));
2035
+ } else {
2036
+ table[k].label = NULL;
2037
+ }
2038
+ atom = GET_ATOM(cx, jp->script, pc2);
2039
+ pc2 += ATOM_INDEX_LEN;
2040
+ off2 = GetJumpOffset(pc, pc2);
2041
+ pc2 += jmplen;
2042
+ table[k].key = ATOM_KEY(atom);
2043
+ table[k].offset = off2;
2044
+ }
2045
+
2046
+ ok = DecompileSwitch(ss, table, (uintN)npairs, pc, len, off,
2047
+ JS_FALSE);
2048
+ JS_free(cx, table);
2049
+ if (!ok)
2050
+ return ok;
2051
+ todo = -2;
2052
+ break;
2053
+ }
2054
+
2055
+ case JSOP_CONDSWITCH:
2056
+ {
2057
+ jsbytecode *pc2;
2058
+ ptrdiff_t off, off2, caseOff;
2059
+ jsint ncases;
2060
+ TableEntry *table;
2061
+
2062
+ sn = js_GetSrcNote(jp->script, pc);
2063
+ JS_ASSERT(sn && SN_TYPE(sn) == SRC_SWITCH);
2064
+ len = js_GetSrcNoteOffset(sn, 0);
2065
+ off = js_GetSrcNoteOffset(sn, 1);
2066
+
2067
+ /*
2068
+ * Count the cases using offsets from switch to first case,
2069
+ * and case to case, stored in srcnote immediates.
2070
+ */
2071
+ pc2 = pc;
2072
+ off2 = off;
2073
+ for (ncases = 0; off2 != 0; ncases++) {
2074
+ pc2 += off2;
2075
+ JS_ASSERT(*pc2 == JSOP_CASE || *pc2 == JSOP_DEFAULT ||
2076
+ *pc2 == JSOP_CASEX || *pc2 == JSOP_DEFAULTX);
2077
+ if (*pc2 == JSOP_DEFAULT || *pc2 == JSOP_DEFAULTX) {
2078
+ /* End of cases, but count default as a case. */
2079
+ off2 = 0;
2080
+ } else {
2081
+ sn = js_GetSrcNote(jp->script, pc2);
2082
+ JS_ASSERT(sn && SN_TYPE(sn) == SRC_PCDELTA);
2083
+ off2 = js_GetSrcNoteOffset(sn, 0);
2084
+ }
2085
+ }
2086
+
2087
+ /*
2088
+ * Allocate table and rescan the cases using their srcnotes,
2089
+ * stashing each case's delta from switch top in table[i].key,
2090
+ * and the distance to its statements in table[i].offset.
2091
+ */
2092
+ table = (TableEntry *)
2093
+ JS_malloc(cx, (size_t)ncases * sizeof *table);
2094
+ if (!table)
2095
+ return JS_FALSE;
2096
+ pc2 = pc;
2097
+ off2 = off;
2098
+ for (i = 0; i < ncases; i++) {
2099
+ pc2 += off2;
2100
+ JS_ASSERT(*pc2 == JSOP_CASE || *pc2 == JSOP_DEFAULT ||
2101
+ *pc2 == JSOP_CASEX || *pc2 == JSOP_DEFAULTX);
2102
+ caseOff = pc2 - pc;
2103
+ table[i].key = INT_TO_JSVAL((jsint) caseOff);
2104
+ table[i].offset = caseOff + GetJumpOffset(pc2, pc2);
2105
+ if (*pc2 == JSOP_CASE || *pc2 == JSOP_CASEX) {
2106
+ sn = js_GetSrcNote(jp->script, pc2);
2107
+ JS_ASSERT(sn && SN_TYPE(sn) == SRC_PCDELTA);
2108
+ off2 = js_GetSrcNoteOffset(sn, 0);
2109
+ }
2110
+ }
2111
+
2112
+ /*
2113
+ * Find offset of default code by fetching the default offset
2114
+ * from the end of table. JSOP_CONDSWITCH always has a default
2115
+ * case at the end.
2116
+ */
2117
+ off = JSVAL_TO_INT(table[ncases-1].key);
2118
+ pc2 = pc + off;
2119
+ off += GetJumpOffset(pc2, pc2);
2120
+
2121
+ ok = DecompileSwitch(ss, table, (uintN)ncases, pc, len, off,
2122
+ JS_TRUE);
2123
+ JS_free(cx, table);
2124
+ if (!ok)
2125
+ return ok;
2126
+ todo = -2;
2127
+ break;
2128
+ }
2129
+
2130
+ case JSOP_CASE:
2131
+ case JSOP_CASEX:
2132
+ {
2133
+ lval = POP_STR();
2134
+ if (!lval)
2135
+ return JS_FALSE;
2136
+ js_printf(jp, "\tcase %s:\n", lval);
2137
+ todo = -2;
2138
+ break;
2139
+ }
2140
+
2141
+ #endif /* JS_HAS_SWITCH_STATEMENT */
2142
+
2143
+ #if !JS_BUG_FALLIBLE_EQOPS
2144
+ case JSOP_NEW_EQ:
2145
+ case JSOP_NEW_NE:
2146
+ rval = POP_STR();
2147
+ lval = POP_STR();
2148
+ todo = Sprint(&ss->sprinter, "%s %c%s %s",
2149
+ lval,
2150
+ (op == JSOP_NEW_EQ) ? '=' : '!',
2151
+ #if JS_HAS_TRIPLE_EQOPS
2152
+ JSVERSION_IS_ECMA(cx->version) ? "==" :
2153
+ #endif
2154
+ "=",
2155
+ rval);
2156
+ break;
2157
+ #endif /* !JS_BUG_FALLIBLE_EQOPS */
2158
+
2159
+ #if JS_HAS_LEXICAL_CLOSURE
2160
+ case JSOP_CLOSURE:
2161
+ atom = GET_ATOM(cx, jp->script, pc);
2162
+ JS_ASSERT(ATOM_IS_OBJECT(atom));
2163
+ goto do_function;
2164
+ #endif /* JS_HAS_LEXICAL_CLOSURE */
2165
+
2166
+ #if JS_HAS_EXPORT_IMPORT
2167
+ case JSOP_EXPORTALL:
2168
+ js_printf(jp, "\texport *\n");
2169
+ todo = -2;
2170
+ break;
2171
+
2172
+ case JSOP_EXPORTNAME:
2173
+ atom = GET_ATOM(cx, jp->script, pc);
2174
+ rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
2175
+ if (!rval)
2176
+ return JS_FALSE;
2177
+ RETRACT(&ss->sprinter, rval);
2178
+ js_printf(jp, "\texport %s\n", rval);
2179
+ todo = -2;
2180
+ break;
2181
+
2182
+ case JSOP_IMPORTALL:
2183
+ lval = POP_STR();
2184
+ js_printf(jp, "\timport %s.*\n", lval);
2185
+ todo = -2;
2186
+ break;
2187
+
2188
+ case JSOP_IMPORTPROP:
2189
+ GET_ATOM_QUOTE_AND_FMT("\timport %s[%s]\n", "\timport %s.%s\n",
2190
+ rval);
2191
+ lval = POP_STR();
2192
+ js_printf(jp, fmt, lval, rval);
2193
+ todo = -2;
2194
+ break;
2195
+
2196
+ case JSOP_IMPORTELEM:
2197
+ xval = POP_STR();
2198
+ op = JSOP_GETELEM;
2199
+ lval = POP_STR();
2200
+ js_printf(jp, "\timport %s[%s]\n", lval, xval);
2201
+ todo = -2;
2202
+ break;
2203
+ #endif /* JS_HAS_EXPORT_IMPORT */
2204
+
2205
+ case JSOP_TRAP:
2206
+ op = JS_GetTrapOpcode(cx, jp->script, pc);
2207
+ if (op == JSOP_LIMIT)
2208
+ return JS_FALSE;
2209
+ *pc = op;
2210
+ cs = &js_CodeSpec[op];
2211
+ len = cs->length;
2212
+ DECOMPILE_CODE(pc, len);
2213
+ *pc = JSOP_TRAP;
2214
+ todo = -2;
2215
+ break;
2216
+
2217
+ #if JS_HAS_INITIALIZERS
2218
+ case JSOP_NEWINIT:
2219
+ LOCAL_ASSERT(ss->top >= 2);
2220
+ (void) PopOff(ss, op);
2221
+ lval = POP_STR();
2222
+ #if JS_HAS_SHARP_VARS
2223
+ op = (JSOp)pc[len];
2224
+ if (op == JSOP_DEFSHARP) {
2225
+ pc += len;
2226
+ cs = &js_CodeSpec[op];
2227
+ len = cs->length;
2228
+ i = (jsint) GET_ATOM_INDEX(pc);
2229
+ todo = Sprint(&ss->sprinter, "#%u=%c",
2230
+ (unsigned) i,
2231
+ (*lval == 'O') ? '{' : '[');
2232
+ } else
2233
+ #endif /* JS_HAS_SHARP_VARS */
2234
+ {
2235
+ todo = Sprint(&ss->sprinter, (*lval == 'O') ? "{" : "[");
2236
+ }
2237
+ break;
2238
+
2239
+ case JSOP_ENDINIT:
2240
+ rval = POP_STR();
2241
+ sn = js_GetSrcNote(jp->script, pc);
2242
+ todo = Sprint(&ss->sprinter, "%s%s%c",
2243
+ rval,
2244
+ (sn && SN_TYPE(sn) == SRC_CONTINUE) ? ", " : "",
2245
+ (*rval == '{') ? '}' : ']');
2246
+ break;
2247
+
2248
+ case JSOP_INITPROP:
2249
+ case JSOP_INITCATCHVAR:
2250
+ atom = GET_ATOM(cx, jp->script, pc);
2251
+ xval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom),
2252
+ ATOM_IS_IDENTIFIER(atom) ? 0 : '\'');
2253
+ if (!xval)
2254
+ return JS_FALSE;
2255
+ rval = POP_STR();
2256
+ lval = POP_STR();
2257
+ do_initprop:
2258
+ #ifdef OLD_GETTER_SETTER
2259
+ todo = Sprint(&ss->sprinter, "%s%s%s%s%s:%s",
2260
+ lval,
2261
+ (lval[1] != '\0') ? ", " : "",
2262
+ xval,
2263
+ (lastop == JSOP_GETTER || lastop == JSOP_SETTER)
2264
+ ? " " : "",
2265
+ (lastop == JSOP_GETTER) ? js_getter_str :
2266
+ (lastop == JSOP_SETTER) ? js_setter_str :
2267
+ "",
2268
+ rval);
2269
+ #else
2270
+ if (lastop == JSOP_GETTER || lastop == JSOP_SETTER) {
2271
+ todo = Sprint(&ss->sprinter, "%s%s%s %s%s",
2272
+ lval,
2273
+ (lval[1] != '\0') ? ", " : "",
2274
+ (lastop == JSOP_GETTER)
2275
+ ? js_get_str : js_set_str,
2276
+ xval,
2277
+ rval + strlen(js_function_str) + 1);
2278
+ } else {
2279
+ todo = Sprint(&ss->sprinter, "%s%s%s:%s",
2280
+ lval,
2281
+ (lval[1] != '\0') ? ", " : "",
2282
+ xval,
2283
+ rval);
2284
+ }
2285
+ #endif
2286
+ break;
2287
+
2288
+ case JSOP_INITELEM:
2289
+ rval = POP_STR();
2290
+ xval = POP_STR();
2291
+ lval = POP_STR();
2292
+ sn = js_GetSrcNote(jp->script, pc);
2293
+ if (sn && SN_TYPE(sn) == SRC_LABEL)
2294
+ goto do_initprop;
2295
+ todo = Sprint(&ss->sprinter, "%s%s%s",
2296
+ lval,
2297
+ (lval[1] != '\0' || *xval != '0') ? ", " : "",
2298
+ rval);
2299
+ break;
2300
+
2301
+ #if JS_HAS_SHARP_VARS
2302
+ case JSOP_DEFSHARP:
2303
+ i = (jsint) GET_ATOM_INDEX(pc);
2304
+ rval = POP_STR();
2305
+ todo = Sprint(&ss->sprinter, "#%u=%s", (unsigned) i, rval);
2306
+ break;
2307
+
2308
+ case JSOP_USESHARP:
2309
+ i = (jsint) GET_ATOM_INDEX(pc);
2310
+ todo = Sprint(&ss->sprinter, "#%u#", (unsigned) i);
2311
+ break;
2312
+ #endif /* JS_HAS_SHARP_VARS */
2313
+ #endif /* JS_HAS_INITIALIZERS */
2314
+
2315
+ #if JS_HAS_DEBUGGER_KEYWORD
2316
+ case JSOP_DEBUGGER:
2317
+ js_printf(jp, "\tdebugger;\n");
2318
+ todo = -2;
2319
+ break;
2320
+ #endif /* JS_HAS_DEBUGGER_KEYWORD */
2321
+
2322
+ default:
2323
+ todo = -2;
2324
+ break;
2325
+ }
2326
+ }
2327
+
2328
+ if (todo < 0) {
2329
+ /* -2 means "don't push", -1 means reported error. */
2330
+ if (todo == -1)
2331
+ return JS_FALSE;
2332
+ } else {
2333
+ if (!PushOff(ss, todo, op))
2334
+ return JS_FALSE;
2335
+ }
2336
+ pc += len;
2337
+ }
2338
+
2339
+ /*
2340
+ * Undefine local macros.
2341
+ */
2342
+ #undef DECOMPILE_CODE
2343
+ #undef POP_STR
2344
+ #undef LOCAL_ASSERT
2345
+ #undef ATOM_IS_IDENTIFIER
2346
+ #undef GET_ATOM_QUOTE_AND_FMT
2347
+
2348
+ return JS_TRUE;
2349
+ }
2350
+
2351
+
2352
+ JSBool
2353
+ js_DecompileCode(JSPrinter *jp, JSScript *script, jsbytecode *pc, uintN len)
2354
+ {
2355
+ SprintStack ss;
2356
+ JSContext *cx;
2357
+ void *mark, *space;
2358
+ size_t offsetsz, opcodesz;
2359
+ JSBool ok;
2360
+ JSScript *oldscript;
2361
+ char *last;
2362
+
2363
+ /* Initialize a sprinter for use with the offset stack. */
2364
+ ss.printer = jp;
2365
+ cx = jp->sprinter.context;
2366
+ mark = JS_ARENA_MARK(&cx->tempPool);
2367
+ INIT_SPRINTER(cx, &ss.sprinter, &cx->tempPool, PAREN_SLOP);
2368
+
2369
+ /* Allocate the parallel (to avoid padding) offset and opcode stacks. */
2370
+ offsetsz = script->depth * sizeof(ptrdiff_t);
2371
+ opcodesz = script->depth * sizeof(jsbytecode);
2372
+ JS_ARENA_ALLOCATE(space, &cx->tempPool, offsetsz + opcodesz);
2373
+ if (!space) {
2374
+ ok = JS_FALSE;
2375
+ goto out;
2376
+ }
2377
+ ss.offsets = (ptrdiff_t *) space;
2378
+ ss.opcodes = (jsbytecode *) ((char *)space + offsetsz);
2379
+ ss.top = 0;
2380
+
2381
+ /* Call recursive subroutine to do the hard work. */
2382
+ oldscript = jp->script;
2383
+ jp->script = script;
2384
+ ok = Decompile(&ss, pc, len);
2385
+ jp->script = oldscript;
2386
+
2387
+ /* If the given code didn't empty the stack, do it now. */
2388
+ if (ss.top) {
2389
+ do {
2390
+ last = OFF2STR(&ss.sprinter, PopOff(&ss, JSOP_NOP));
2391
+ } while (ss.top);
2392
+ js_printf(jp, "%s", last);
2393
+ }
2394
+
2395
+ out:
2396
+ /* Free all temporary stuff allocated under this call. */
2397
+ JS_ARENA_RELEASE(&cx->tempPool, mark);
2398
+ return ok;
2399
+ }
2400
+
2401
+ JSBool
2402
+ js_DecompileScript(JSPrinter *jp, JSScript *script)
2403
+ {
2404
+ return js_DecompileCode(jp, script, script->code, (uintN)script->length);
2405
+ }
2406
+
2407
+ static const char native_code_str[] = "\t[native code]\n";
2408
+
2409
+ JSBool
2410
+ js_DecompileFunctionBody(JSPrinter *jp, JSFunction *fun)
2411
+ {
2412
+ JSScript *script;
2413
+ JSScope *scope, *save;
2414
+ JSBool ok;
2415
+
2416
+ if (!fun->interpreted) {
2417
+ js_printf(jp, native_code_str);
2418
+ return JS_TRUE;
2419
+ }
2420
+ script = fun->u.script;
2421
+ scope = fun->object ? OBJ_SCOPE(fun->object) : NULL;
2422
+ save = jp->scope;
2423
+ jp->scope = scope;
2424
+ ok = js_DecompileCode(jp, script, script->code, (uintN)script->length);
2425
+ jp->scope = save;
2426
+ return ok;
2427
+ }
2428
+
2429
+ JSBool
2430
+ js_DecompileFunction(JSPrinter *jp, JSFunction *fun)
2431
+ {
2432
+ JSContext *cx;
2433
+ uintN i, nargs, indent;
2434
+ void *mark;
2435
+ JSAtom **params;
2436
+ JSScope *scope, *oldscope;
2437
+ JSScopeProperty *sprop;
2438
+ JSBool ok;
2439
+
2440
+ /*
2441
+ * If pretty, conform to ECMA-262 Edition 3, 15.3.4.2, by decompiling a
2442
+ * FunctionDeclaration. Otherwise, check the JSFUN_LAMBDA flag and force
2443
+ * an expression by parenthesizing.
2444
+ */
2445
+ if (jp->pretty) {
2446
+ js_puts(jp, "\n");
2447
+ js_printf(jp, "\t");
2448
+ } else {
2449
+ if (!jp->grouped && (fun->flags & JSFUN_LAMBDA))
2450
+ js_puts(jp, "(");
2451
+ }
2452
+ if (fun->flags & JSFUN_GETTER)
2453
+ js_printf(jp, "%s ", js_getter_str);
2454
+ else if (fun->flags & JSFUN_SETTER)
2455
+ js_printf(jp, "%s ", js_setter_str);
2456
+
2457
+ js_printf(jp, "%s ", js_function_str);
2458
+ if (fun->atom && !QuoteString(&jp->sprinter, ATOM_TO_STRING(fun->atom), 0))
2459
+ return JS_FALSE;
2460
+ js_puts(jp, "(");
2461
+
2462
+ if (fun->interpreted && fun->object) {
2463
+ /*
2464
+ * Print the parameters.
2465
+ *
2466
+ * This code is complicated by the need to handle duplicate parameter
2467
+ * names, as required by ECMA (bah!). A duplicate parameter is stored
2468
+ * as another node with the same id (the parameter name) but different
2469
+ * shortid (the argument index) along the property tree ancestor line
2470
+ * starting at SCOPE_LAST_PROP(scope). Only the last duplicate param
2471
+ * is mapped by the scope's hash table.
2472
+ */
2473
+ cx = jp->sprinter.context;
2474
+ nargs = fun->nargs;
2475
+ mark = JS_ARENA_MARK(&cx->tempPool);
2476
+ JS_ARENA_ALLOCATE_CAST(params, JSAtom **, &cx->tempPool,
2477
+ nargs * sizeof(JSAtom *));
2478
+ if (!params) {
2479
+ JS_ReportOutOfMemory(cx);
2480
+ return JS_FALSE;
2481
+ }
2482
+ scope = OBJ_SCOPE(fun->object);
2483
+ for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) {
2484
+ if (sprop->getter != js_GetArgument)
2485
+ continue;
2486
+ JS_ASSERT(sprop->flags & SPROP_HAS_SHORTID);
2487
+ JS_ASSERT((uintN) sprop->shortid < nargs);
2488
+ JS_ASSERT(!JSVAL_IS_INT(sprop->id));
2489
+ params[(uintN) sprop->shortid] = (JSAtom *) sprop->id;
2490
+ }
2491
+ for (i = 0; i < nargs; i++) {
2492
+ if (i > 0)
2493
+ js_puts(jp, ", ");
2494
+ if (!QuoteString(&jp->sprinter, ATOM_TO_STRING(params[i]), 0))
2495
+ return JS_FALSE;
2496
+ }
2497
+ JS_ARENA_RELEASE(&cx->tempPool, mark);
2498
+ #ifdef __GNUC__
2499
+ } else {
2500
+ scope = NULL;
2501
+ #endif
2502
+ }
2503
+
2504
+ js_printf(jp, ") {\n");
2505
+ indent = jp->indent;
2506
+ jp->indent += 4;
2507
+ if (fun->interpreted && fun->object) {
2508
+ oldscope = jp->scope;
2509
+ jp->scope = scope;
2510
+ ok = js_DecompileScript(jp, fun->u.script);
2511
+ jp->scope = oldscope;
2512
+ if (!ok) {
2513
+ jp->indent = indent;
2514
+ return JS_FALSE;
2515
+ }
2516
+ } else {
2517
+ js_printf(jp, native_code_str);
2518
+ }
2519
+ jp->indent -= 4;
2520
+ js_printf(jp, "\t}");
2521
+
2522
+ if (jp->pretty) {
2523
+ js_puts(jp, "\n");
2524
+ } else {
2525
+ if (!jp->grouped && (fun->flags & JSFUN_LAMBDA))
2526
+ js_puts(jp, ")");
2527
+ }
2528
+ return JS_TRUE;
2529
+ }
2530
+
2531
+ JSString *
2532
+ js_DecompileValueGenerator(JSContext *cx, intN spindex, jsval v,
2533
+ JSString *fallback)
2534
+ {
2535
+ JSStackFrame *fp, *down;
2536
+ jsbytecode *pc, *begin, *end, *tmp;
2537
+ jsval *sp, *base, *limit;
2538
+ JSScript *script;
2539
+ JSOp op;
2540
+ const JSCodeSpec *cs;
2541
+ uint32 format, mode;
2542
+ intN depth;
2543
+ jssrcnote *sn;
2544
+ uintN len, off;
2545
+ JSPrinter *jp;
2546
+ JSString *name;
2547
+
2548
+ fp = cx->fp;
2549
+ if (!fp)
2550
+ goto do_fallback;
2551
+
2552
+ /* Try to find sp's generating pc depth slots under it on the stack. */
2553
+ pc = fp->pc;
2554
+ if (spindex == JSDVG_SEARCH_STACK) {
2555
+ if (!pc) {
2556
+ /*
2557
+ * Current frame is native: look under it for a scripted call
2558
+ * in which a decompilable bytecode string that generated the
2559
+ * value as an actual argument might exist.
2560
+ */
2561
+ JS_ASSERT(!fp->script && !(fp->fun && fp->fun->interpreted));
2562
+ down = fp->down;
2563
+ if (!down)
2564
+ goto do_fallback;
2565
+ script = down->script;
2566
+ base = fp->argv;
2567
+ limit = base + fp->argc;
2568
+ } else {
2569
+ /*
2570
+ * This should be a script activation, either a top-level
2571
+ * script or a scripted function. But be paranoid about calls
2572
+ * to js_DecompileValueGenerator from code that hasn't fully
2573
+ * initialized a (default-all-zeroes) frame.
2574
+ */
2575
+ script = fp->script;
2576
+ base = fp->spbase;
2577
+ limit = fp->sp;
2578
+ }
2579
+
2580
+ /*
2581
+ * Pure paranoia about default-zeroed frames being active while
2582
+ * js_DecompileValueGenerator is called. It can't hurt much now;
2583
+ * error reporting performance is not an issue.
2584
+ */
2585
+ if (!script || !base || !limit)
2586
+ goto do_fallback;
2587
+
2588
+ /*
2589
+ * Try to find operand-generating pc depth slots below sp.
2590
+ *
2591
+ * In the native case, we know the arguments have generating pc's
2592
+ * under them, on account of fp->down->script being non-null: all
2593
+ * compiled scripts get depth slots for generating pc's allocated
2594
+ * upon activation, at the top of js_Interpret.
2595
+ *
2596
+ * In the script or scripted function case, the same reasoning
2597
+ * applies to fp rather than to fp->down.
2598
+ */
2599
+ for (sp = base; sp < limit; sp++) {
2600
+ if (*sp == v) {
2601
+ depth = (intN)script->depth;
2602
+ pc = (jsbytecode *) sp[-depth];
2603
+ break;
2604
+ }
2605
+ }
2606
+ } else {
2607
+ /*
2608
+ * At this point, pc may or may not be null, i.e., we could be in
2609
+ * a script activation, or we could be in a native frame that was
2610
+ * called by another native function. Check pc and script.
2611
+ */
2612
+ if (!pc)
2613
+ goto do_fallback;
2614
+ script = fp->script;
2615
+ if (!script)
2616
+ goto do_fallback;
2617
+
2618
+ if (spindex != JSDVG_IGNORE_STACK) {
2619
+ JS_ASSERT(spindex < 0);
2620
+ depth = (intN)script->depth;
2621
+ #if !JS_HAS_NO_SUCH_METHOD
2622
+ JS_ASSERT(-depth <= spindex);
2623
+ #endif
2624
+ spindex -= depth;
2625
+
2626
+ base = (jsval *) cx->stackPool.current->base;
2627
+ limit = (jsval *) cx->stackPool.current->avail;
2628
+ sp = fp->sp + spindex;
2629
+ if (JS_UPTRDIFF(sp, base) < JS_UPTRDIFF(limit, base))
2630
+ pc = (jsbytecode *) *sp;
2631
+ }
2632
+ }
2633
+
2634
+ /*
2635
+ * Again, be paranoid, this time about possibly loading an invalid pc
2636
+ * from sp[-(1+depth)].
2637
+ */
2638
+ if (JS_UPTRDIFF(pc, script->code) >= (jsuword)script->length) {
2639
+ pc = fp->pc;
2640
+ if (!pc)
2641
+ goto do_fallback;
2642
+ }
2643
+ op = (JSOp) *pc;
2644
+ if (op == JSOP_TRAP)
2645
+ op = JS_GetTrapOpcode(cx, script, pc);
2646
+
2647
+ /* XXX handle null as a special case, to avoid calling null "object" */
2648
+ if (op == JSOP_NULL)
2649
+ return ATOM_TO_STRING(cx->runtime->atomState.nullAtom);
2650
+
2651
+ cs = &js_CodeSpec[op];
2652
+ format = cs->format;
2653
+ mode = (format & JOF_MODEMASK);
2654
+
2655
+ /* NAME ops are self-contained, but others require left context. */
2656
+ if (mode == JOF_NAME) {
2657
+ begin = pc;
2658
+ } else {
2659
+ sn = js_GetSrcNote(script, pc);
2660
+ if (!sn || SN_TYPE(sn) != SRC_PCBASE)
2661
+ goto do_fallback;
2662
+ begin = pc - js_GetSrcNoteOffset(sn, 0);
2663
+ }
2664
+ end = pc + cs->length;
2665
+ len = PTRDIFF(end, begin, jsbytecode);
2666
+
2667
+ if (format & (JOF_SET | JOF_DEL | JOF_INCDEC | JOF_IMPORT | JOF_FOR)) {
2668
+ tmp = (jsbytecode *) JS_malloc(cx, len * sizeof(jsbytecode));
2669
+ if (!tmp)
2670
+ return NULL;
2671
+ memcpy(tmp, begin, len * sizeof(jsbytecode));
2672
+ if (mode == JOF_NAME) {
2673
+ tmp[0] = JSOP_NAME;
2674
+ } else {
2675
+ /*
2676
+ * We must replace the faulting pc's bytecode with a corresponding
2677
+ * JSOP_GET* code. For JSOP_SET{PROP,ELEM}, we must use the "2nd"
2678
+ * form of JSOP_GET{PROP,ELEM}, to throw away the assignment op's
2679
+ * right-hand operand and decompile it as if it were a GET of its
2680
+ * left-hand operand.
2681
+ */
2682
+ off = len - cs->length;
2683
+ JS_ASSERT(off == (uintN) PTRDIFF(pc, begin, jsbytecode));
2684
+ if (mode == JOF_PROP) {
2685
+ tmp[off] = (format & JOF_SET) ? JSOP_GETPROP2 : JSOP_GETPROP;
2686
+ } else if (mode == JOF_ELEM) {
2687
+ tmp[off] = (format & JOF_SET) ? JSOP_GETELEM2 : JSOP_GETELEM;
2688
+ } else {
2689
+ /*
2690
+ * A zero mode means precisely that op is uncategorized for our
2691
+ * purposes, so we must write per-op special case code here.
2692
+ */
2693
+ switch (op) {
2694
+ case JSOP_ENUMELEM:
2695
+ tmp[off] = JSOP_GETELEM;
2696
+ break;
2697
+ #if JS_HAS_LVALUE_RETURN
2698
+ case JSOP_SETCALL:
2699
+ tmp[off] = JSOP_CALL;
2700
+ break;
2701
+ #endif
2702
+ default:
2703
+ JS_ASSERT(0);
2704
+ }
2705
+ }
2706
+ }
2707
+ begin = tmp;
2708
+ } else {
2709
+ /* No need to revise script bytecode. */
2710
+ tmp = NULL;
2711
+ }
2712
+
2713
+ name = NULL;
2714
+ jp = js_NewPrinter(cx, "js_DecompileValueGenerator", 0, JS_FALSE);
2715
+ if (jp) {
2716
+ if (fp->fun && fp->fun->object) {
2717
+ JS_ASSERT(OBJ_IS_NATIVE(fp->fun->object));
2718
+ jp->scope = OBJ_SCOPE(fp->fun->object);
2719
+ }
2720
+ if (js_DecompileCode(jp, script, begin, len))
2721
+ name = js_GetPrinterOutput(jp);
2722
+ }
2723
+ js_DestroyPrinter(jp);
2724
+ if (tmp)
2725
+ JS_free(cx, tmp);
2726
+ return name;
2727
+
2728
+ do_fallback:
2729
+ return fallback ? fallback : js_ValueToString(cx, v);
2730
+ }