ruby-internal 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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
+