ruby-internal 0.6.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 (310) hide show
  1. data/COPYING +59 -0
  2. data/LGPL +515 -0
  3. data/LICENSE +9 -0
  4. data/README +31 -0
  5. data/Rakefile +20 -0
  6. data/TODO +9 -0
  7. data/example/README +5 -0
  8. data/example/simple_client.rb +12 -0
  9. data/example/simple_server.rb +11 -0
  10. data/example/triangle_client.rb +7 -0
  11. data/example/triangle_server.rb +24 -0
  12. data/ext/cached/ruby-1.8.0/internal/binding/block.h +37 -0
  13. data/ext/cached/ruby-1.8.0/internal/method/method.h +19 -0
  14. data/ext/cached/ruby-1.8.0/internal/module/classpath.c +27 -0
  15. data/ext/cached/ruby-1.8.0/internal/module/classpath.h +14 -0
  16. data/ext/cached/ruby-1.8.0/internal/node/block.h +37 -0
  17. data/ext/cached/ruby-1.8.0/internal/node/global_entry.h +10 -0
  18. data/ext/cached/ruby-1.8.0/internal/node/node_type_descrip.c +155 -0
  19. data/ext/cached/ruby-1.8.0/internal/node/nodeinfo.c +5741 -0
  20. data/ext/cached/ruby-1.8.0/internal/node/nodeinfo.h +69 -0
  21. data/ext/cached/ruby-1.8.0/internal/proc/block.h +37 -0
  22. data/ext/cached/ruby-1.8.0/internal/tag/tag.h +15 -0
  23. data/ext/cached/ruby-1.8.0/internal/vm/instruction/insns_info.c +39 -0
  24. data/ext/cached/ruby-1.8.0/internal/vm/instruction/insns_info.h +21 -0
  25. data/ext/cached/ruby-1.8.0/internal/vm/iseq/insns_info.inc +12 -0
  26. data/ext/cached/ruby-1.8.1/internal/binding/block.h +31 -0
  27. data/ext/cached/ruby-1.8.1/internal/method/method.h +19 -0
  28. data/ext/cached/ruby-1.8.1/internal/module/classpath.c +27 -0
  29. data/ext/cached/ruby-1.8.1/internal/module/classpath.h +14 -0
  30. data/ext/cached/ruby-1.8.1/internal/node/block.h +31 -0
  31. data/ext/cached/ruby-1.8.1/internal/node/global_entry.h +10 -0
  32. data/ext/cached/ruby-1.8.1/internal/node/node_type_descrip.c +154 -0
  33. data/ext/cached/ruby-1.8.1/internal/node/nodeinfo.c +5733 -0
  34. data/ext/cached/ruby-1.8.1/internal/node/nodeinfo.h +69 -0
  35. data/ext/cached/ruby-1.8.1/internal/proc/block.h +31 -0
  36. data/ext/cached/ruby-1.8.1/internal/tag/tag.h +16 -0
  37. data/ext/cached/ruby-1.8.1/internal/vm/instruction/insns_info.c +39 -0
  38. data/ext/cached/ruby-1.8.1/internal/vm/instruction/insns_info.h +21 -0
  39. data/ext/cached/ruby-1.8.1/internal/vm/iseq/insns_info.inc +12 -0
  40. data/ext/cached/ruby-1.8.2/internal/binding/block.h +32 -0
  41. data/ext/cached/ruby-1.8.2/internal/method/method.h +19 -0
  42. data/ext/cached/ruby-1.8.2/internal/module/classpath.c +45 -0
  43. data/ext/cached/ruby-1.8.2/internal/module/classpath.h +17 -0
  44. data/ext/cached/ruby-1.8.2/internal/node/block.h +32 -0
  45. data/ext/cached/ruby-1.8.2/internal/node/global_entry.h +10 -0
  46. data/ext/cached/ruby-1.8.2/internal/node/node_type_descrip.c +154 -0
  47. data/ext/cached/ruby-1.8.2/internal/node/nodeinfo.c +5733 -0
  48. data/ext/cached/ruby-1.8.2/internal/node/nodeinfo.h +69 -0
  49. data/ext/cached/ruby-1.8.2/internal/proc/block.h +32 -0
  50. data/ext/cached/ruby-1.8.2/internal/tag/tag.h +16 -0
  51. data/ext/cached/ruby-1.8.2/internal/vm/instruction/insns_info.c +39 -0
  52. data/ext/cached/ruby-1.8.2/internal/vm/instruction/insns_info.h +21 -0
  53. data/ext/cached/ruby-1.8.2/internal/vm/iseq/insns_info.inc +12 -0
  54. data/ext/cached/ruby-1.8.3/internal/binding/block.h +32 -0
  55. data/ext/cached/ruby-1.8.3/internal/method/method.h +20 -0
  56. data/ext/cached/ruby-1.8.3/internal/module/classpath.c +45 -0
  57. data/ext/cached/ruby-1.8.3/internal/module/classpath.h +17 -0
  58. data/ext/cached/ruby-1.8.3/internal/node/block.h +32 -0
  59. data/ext/cached/ruby-1.8.3/internal/node/global_entry.h +10 -0
  60. data/ext/cached/ruby-1.8.3/internal/node/node_type_descrip.c +154 -0
  61. data/ext/cached/ruby-1.8.3/internal/node/nodeinfo.c +5733 -0
  62. data/ext/cached/ruby-1.8.3/internal/node/nodeinfo.h +69 -0
  63. data/ext/cached/ruby-1.8.3/internal/proc/block.h +32 -0
  64. data/ext/cached/ruby-1.8.3/internal/tag/tag.h +16 -0
  65. data/ext/cached/ruby-1.8.3/internal/vm/instruction/insns_info.c +39 -0
  66. data/ext/cached/ruby-1.8.3/internal/vm/instruction/insns_info.h +21 -0
  67. data/ext/cached/ruby-1.8.3/internal/vm/iseq/insns_info.inc +12 -0
  68. data/ext/cached/ruby-1.8.4/internal/binding/block.h +32 -0
  69. data/ext/cached/ruby-1.8.4/internal/method/method.h +20 -0
  70. data/ext/cached/ruby-1.8.4/internal/module/classpath.c +45 -0
  71. data/ext/cached/ruby-1.8.4/internal/module/classpath.h +17 -0
  72. data/ext/cached/ruby-1.8.4/internal/node/block.h +32 -0
  73. data/ext/cached/ruby-1.8.4/internal/node/global_entry.h +10 -0
  74. data/ext/cached/ruby-1.8.4/internal/node/node_type_descrip.c +154 -0
  75. data/ext/cached/ruby-1.8.4/internal/node/nodeinfo.c +5733 -0
  76. data/ext/cached/ruby-1.8.4/internal/node/nodeinfo.h +69 -0
  77. data/ext/cached/ruby-1.8.4/internal/proc/block.h +32 -0
  78. data/ext/cached/ruby-1.8.4/internal/tag/tag.h +16 -0
  79. data/ext/cached/ruby-1.8.4/internal/vm/instruction/insns_info.c +39 -0
  80. data/ext/cached/ruby-1.8.4/internal/vm/instruction/insns_info.h +21 -0
  81. data/ext/cached/ruby-1.8.4/internal/vm/iseq/insns_info.inc +12 -0
  82. data/ext/cached/ruby-1.8.5/internal/binding/block.h +32 -0
  83. data/ext/cached/ruby-1.8.5/internal/method/method.h +20 -0
  84. data/ext/cached/ruby-1.8.5/internal/module/classpath.c +45 -0
  85. data/ext/cached/ruby-1.8.5/internal/module/classpath.h +17 -0
  86. data/ext/cached/ruby-1.8.5/internal/node/block.h +32 -0
  87. data/ext/cached/ruby-1.8.5/internal/node/global_entry.h +10 -0
  88. data/ext/cached/ruby-1.8.5/internal/node/node_type_descrip.c +154 -0
  89. data/ext/cached/ruby-1.8.5/internal/node/nodeinfo.c +5732 -0
  90. data/ext/cached/ruby-1.8.5/internal/node/nodeinfo.h +67 -0
  91. data/ext/cached/ruby-1.8.5/internal/proc/block.h +32 -0
  92. data/ext/cached/ruby-1.8.5/internal/tag/tag.h +16 -0
  93. data/ext/cached/ruby-1.8.5/internal/vm/instruction/insns_info.c +39 -0
  94. data/ext/cached/ruby-1.8.5/internal/vm/instruction/insns_info.h +21 -0
  95. data/ext/cached/ruby-1.8.5/internal/vm/iseq/insns_info.inc +12 -0
  96. data/ext/cached/ruby-1.8.6/internal/binding/block.h +32 -0
  97. data/ext/cached/ruby-1.8.6/internal/method/method.h +20 -0
  98. data/ext/cached/ruby-1.8.6/internal/module/classpath.c +45 -0
  99. data/ext/cached/ruby-1.8.6/internal/module/classpath.h +17 -0
  100. data/ext/cached/ruby-1.8.6/internal/node/block.h +32 -0
  101. data/ext/cached/ruby-1.8.6/internal/node/global_entry.h +10 -0
  102. data/ext/cached/ruby-1.8.6/internal/node/node_type_descrip.c +154 -0
  103. data/ext/cached/ruby-1.8.6/internal/node/nodeinfo.c +5732 -0
  104. data/ext/cached/ruby-1.8.6/internal/node/nodeinfo.h +67 -0
  105. data/ext/cached/ruby-1.8.6/internal/proc/block.h +32 -0
  106. data/ext/cached/ruby-1.8.6/internal/tag/tag.h +16 -0
  107. data/ext/cached/ruby-1.8.6/internal/vm/instruction/insns_info.c +39 -0
  108. data/ext/cached/ruby-1.8.6/internal/vm/instruction/insns_info.h +21 -0
  109. data/ext/cached/ruby-1.8.6/internal/vm/iseq/insns_info.inc +12 -0
  110. data/ext/cached/ruby-1.8.7/internal/binding/block.h +32 -0
  111. data/ext/cached/ruby-1.8.7/internal/method/method.h +20 -0
  112. data/ext/cached/ruby-1.8.7/internal/module/classpath.c +45 -0
  113. data/ext/cached/ruby-1.8.7/internal/module/classpath.h +17 -0
  114. data/ext/cached/ruby-1.8.7/internal/node/block.h +32 -0
  115. data/ext/cached/ruby-1.8.7/internal/node/global_entry.h +10 -0
  116. data/ext/cached/ruby-1.8.7/internal/node/node_type_descrip.c +154 -0
  117. data/ext/cached/ruby-1.8.7/internal/node/nodeinfo.c +5732 -0
  118. data/ext/cached/ruby-1.8.7/internal/node/nodeinfo.h +67 -0
  119. data/ext/cached/ruby-1.8.7/internal/proc/block.h +32 -0
  120. data/ext/cached/ruby-1.8.7/internal/tag/tag.h +16 -0
  121. data/ext/cached/ruby-1.8.7/internal/vm/instruction/insns_info.c +39 -0
  122. data/ext/cached/ruby-1.8.7/internal/vm/instruction/insns_info.h +21 -0
  123. data/ext/cached/ruby-1.8.7/internal/vm/iseq/insns_info.inc +12 -0
  124. data/ext/cached/ruby-1.9.0/internal/binding/block.h +12 -0
  125. data/ext/cached/ruby-1.9.0/internal/method/method.h +20 -0
  126. data/ext/cached/ruby-1.9.0/internal/module/classpath.c +42 -0
  127. data/ext/cached/ruby-1.9.0/internal/module/classpath.h +17 -0
  128. data/ext/cached/ruby-1.9.0/internal/node/block.h +12 -0
  129. data/ext/cached/ruby-1.9.0/internal/node/global_entry.h +10 -0
  130. data/ext/cached/ruby-1.9.0/internal/node/node_type_descrip.c +149 -0
  131. data/ext/cached/ruby-1.9.0/internal/node/nodeinfo.c +5579 -0
  132. data/ext/cached/ruby-1.9.0/internal/node/nodeinfo.h +70 -0
  133. data/ext/cached/ruby-1.9.0/internal/proc/block.h +12 -0
  134. data/ext/cached/ruby-1.9.0/internal/tag/tag.h +6 -0
  135. data/ext/cached/ruby-1.9.0/internal/vm/instruction/insns_info.c +5936 -0
  136. data/ext/cached/ruby-1.9.0/internal/vm/instruction/insns_info.h +891 -0
  137. data/ext/cached/ruby-1.9.0/internal/vm/iseq/insns_info.inc +700 -0
  138. data/ext/cached/ruby-1.9.0/internal/yarv-headers/debug.h +36 -0
  139. data/ext/cached/ruby-1.9.0/internal/yarv-headers/dln.h +41 -0
  140. data/ext/cached/ruby-1.9.0/internal/yarv-headers/encdb.h +147 -0
  141. data/ext/cached/ruby-1.9.0/internal/yarv-headers/eval_intern.h +221 -0
  142. data/ext/cached/ruby-1.9.0/internal/yarv-headers/gc.h +75 -0
  143. data/ext/cached/ruby-1.9.0/internal/yarv-headers/id.h +83 -0
  144. data/ext/cached/ruby-1.9.0/internal/yarv-headers/iseq.h +94 -0
  145. data/ext/cached/ruby-1.9.0/internal/yarv-headers/node.h +516 -0
  146. data/ext/cached/ruby-1.9.0/internal/yarv-headers/parse.h +303 -0
  147. data/ext/cached/ruby-1.9.0/internal/yarv-headers/regenc.h +207 -0
  148. data/ext/cached/ruby-1.9.0/internal/yarv-headers/regint.h +842 -0
  149. data/ext/cached/ruby-1.9.0/internal/yarv-headers/regparse.h +351 -0
  150. data/ext/cached/ruby-1.9.0/internal/yarv-headers/revision.h +1 -0
  151. data/ext/cached/ruby-1.9.0/internal/yarv-headers/thread_pthread.h +24 -0
  152. data/ext/cached/ruby-1.9.0/internal/yarv-headers/thread_win32.h +33 -0
  153. data/ext/cached/ruby-1.9.0/internal/yarv-headers/transcode_data.h +99 -0
  154. data/ext/cached/ruby-1.9.0/internal/yarv-headers/transdb.h +67 -0
  155. data/ext/cached/ruby-1.9.0/internal/yarv-headers/version.h +57 -0
  156. data/ext/cached/ruby-1.9.0/internal/yarv-headers/vm_core.h +663 -0
  157. data/ext/cached/ruby-1.9.0/internal/yarv-headers/vm_exec.h +187 -0
  158. data/ext/cached/ruby-1.9.0/internal/yarv-headers/vm_insnhelper.h +191 -0
  159. data/ext/cached/ruby-1.9.0/internal/yarv-headers/vm_opts.h +51 -0
  160. data/ext/cached/ruby-1.9.1/internal/binding/block.h +12 -0
  161. data/ext/cached/ruby-1.9.1/internal/method/method.h +20 -0
  162. data/ext/cached/ruby-1.9.1/internal/module/classpath.c +42 -0
  163. data/ext/cached/ruby-1.9.1/internal/module/classpath.h +17 -0
  164. data/ext/cached/ruby-1.9.1/internal/node/block.h +12 -0
  165. data/ext/cached/ruby-1.9.1/internal/node/global_entry.h +10 -0
  166. data/ext/cached/ruby-1.9.1/internal/node/node_type_descrip.c +149 -0
  167. data/ext/cached/ruby-1.9.1/internal/node/nodeinfo.c +5579 -0
  168. data/ext/cached/ruby-1.9.1/internal/node/nodeinfo.h +70 -0
  169. data/ext/cached/ruby-1.9.1/internal/proc/block.h +12 -0
  170. data/ext/cached/ruby-1.9.1/internal/tag/tag.h +6 -0
  171. data/ext/cached/ruby-1.9.1/internal/vm/instruction/insns_info.c +5936 -0
  172. data/ext/cached/ruby-1.9.1/internal/vm/instruction/insns_info.h +891 -0
  173. data/ext/cached/ruby-1.9.1/internal/vm/iseq/insns_info.inc +700 -0
  174. data/ext/cached/ruby-1.9.1/internal/yarv-headers/debug.h +36 -0
  175. data/ext/cached/ruby-1.9.1/internal/yarv-headers/dln.h +41 -0
  176. data/ext/cached/ruby-1.9.1/internal/yarv-headers/encdb.h +147 -0
  177. data/ext/cached/ruby-1.9.1/internal/yarv-headers/eval_intern.h +209 -0
  178. data/ext/cached/ruby-1.9.1/internal/yarv-headers/gc.h +75 -0
  179. data/ext/cached/ruby-1.9.1/internal/yarv-headers/id.h +184 -0
  180. data/ext/cached/ruby-1.9.1/internal/yarv-headers/iseq.h +94 -0
  181. data/ext/cached/ruby-1.9.1/internal/yarv-headers/node.h +516 -0
  182. data/ext/cached/ruby-1.9.1/internal/yarv-headers/parse.h +303 -0
  183. data/ext/cached/ruby-1.9.1/internal/yarv-headers/regenc.h +207 -0
  184. data/ext/cached/ruby-1.9.1/internal/yarv-headers/regint.h +842 -0
  185. data/ext/cached/ruby-1.9.1/internal/yarv-headers/regparse.h +351 -0
  186. data/ext/cached/ruby-1.9.1/internal/yarv-headers/revision.h +1 -0
  187. data/ext/cached/ruby-1.9.1/internal/yarv-headers/thread_pthread.h +24 -0
  188. data/ext/cached/ruby-1.9.1/internal/yarv-headers/thread_win32.h +33 -0
  189. data/ext/cached/ruby-1.9.1/internal/yarv-headers/transcode_data.h +99 -0
  190. data/ext/cached/ruby-1.9.1/internal/yarv-headers/transdb.h +85 -0
  191. data/ext/cached/ruby-1.9.1/internal/yarv-headers/version.h +60 -0
  192. data/ext/cached/ruby-1.9.1/internal/yarv-headers/vm_core.h +655 -0
  193. data/ext/cached/ruby-1.9.1/internal/yarv-headers/vm_exec.h +187 -0
  194. data/ext/cached/ruby-1.9.1/internal/yarv-headers/vm_insnhelper.h +194 -0
  195. data/ext/cached/ruby-1.9.1/internal/yarv-headers/vm_opts.h +51 -0
  196. data/ext/internal/binding/binding.c +45 -0
  197. data/ext/internal/binding/block.h.rpp +44 -0
  198. data/ext/internal/binding/extconf.rb +6 -0
  199. data/ext/internal/method/extconf.rb +8 -0
  200. data/ext/internal/method/method.c +269 -0
  201. data/ext/internal/method/method.h.rpp +58 -0
  202. data/ext/internal/module/classpath.c.rpp +29 -0
  203. data/ext/internal/module/classpath.h.rpp +36 -0
  204. data/ext/internal/module/extconf.rb +11 -0
  205. data/ext/internal/module/module.c +797 -0
  206. data/ext/internal/module/module.h +7 -0
  207. data/ext/internal/node/block.h.rpp +44 -0
  208. data/ext/internal/node/builtins.h +41 -0
  209. data/ext/internal/node/extconf.rb +66 -0
  210. data/ext/internal/node/global_entry.h.rpp +26 -0
  211. data/ext/internal/node/node.c +1147 -0
  212. data/ext/internal/node/node_type_descrip.c.rpp +72 -0
  213. data/ext/internal/node/node_type_descrip.h +17 -0
  214. data/ext/internal/node/node_type_descrip.rb +39 -0
  215. data/ext/internal/node/nodeinfo.c.rpp +587 -0
  216. data/ext/internal/node/nodeinfo.h.rpp +30 -0
  217. data/ext/internal/node/nodes.rb +78 -0
  218. data/ext/internal/node/read_node_h.rb +34 -0
  219. data/ext/internal/node/ruby_internal_node.h +31 -0
  220. data/ext/internal/noex/extconf.rb +6 -0
  221. data/ext/internal/noex/noex.c +44 -0
  222. data/ext/internal/object/extconf.rb +4 -0
  223. data/ext/internal/object/object.c +75 -0
  224. data/ext/internal/proc/block.h.rpp +44 -0
  225. data/ext/internal/proc/extconf.rb +9 -0
  226. data/ext/internal/proc/proc.c +331 -0
  227. data/ext/internal/tag/extconf.rb +3 -0
  228. data/ext/internal/tag/tag.c +17 -0
  229. data/ext/internal/tag/tag.h.rpp +22 -0
  230. data/ext/internal/thread/extconf.rb +3 -0
  231. data/ext/internal/thread/thread.c +107 -0
  232. data/ext/internal/vm/constants/constants.c +33 -0
  233. data/ext/internal/vm/constants/extconf.rb +3 -0
  234. data/ext/internal/vm/control_frame/control_frame.c +185 -0
  235. data/ext/internal/vm/control_frame/control_frame.h +18 -0
  236. data/ext/internal/vm/control_frame/extconf.rb +3 -0
  237. data/ext/internal/vm/extconf.rb +3 -0
  238. data/ext/internal/vm/inline_cache/extconf.rb +6 -0
  239. data/ext/internal/vm/inline_cache/inline_cache.c +79 -0
  240. data/ext/internal/vm/instruction/extconf.rb +6 -0
  241. data/ext/internal/vm/instruction/insns_info.c.rpp +213 -0
  242. data/ext/internal/vm/instruction/insns_info.h.rpp +53 -0
  243. data/ext/internal/vm/instruction/instruction.c +78 -0
  244. data/ext/internal/vm/instruction/instruction.h +10 -0
  245. data/ext/internal/vm/iseq/extconf.rb +7 -0
  246. data/ext/internal/vm/iseq/insns_info.inc.rpp +30 -0
  247. data/ext/internal/vm/iseq/internal_iseq.h +9 -0
  248. data/ext/internal/vm/iseq/iseq.c +555 -0
  249. data/ext/internal/vm/vm.c +55 -0
  250. data/ext/mkmf-ruby-internal.rb +111 -0
  251. data/ext/ruby_source_dir.rb +24 -0
  252. data/ext/rubypp.rb +97 -0
  253. data/generate_rdoc.rb +33 -0
  254. data/lib/internal/binding.rb +1 -0
  255. data/lib/internal/classtree.rb +55 -0
  256. data/lib/internal/debug.rb +16 -0
  257. data/lib/internal/method.rb +1 -0
  258. data/lib/internal/method/as_code.rb +33 -0
  259. data/lib/internal/method/as_expression.rb +34 -0
  260. data/lib/internal/method/signature.rb +442 -0
  261. data/lib/internal/module.rb +1 -0
  262. data/lib/internal/module/as_code.rb +45 -0
  263. data/lib/internal/node.rb +3 -0
  264. data/lib/internal/node/as_code.rb +233 -0
  265. data/lib/internal/node/as_expression.rb +619 -0
  266. data/lib/internal/node/dump.rb +53 -0
  267. data/lib/internal/node/pp.rb +72 -0
  268. data/lib/internal/node/to_a.rb +52 -0
  269. data/lib/internal/noex.rb +1 -0
  270. data/lib/internal/obfusc.rb +57 -0
  271. data/lib/internal/object.rb +1 -0
  272. data/lib/internal/object/as_code.rb +10 -0
  273. data/lib/internal/proc.rb +1 -0
  274. data/lib/internal/proc/as_code.rb +21 -0
  275. data/lib/internal/proc/as_expression.rb +14 -0
  276. data/lib/internal/proc/signature.rb +184 -0
  277. data/lib/internal/tag.rb +1 -0
  278. data/lib/internal/thread.rb +1 -0
  279. data/lib/internal/vm.rb +1 -0
  280. data/lib/internal/vm/bytedecoder.rb +866 -0
  281. data/lib/internal/vm/constants.rb +1 -0
  282. data/lib/internal/vm/control_frame.rb +1 -0
  283. data/lib/internal/vm/inline_cache.rb +1 -0
  284. data/lib/internal/vm/instruction.rb +1 -0
  285. data/lib/internal/vm/iseq.rb +1 -0
  286. data/lib/internal/vm/iseq/as_code.rb +27 -0
  287. data/lib/internal/vm/iseq/as_expression.rb +26 -0
  288. data/metaconfig +19 -0
  289. data/post-config.rb +1 -0
  290. data/post-install.rb +4 -0
  291. data/post-setup.rb +7 -0
  292. data/pre-config.rb +96 -0
  293. data/pre-install.rb +13 -0
  294. data/pre-setup.rb +8 -0
  295. data/run_tests.rb +26 -0
  296. data/setup.rb +1599 -0
  297. data/test/expression_samples.rb +160 -0
  298. data/test/node_samples.rb +122 -0
  299. data/test/test_as_code.rb +261 -0
  300. data/test/test_as_expression.rb +229 -0
  301. data/test/test_dump_class.rb +187 -0
  302. data/test/test_dump_method.rb +144 -0
  303. data/test/test_dump_proc.rb +118 -0
  304. data/test/test_helpers.rb +61 -0
  305. data/test/test_method.rb +72 -0
  306. data/test/test_methodsig.rb +267 -0
  307. data/test/test_module.rb +49 -0
  308. data/test/test_node.rb +77 -0
  309. data/test/test_proc.rb +47 -0
  310. metadata +377 -0
@@ -0,0 +1,72 @@
1
+ #include "node_type_descrip.h"
2
+ #include "version.h"
3
+
4
+ Node_Type_Descrip node_type_descrips_unsorted[] = {
5
+ #ruby <<END
6
+ require 'node_type_descrip'
7
+ NODE_TYPE_DESCRIPS.each do |descrip|
8
+ name = descrip.name
9
+ node1 = descrip.node1
10
+ node2 = descrip.node2
11
+ node3 = descrip.node3
12
+
13
+ if name == 'ALLOCA' then
14
+ puts <<-END
15
+ #ifdef HAVE_NODE_ALLOCA
16
+ END
17
+ end
18
+
19
+ puts <<-END
20
+ { NODE_#{name}, NEN_#{node1}, NEN_#{node2}, NEN_#{node3}, "#{name}" },
21
+ END
22
+
23
+ if name == 'ALLOCA' then
24
+ puts <<-END
25
+ #endif
26
+ END
27
+ end
28
+ end
29
+ nil
30
+ END
31
+ };
32
+
33
+ static Node_Type_Descrip * node_type_descrips[NUM_NODE_TYPE_DESCRIPS];
34
+ static int node_type_descrips_initialized = 0;
35
+
36
+ static void init_node_type_descrips()
37
+ {
38
+ if(!node_type_descrips_initialized)
39
+ {
40
+ Node_Type_Descrip * descrip;
41
+ memset(node_type_descrips, 0, sizeof(node_type_descrips));
42
+ for(descrip = node_type_descrips_unsorted;
43
+ descrip->nt != NODE_LAST;
44
+ ++descrip)
45
+ {
46
+ if(node_type_descrips[descrip->nt])
47
+ {
48
+ rb_raise(rb_eRuntimeError, "duplicate entry for node type %d (%s is also %s)\n", descrip->nt, descrip->name, node_type_descrips[descrip->nt]->name);
49
+ }
50
+ else
51
+ {
52
+ node_type_descrips[descrip->nt] = descrip;
53
+ }
54
+ }
55
+ node_type_descrips_initialized = 1;
56
+ }
57
+ }
58
+
59
+ /* Given a node, find out the types of the three elements it contains */
60
+ Node_Type_Descrip const * node_type_descrip(enum node_type nt)
61
+ {
62
+ init_node_type_descrips();
63
+ if(node_type_descrips[nt])
64
+ {
65
+ return node_type_descrips[nt];
66
+ }
67
+ else
68
+ {
69
+ rb_raise(rb_eArgError, "Unknown node type %d", nt);
70
+ }
71
+ }
72
+
@@ -0,0 +1,17 @@
1
+ #ifndef node_type_descrip__h
2
+ #define node_type_descrip__h
3
+
4
+ #include "nodeinfo.h"
5
+
6
+ typedef struct {
7
+ enum node_type nt;
8
+ enum Node_Elem_Name n1;
9
+ enum Node_Elem_Name n2;
10
+ enum Node_Elem_Name n3;
11
+ char const * name;
12
+ } Node_Type_Descrip;
13
+
14
+ Node_Type_Descrip const * node_type_descrip(enum node_type nt);
15
+
16
+ #endif
17
+
@@ -0,0 +1,39 @@
1
+ $: << '../..'
2
+ require 'ruby_source_dir'
3
+ require 'nodes'
4
+
5
+ NODE_TYPE_DESCRIPS = []
6
+
7
+ ruby_version_code = RUBY_VERSION.gsub(/\./, '').to_i
8
+
9
+ nodes = Nodes.new
10
+ nodes.each do |name, node|
11
+ members = node['members'] || {}
12
+ version_range = node['version_range']
13
+ if version_range.includes?(ruby_version_code) then
14
+ node_name = node['name'].upcase
15
+ member_names = [
16
+ (members.keys[0] || 'NONE').upcase,
17
+ (members.keys[1] || 'NONE').upcase,
18
+ (members.keys[2] || 'NONE').upcase,
19
+ ]
20
+ NODE_TYPE_DESCRIPS << [ node_name, *member_names ]
21
+ end
22
+ end
23
+
24
+ NODE_TYPE_DESCRIPS.concat [
25
+ [ 'LAST' , 'NONE' , 'NONE' , 'NONE' ],
26
+ ]
27
+
28
+ Node_Type_Descrip = Struct.new(:name, :node1, :node2, :node3)
29
+
30
+ NODE_TYPE_DESCRIPS.map! { |x| Node_Type_Descrip.new(*x) }
31
+
32
+ NEN_TO_NODE_TYPE = {}
33
+ NODE_TYPE_DESCRIPS.each do |descrip|
34
+ [descrip.node1, descrip.node2, descrip.node3].each do |nen|
35
+ NEN_TO_NODE_TYPE[nen] ||= []
36
+ NEN_TO_NODE_TYPE[nen] << descrip.name
37
+ end
38
+ end
39
+
@@ -0,0 +1,587 @@
1
+ #include "nodeinfo.h"
2
+ #include "version.h"
3
+ #include "global_entry.h"
4
+ #include "builtins.h"
5
+
6
+ static int is_flip_state(ID id)
7
+ {
8
+ if(id == 0)
9
+ {
10
+ return 1;
11
+ }
12
+ #ifdef HAVE_RB_IS_LOCAL_ID
13
+ if(!rb_is_local_id(id))
14
+ {
15
+ return 1;
16
+ }
17
+ #endif
18
+ return 0;
19
+ }
20
+
21
+ static VALUE variable_names(ID * tbl)
22
+ {
23
+ if(tbl)
24
+ {
25
+ size_t j;
26
+ VALUE arr = rb_ary_new();
27
+ /* A tbl contains the names of local variables. The first
28
+ * element is the size of the table. The next two elements
29
+ * are $_ and $~. The rest of the elements are the names of
30
+ * the variables themselves.
31
+ */
32
+ for(j = 3; j <= tbl[0]; ++j)
33
+ {
34
+ if(is_flip_state(tbl[j]))
35
+ {
36
+ /* flip state */
37
+ rb_ary_push(arr, Qnil);
38
+ }
39
+ else
40
+ {
41
+ rb_ary_push(arr, ID2SYM(tbl[j]));
42
+ }
43
+ }
44
+ return arr;
45
+ }
46
+ else
47
+ {
48
+ return Qnil;
49
+ }
50
+ }
51
+
52
+ /* Every node contains three elements. This function takes any one of
53
+ * those elements, converts it to a Ruby object that can be dumped
54
+ * (since nodes can't be dumped), and puts the resulting object into
55
+ * node_hash.
56
+ */
57
+ VALUE dump_node_elem(enum Node_Elem_Name nen, NODE * n, VALUE node_hash)
58
+ {
59
+ switch(nen)
60
+ {
61
+ case NEN_NONE:
62
+ return Qnil;
63
+ #ruby <<END
64
+ require 'read_node_h'
65
+ require 'nodes'
66
+ require 'node_type_descrip'
67
+
68
+ NODEINFO.sort.each do |node_elem_name, node_elem_ref|
69
+ puts <<-END
70
+ case NEN_#{node_elem_name.upcase}:
71
+ END
72
+
73
+ if node_elem_name == "noex" or node_elem_name == "cflag" then
74
+ # noex and cflag point to an id but are really a long
75
+ node_elem_ref.sub!('id', 'cnt')
76
+ end
77
+
78
+ if node_elem_name == "rval" then
79
+ # rval points to a value but is really a node
80
+ node_elem_ref.sub!('value', 'node')
81
+ node_elem_name = '2nd'
82
+ end
83
+
84
+ case node_elem_ref
85
+ when /\.node/
86
+ puts <<-END
87
+ if(n->nd_#{node_elem_name})
88
+ {
89
+ int node_type;
90
+ if(#{node_elem_name == "next" ? 1 : 0} && nd_type(n) == NODE_OP_ASGN2)
91
+ {
92
+ /* All children of NODE_OP_ASGN2 are NODE_OP_ASGN2_ARG */
93
+ node_type = NODE_OP_ASGN2_ARG;
94
+ }
95
+ else
96
+ {
97
+ node_type = nd_type(n->nd_#{node_elem_name});
98
+ }
99
+
100
+ dump_node_or_iseq_to_hash(
101
+ (VALUE)n->nd_#{node_elem_name},
102
+ node_type,
103
+ node_hash);
104
+ return node_id(n->nd_#{node_elem_name});
105
+ }
106
+ else
107
+ {
108
+ return Qnil;
109
+ }
110
+ END
111
+ when /\.value$/
112
+ puts <<-END
113
+ switch(TYPE(n->nd_#{node_elem_name}))
114
+ {
115
+ case T_CLASS:
116
+ case T_MODULE:
117
+ {
118
+ /* When dumping a class, we dump just the name (otherwise we'd
119
+ * get multiple copies of the class each time we load a method
120
+ * on the other side).
121
+ */
122
+ VALUE klass = (VALUE)n->nd_#{node_elem_name};
123
+ VALUE path;
124
+ if(FL_TEST(klass, FL_SINGLETON))
125
+ {
126
+ VALUE singleton = rb_iv_get(klass, "__attached__");
127
+ path = rb_class_path(singleton);
128
+ }
129
+ else
130
+ {
131
+ path = rb_class_path(klass);
132
+ if(STR2CSTR(path)[0] == '#')
133
+ {
134
+ rb_raise(rb_eArgError, "cannot dump anonymous class");
135
+ }
136
+ }
137
+ return rb_assoc_new(
138
+ INT2NUM(((struct RBasic *)(n->nd_#{node_elem_name}))->flags),
139
+ path);
140
+ }
141
+
142
+ case T_NODE:
143
+ rb_raise(
144
+ rb_eRuntimeError,
145
+ "Wrong node elem #{node_elem_name} for node type %d",
146
+ nd_type(n));
147
+
148
+ default:
149
+ /* TODO: would like to dump flags, not type */
150
+ return rb_assoc_new(
151
+ INT2NUM(TYPE((VALUE)n->nd_#{node_elem_name})),
152
+ (VALUE)n->nd_#{node_elem_name});
153
+ }
154
+ END
155
+ when /\.id$/
156
+ puts <<-END
157
+ if(n->nd_#{node_elem_name} == 0)
158
+ {
159
+ return Qfalse;
160
+ }
161
+ else if(n->nd_#{node_elem_name} == 1)
162
+ {
163
+ return Qtrue;
164
+ }
165
+ else
166
+ {
167
+ return ID2SYM(n->nd_#{node_elem_name});
168
+ }
169
+ END
170
+ when /\.(argc|state|cnt)$/
171
+ puts <<-END
172
+ {
173
+ return LONG2NUM((long)n->nd_#{node_elem_name});
174
+ }
175
+ END
176
+ when /\.(tbl)$/
177
+ puts <<-END
178
+ {
179
+ VALUE v = variable_names(n->nd_#{node_elem_name});
180
+ return v;
181
+ }
182
+ END
183
+ when /\.(entry)$/
184
+ puts <<-END
185
+ if(n->nd_#{node_elem_name}->id == 0)
186
+ {
187
+ return Qfalse;
188
+ }
189
+ else
190
+ {
191
+ return ID2SYM(n->nd_#{node_elem_name}->id);
192
+ }
193
+ END
194
+ when /\.(cfunc)$/
195
+ puts <<-END
196
+ /* rb_funcall(rb_cObject, rb_intern("pp"), wrap_node(n), 0); */
197
+ rb_raise(rb_eArgError, "Cannot dump #{$1}");
198
+ END
199
+ end
200
+ end
201
+ nil
202
+ END
203
+ }
204
+ rb_raise(rb_eArgError, "Invalid Node_Elem_Name %d", nen);
205
+ }
206
+
207
+ void load_node_elem(enum Node_Elem_Name nen, VALUE v, NODE * n, VALUE node_hash, VALUE id_hash)
208
+ {
209
+ switch(nen)
210
+ {
211
+ case NEN_NONE:
212
+ return;
213
+ #ruby <<END
214
+ NODEINFO.sort.each do |node_elem_name, node_elem_ref|
215
+ puts <<-END
216
+ case NEN_#{node_elem_name.upcase}:
217
+ {
218
+ END
219
+
220
+ if node_elem_name == "noex" or node_elem_name == "cflag" then
221
+ # noex and cflag point to an id but are really a long
222
+ node_elem_ref.sub!('id', 'cnt')
223
+ end
224
+
225
+ if node_elem_name == "rval" then
226
+ # rval points to a value but is really a node
227
+ node_elem_ref.sub!('value', 'node')
228
+ node_elem_name = '2nd'
229
+ end
230
+
231
+ case node_elem_ref
232
+ when /\.node$/
233
+ puts <<-END
234
+ if(v == Qnil)
235
+ {
236
+ n->nd_#{node_elem_name} = 0;
237
+ }
238
+ else
239
+ {
240
+ VALUE nid = rb_hash_aref(id_hash, v);
241
+ if(RTEST(nid))
242
+ {
243
+ n->nd_#{node_elem_name} = id_to_node(nid);
244
+ }
245
+ else
246
+ {
247
+ n->#{node_elem_ref} = (NODE *)load_node_or_iseq_from_hash(
248
+ v, node_hash, id_hash);
249
+ if(nd_type(n->#{node_elem_ref}) == NODE_OP_ASGN2_ARG)
250
+ {
251
+ nd_set_type(n->#{node_elem_ref}, NODE_OP_ASGN2);
252
+ }
253
+ }
254
+ }
255
+ return;
256
+ END
257
+ when /\.value$/
258
+ puts <<-END
259
+ Check_Type(v, T_ARRAY);
260
+ if(RARRAY_LEN(v) != 2)
261
+ {
262
+ rb_raise(rb_eArgError, "wrong size for array");
263
+ }
264
+ int flags = NUM2INT(RARRAY_PTR(v)[0]);
265
+ switch(flags & T_MASK)
266
+ {
267
+ case T_CLASS:
268
+ case T_MODULE:
269
+ {
270
+ VALUE str = RARRAY_PTR(v)[1];
271
+ Check_Type(str, T_STRING);
272
+ VALUE klass = rb_path2class(STR2CSTR(str));
273
+ if(flags & FL_SINGLETON)
274
+ {
275
+ *(VALUE *)(&n->nd_#{node_elem_name}) =
276
+ rb_singleton_class(klass);
277
+ }
278
+ else
279
+ {
280
+ *(VALUE *)(&n->nd_#{node_elem_name}) =
281
+ klass;
282
+ }
283
+ break;
284
+ }
285
+ default:
286
+ *(VALUE *)(&n->nd_#{node_elem_name}) = RARRAY_PTR(v)[1];
287
+ break;
288
+ }
289
+ return;
290
+ END
291
+ when /\.id$/
292
+ puts <<-END
293
+ if(v == Qfalse)
294
+ {
295
+ n->nd_#{node_elem_name} = 0;
296
+ }
297
+ else if(v == Qfalse)
298
+ {
299
+ n->nd_#{node_elem_name} = 1;
300
+ }
301
+ else
302
+ {
303
+ n->nd_#{node_elem_name} = SYM2ID(v);
304
+ }
305
+ return;
306
+ END
307
+ when /\.(argc|state|cnt)$/
308
+ puts <<-END
309
+ n->nd_#{node_elem_name} = NUM2LONG(v);
310
+ return;
311
+ END
312
+ when /\.(tbl)$/
313
+ puts <<-END
314
+ if(v == Qnil)
315
+ {
316
+ n->nd_#{node_elem_name} = 0;
317
+ }
318
+ else
319
+ {
320
+ size_t len, j;
321
+ ID * tmp_tbl;
322
+
323
+ Check_Type(v, T_ARRAY);
324
+ len = RARRAY_LEN(v);
325
+ tmp_tbl = ALLOCA_N(ID, len + 3);
326
+ tmp_tbl[0] = (ID)(len + 2);
327
+ tmp_tbl[1] = (ID)('_');
328
+ tmp_tbl[2] = (ID)('~');
329
+ for(j = 0; j < len; ++j)
330
+ {
331
+ VALUE e = RARRAY_PTR(v)[j];
332
+ if(e == Qnil)
333
+ {
334
+ /* flip state */
335
+ tmp_tbl[j + 3] = 0;
336
+ }
337
+ else
338
+ {
339
+ tmp_tbl[j + 3] = SYM2ID(e);
340
+ }
341
+ }
342
+ n->nd_#{node_elem_name} = ALLOC_N(ID, len + 3);
343
+ memcpy(n->nd_#{node_elem_name}, tmp_tbl, sizeof(ID) * (len + 3));
344
+ }
345
+ return;
346
+ END
347
+ when /\.(entry)$/
348
+ puts <<-END
349
+ n->nd_#{node_elem_name} = rb_global_entry(SYM2ID(v));
350
+ return;
351
+ END
352
+ when /\.(cfunc)$/
353
+ puts <<-END
354
+ rb_raise(rb_eRuntimeError, "Cannot load #{$1}");
355
+ END
356
+ end
357
+ puts <<-END
358
+ }
359
+ END
360
+ end
361
+ nil
362
+ END
363
+ }
364
+ rb_raise(rb_eRuntimeError, "Internal error: invalid Node_Elem_Name %d", nen);
365
+ }
366
+
367
+ #ruby <<END
368
+ NODEINFO.sort.each do |node_elem_name, node_elem_ref|
369
+ # get rid of warning about unused functions
370
+ nen = node_elem_name.upcase
371
+ next if NEN_TO_NODE_TYPE[nen].nil?
372
+
373
+ if node_elem_name == "noex" or node_elem_name == "cflag" then
374
+ # noex and cflag point to an id but are really a long
375
+ node_elem_ref.sub!('id', 'cnt')
376
+ end
377
+
378
+ case node_elem_ref
379
+ when /\.node$/, /\.value$/
380
+ puts <<-END
381
+ /*
382
+ * Return the Node's _#{node_elem_name}_ member. The return type is
383
+ * either a Node or an Object.
384
+ */
385
+ static VALUE node_#{node_elem_name}(VALUE self)
386
+ {
387
+ NODE * n;
388
+ Data_Get_Struct(self, NODE, n);
389
+
390
+ if(TYPE(n->nd_#{node_elem_name}) == T_NODE)
391
+ {
392
+ if(#{node_elem_name == "next" ? 1 : 0} && nd_type(n) == NODE_OP_ASGN2)
393
+ {
394
+ return wrap_node_as(
395
+ (NODE *)n->nd_#{node_elem_name},
396
+ rb_cNodeSubclass[NODE_OP_ASGN2_ARG]);
397
+ }
398
+ else
399
+ {
400
+ return wrap_node((NODE *)n->nd_#{node_elem_name});
401
+ }
402
+ }
403
+ else
404
+ {
405
+ return (VALUE)n->nd_#{node_elem_name};
406
+ }
407
+ }
408
+ END
409
+ when /\.id$/
410
+ puts <<-END
411
+ /*
412
+ * Return the Node's _#{node_elem_name}_ member. The return type is a
413
+ * Symbol.
414
+ */
415
+ static VALUE node_#{node_elem_name}(VALUE self)
416
+ {
417
+ NODE * n;
418
+ Data_Get_Struct(self, NODE, n);
419
+ if(n->nd_#{node_elem_name} == 0)
420
+ {
421
+ return Qfalse;
422
+ }
423
+ else if(n->nd_#{node_elem_name} == 1)
424
+ {
425
+ return Qtrue;
426
+ }
427
+ else
428
+ {
429
+ return ID2SYM(n->nd_#{node_elem_name});
430
+ }
431
+ }
432
+ END
433
+ when /\.(argc|state|cnt)$/
434
+ puts <<-END
435
+ /*
436
+ * Return the Node's _#{node_elem_name}_ member. The return type is an
437
+ * Integer.
438
+ */
439
+ static VALUE node_#{node_elem_name}(VALUE self)
440
+ {
441
+ NODE * n;
442
+ Data_Get_Struct(self, NODE, n);
443
+ return LONG2NUM(n->nd_#{node_elem_name});
444
+ }
445
+ END
446
+ when /\.(tbl)$/
447
+ puts <<-END
448
+ /*
449
+ * Return the Node's _#{node_elem_name}_ member. The return value is an
450
+ * Array holding names of variables.
451
+ */
452
+ static VALUE node_#{node_elem_name}(VALUE self)
453
+ {
454
+ NODE * n;
455
+ Data_Get_Struct(self, NODE, n);
456
+ return variable_names(n->nd_#{node_elem_name});
457
+ }
458
+ END
459
+ when /\.(entry)$/
460
+ puts <<-END
461
+ /*
462
+ * Return the Node's _#{node_elem_name}_ member. The return type is
463
+ * either a Node or an Object.
464
+ */
465
+ static VALUE node_#{node_elem_name}(VALUE self)
466
+ {
467
+ NODE * n;
468
+ Data_Get_Struct(self, NODE, n);
469
+ if(n->nd_#{node_elem_name}->id == 0)
470
+ {
471
+ return Qfalse;
472
+ }
473
+ else
474
+ {
475
+ return ID2SYM(n->nd_#{node_elem_name}->id);
476
+ }
477
+ }
478
+ END
479
+ when /\.(cfunc)$/
480
+ puts <<-END
481
+ static VALUE node_#{node_elem_name}(VALUE self)
482
+ {
483
+ NODE * n;
484
+ Data_Get_Struct(self, NODE, n);
485
+ return LONG2NUM((long)(n->nd_#{node_elem_name}));
486
+ }
487
+ END
488
+ end
489
+ end
490
+ nil
491
+ END
492
+
493
+ /*
494
+ * Return an array of strings containing the names of the node class's
495
+ * members.
496
+ */
497
+ VALUE node_s_members(VALUE klass)
498
+ {
499
+ return rb_iv_get(klass, "__member__");
500
+ }
501
+
502
+ #ruby <<END
503
+ nodes = Nodes.new
504
+ nil
505
+ END
506
+
507
+ void define_node_subclass_methods()
508
+ {
509
+ /* For rdoc: rb_cNode = rb_define_class("Node", rb_cObject); */
510
+ VALUE rb_cNode = rb_const_get(rb_cObject, rb_intern("Node"));
511
+ VALUE members;
512
+ int j;
513
+
514
+ for(j = 0; j < NODE_LAST; ++j)
515
+ {
516
+ rb_cNodeSubclass[j] = Qnil;
517
+ }
518
+
519
+ #ruby <<END
520
+ ruby_version_code = RUBY_VERSION.gsub(/\./, '').to_i
521
+
522
+ nodes.each do |key, node|
523
+
524
+ version_range = node.version_range
525
+ next if not version_range.includes?(ruby_version_code)
526
+
527
+ node_type = "rb_c#{node.name}"
528
+
529
+ if node.doc then
530
+ doc = "\n /* Document-class: Node::#{node.name}"
531
+ node.doc.each_line do |line|
532
+ doc << "\n * #{line.chomp}"
533
+ end
534
+ doc << "\n */\n"
535
+ puts doc
536
+ else
537
+ $stderr.puts "WARNING: No documentation for #{node.name}"
538
+ end
539
+
540
+ if node.name == 'ALLOCA' then
541
+ puts <<-END
542
+ #ifdef HAVE_NODE_ALLOCA
543
+ END
544
+ end
545
+
546
+ puts <<-END
547
+ {
548
+ VALUE #{node_type} = rb_define_class_under(rb_cNode, "#{node.name}", rb_cNode);
549
+ members = rb_ary_new();
550
+ rb_cNodeSubclass[NODE_#{node.name}] = #{node_type};
551
+ rb_iv_set(#{node_type}, "__member__", members);
552
+ rb_iv_set(#{node_type}, "__type__", INT2NUM(NODE_#{node.name}));
553
+ rb_define_singleton_method(#{node_type}, "members", node_s_members, 0);
554
+ END
555
+ node.members.each do |member_name, member|
556
+ mname = member_name
557
+ mname = 'first' if member_name == '1st'
558
+ mname = 'second' if member_name == '2nd'
559
+ if member.doc then
560
+ doc = "\n /* Document-method: #{mname}"
561
+ member.doc.each_line do |line|
562
+ doc << "\n * #{line.chomp}"
563
+ end
564
+ doc << "\n */\n"
565
+ puts doc
566
+ end
567
+ puts <<-END
568
+ rb_define_method(#{node_type}, "#{mname}", node_#{member_name}, 0);
569
+ rb_ary_push(members, rb_str_new2("#{mname}"));
570
+ END
571
+ end
572
+ puts <<-END
573
+ }
574
+ END
575
+
576
+ if node.name == 'ALLOCA' then
577
+ puts <<-END
578
+ #endif
579
+ END
580
+ end
581
+
582
+ end
583
+ nil
584
+ END
585
+ }
586
+
587
+