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,6 @@
1
+ $: << '../../..'
2
+ require 'mkmf-ruby-internal'
3
+
4
+ have_header('vm.h')
5
+
6
+ create_ruby_internal_makefile 'internal/vm/instruction/instruction'
@@ -0,0 +1,213 @@
1
+ #include "insns_info.h"
2
+
3
+ #ifdef RUBY_VM
4
+
5
+ #ruby <<END
6
+ $:.unshift '../../..'
7
+ require 'ruby_source_dir'
8
+ insns_location = "#{RUBY_SOURCE_DIR}/insns.inc"
9
+ insns_info_location = "#{RUBY_SOURCE_DIR}/insns_info.inc"
10
+ insns_def_location = "#{RUBY_SOURCE_DIR}/insns.def"
11
+ iseq_c_location = "#{RUBY_SOURCE_DIR}/iseq.c"
12
+
13
+ INSTRUCTION_NAMES = []
14
+ record_instruction_names = false
15
+
16
+ [ insns_location, insns_info_location ].each do |file|
17
+ next if not File.exist?(file)
18
+
19
+ File.open(file) do |input|
20
+ while (line = input.gets) != nil do
21
+ line.chomp!
22
+ if line =~ /^\}/ then
23
+ record_instruction_names = false
24
+ end
25
+ if record_instruction_names then
26
+ name = line.chomp(',').gsub(/"/, '').lstrip.upcase
27
+ INSTRUCTION_NAMES.push(name) if name != ''
28
+ end
29
+ if line =~ /static.*insn_name_info.*=/ then
30
+ record_instruction_names = true
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ write = false
37
+
38
+ [ iseq_c_location ].each do |file|
39
+ next if not File.exist?(file)
40
+
41
+ File.open(file) do |input|
42
+ while (line = input.gets) != nil do
43
+ line.chomp!
44
+ case line
45
+ when /^make_compile_option\(/
46
+ puts 'void'
47
+ write = true
48
+ when /^static.*COMPILE_OPTION_DEFAULT.*=/
49
+ write = true
50
+ when /^static.*COMPILE_OPTION_FALSE.*;/
51
+ puts line
52
+ end
53
+ puts line if write
54
+ if line =~ /^\}/ then
55
+ write = false
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ INSTRUCTION_OPERAND_NAMES = {}
62
+
63
+ [ insns_def_location ].each do |file|
64
+ next if not File.exist?(file)
65
+
66
+ File.open(file) do |input|
67
+ if input.respond_to?(:set_encoding) then
68
+ input.set_encoding(Encoding::ASCII_8BIT)
69
+ end
70
+ while (line = input.gets) != nil do
71
+ line.chomp!
72
+ case line
73
+ when /^DEFINE_INSN/
74
+ name = input.gets.chomp
75
+ operand_line = input.gets.chomp
76
+ operand_line.gsub!(/\((.*)\)/, '\1')
77
+ operands = operand_line.split(',')
78
+ operand_names = operands.map { |x| x.split[1] }
79
+ INSTRUCTION_OPERAND_NAMES[name] = operand_names
80
+ end
81
+ end
82
+ end
83
+ end
84
+
85
+ nil
86
+ END
87
+
88
+ VALUE instruction_class[VM_INSTRUCTION_SIZE];
89
+
90
+ static ID operand_type_name_of(int operand_type)
91
+ {
92
+ char const * retval = "????";
93
+
94
+ switch(operand_type)
95
+ {
96
+ case TS_ISEQ: retval = "iseq"; break;
97
+ case TS_GENTRY: retval = "gentry"; break;
98
+ case TS_OFFSET: retval = "operand"; break;
99
+ case TS_DINDEX: retval = "dindex"; break;
100
+ case TS_VARIABLE: retval = "variable"; break;
101
+ case TS_CDHASH: retval = "cdhash"; break;
102
+ case TS_IC: retval = "ic"; break;
103
+ case TS_ID: retval = "id"; break;
104
+ case TS_VALUE: retval = "value"; break;
105
+ case TS_LINDEX: retval = "lindex"; break;
106
+ case TS_NUM: retval = "num"; break;
107
+ }
108
+
109
+ return rb_intern(retval);
110
+ }
111
+
112
+ #ruby <<END
113
+ INSTRUCTION_NAMES.each_with_index do |name, index|
114
+ $operand_names = INSTRUCTION_OPERAND_NAMES[name.downcase]
115
+
116
+ # 1 #<VM::Instruction::TRACE:0x402d991c @length=2, @operands=[1],
117
+ # @instruction=45, @operand_types=[:num], @name=:trace>
118
+ puts <<-END
119
+ /*
120
+ * call-seq:
121
+ * insn.length => Integer
122
+ *
123
+ * Returns the length of the instruction.
124
+ */
125
+ static VALUE insn_#{name}_length(VALUE self)
126
+ {
127
+ return LONG2NUM(insn_len(#{index}));
128
+ }
129
+
130
+ /*
131
+ * call-seq:
132
+ * insn.to_i => Integer
133
+ *
134
+ * Returns the numeric instruction number.
135
+ */
136
+ static VALUE insn_#{name}_to_i(VALUE self)
137
+ {
138
+ return NUM2LONG(#{index});
139
+ }
140
+
141
+ /*
142
+ * call-seq:
143
+ * insn.operand_types => Array of Symbol
144
+ *
145
+ * Returns an array containing the types of the operands.
146
+ */
147
+ static VALUE insn_#{name}_operand_types(VALUE self)
148
+ {
149
+ VALUE operand_types = rb_ary_new();
150
+ char const * s;
151
+
152
+ for(s = insn_op_types(#{index}); *s != '\\0'; ++s)
153
+ {
154
+ rb_ary_push(operand_types, ID2SYM(operand_type_name_of(*s)));
155
+ }
156
+
157
+ return operand_types;
158
+ }
159
+
160
+ /*
161
+ * call-seq:
162
+ * insn.name => Symbol
163
+ *
164
+ * Returns the name of the instruction.
165
+ */
166
+ static VALUE insn_#{name}_name(VALUE self)
167
+ {
168
+ return rb_intern("#{name}");
169
+ }
170
+
171
+ /*
172
+ * call-seq:
173
+ * insn.name => Symbol
174
+ *
175
+ * Returns the name of the operands for this instruction.
176
+ */
177
+ static VALUE insn_#{name}_operand_names(VALUE self)
178
+ {
179
+ VALUE v[] = {
180
+ #{$operand_names.map { |x| "ID2SYM(rb_intern(\"#{x}\"))" }.join(', ')}
181
+ };
182
+ return rb_ary_new4(#{$operand_names.size}, v);
183
+ }
184
+
185
+ END
186
+ end
187
+ nil
188
+ END
189
+
190
+ void define_instruction_subclasses(VALUE rb_cInstruction)
191
+ {
192
+ /* For rdoc: rb_cVM = rb_define_class("VM", rb_cObject); */
193
+ /* For rdoc: rb_cInstruction = rb_define_class_under(rb_cVM, "Instruction", rb_cObject); */
194
+
195
+ #ruby <<END
196
+ INSTRUCTION_NAMES.each_with_index do |name, index|
197
+ puts <<-END
198
+ {
199
+ VALUE rb_cInstruction_#{name} = instruction_class[#{index}] = rb_define_class_under(rb_cInstruction, "#{name}", rb_cInstruction);
200
+ rb_define_method(rb_cInstruction_#{name}, "length", insn_#{name}_length, 0);
201
+ rb_define_method(rb_cInstruction_#{name}, "to_i", insn_#{name}_to_i, 0);
202
+ rb_define_method(rb_cInstruction_#{name}, "operand_types", insn_#{name}_operand_types, 0);
203
+ rb_define_method(rb_cInstruction_#{name}, "operand_names", insn_#{name}_operand_names, 0);
204
+ rb_define_method(rb_cInstruction_#{name}, "name", insn_#{name}_name, 0);
205
+ }
206
+ END
207
+ end
208
+ nil
209
+ END
210
+ }
211
+
212
+ #endif
213
+
@@ -0,0 +1,53 @@
1
+ #ifndef insns_info__h_
2
+ #define insns_info__h_
3
+
4
+ #include "ruby.h"
5
+
6
+ #ifdef RUBY_VM
7
+
8
+ #include "vm_core.h"
9
+
10
+ #ifdef HAVE_VM_H
11
+ #include "vm.h"
12
+ #endif
13
+
14
+ #ruby <<END
15
+ $:.unshift '../../..'
16
+ require 'ruby_source_dir'
17
+ insns_location = "#{RUBY_SOURCE_DIR}/insns.inc"
18
+ insns_info_location = "#{RUBY_SOURCE_DIR}/insns_info.inc"
19
+ iseq_c_location = "#{RUBY_SOURCE_DIR}/iseq.c"
20
+
21
+ [ insns_location, insns_info_location ].each do |file|
22
+ next if not File.exist?(file)
23
+
24
+ File.open(file) do |input|
25
+ while (line = input.gets) != nil do
26
+ puts line
27
+ end
28
+ end
29
+ end
30
+
31
+ [ iseq_c_location ].each do |file|
32
+ next if not File.exist?(file)
33
+
34
+ File.open(file) do |input|
35
+ while (line = input.gets) != nil do
36
+ line.chomp!
37
+ if line =~ /^make_compile_option/ then
38
+ puts 'void'
39
+ puts "#{line};"
40
+ end
41
+ end
42
+ end
43
+ end
44
+ nil
45
+ END
46
+
47
+ extern VALUE instruction_class[VM_INSTRUCTION_SIZE];
48
+ void define_instruction_subclasses(VALUE rb_cInstruction);
49
+
50
+ #endif
51
+
52
+ #endif
53
+
@@ -0,0 +1,78 @@
1
+ #include "instruction.h"
2
+ #include "insns_info.h"
3
+ #include <ruby.h>
4
+
5
+ #ifndef RARRAY_LEN
6
+ #define RARRAY_LEN(a) RARRAY(a)->len
7
+ #endif
8
+
9
+ #ifndef RARRAY_PTR
10
+ #define RARRAY_PTR(a) RARRAY(a)->ptr
11
+ #endif
12
+
13
+ #ifdef RUBY_VM
14
+
15
+ /*
16
+ * call-seq:
17
+ * Instruction.new(*operands) => Instruction
18
+ *
19
+ * Create a new instruction with the given operands.
20
+ */
21
+ static VALUE instruction_initialize(int argc, VALUE * argv, VALUE self)
22
+ {
23
+ VALUE operands = rb_ary_new4(argc, argv);
24
+ rb_iv_set(self, "@operands", operands);
25
+ return Qnil;
26
+ }
27
+
28
+ /*
29
+ * call-seq:
30
+ * instruction.operands => Array
31
+ *
32
+ * Returns the instructions operands.
33
+ */
34
+ static VALUE instruction_operands(VALUE self)
35
+ {
36
+ return rb_iv_get(self, "@operands");
37
+ }
38
+
39
+ VALUE allocate_instruction(int instruction, VALUE args)
40
+ {
41
+ return rb_class_new_instance(
42
+ RARRAY_LEN(args),
43
+ RARRAY_PTR(args),
44
+ instruction_class[instruction]);
45
+ }
46
+
47
+ #endif
48
+
49
+ void Init_instruction(void)
50
+ {
51
+ #ifdef RUBY_VM
52
+ VALUE rb_cRubyVM;
53
+ VALUE rb_cInstruction;
54
+
55
+ if(!rb_const_defined(rb_cObject, rb_intern("RubyVM")))
56
+ {
57
+ rb_define_const(
58
+ rb_cObject,
59
+ "RubyVM",
60
+ rb_const_get(rb_cObject, rb_intern("VM")));
61
+ }
62
+
63
+ rb_cRubyVM = rb_define_class("RubyVM", rb_cObject);
64
+
65
+ rb_cInstruction = rb_define_class_under(rb_cRubyVM, "Instruction", rb_cObject);
66
+ rb_define_method(rb_cInstruction, "initialize", instruction_initialize, -1);
67
+ rb_define_method(rb_cInstruction, "operands", instruction_operands, 0);
68
+ rb_undef_method(rb_cInstruction, "new");
69
+
70
+ define_instruction_subclasses(rb_cInstruction);
71
+
72
+ /* Silence compiler warnings about unused static functions */
73
+ insn_name(0);
74
+ insn_op_type(0, 0);
75
+ insn_op_types(0);
76
+ #endif
77
+ }
78
+
@@ -0,0 +1,10 @@
1
+ #ifndef ruby_internal_vm__instruction__h_
2
+ #define ruby_internal_vm__instruction__h_
3
+
4
+ #ifdef RUBY_VM
5
+
6
+ VALUE allocate_instruction(int instruction, VALUE args);
7
+
8
+ #endif
9
+
10
+ #endif
@@ -0,0 +1,7 @@
1
+ $: << '../../..'
2
+ require 'mkmf-ruby-internal'
3
+
4
+ have_header('iseq.h')
5
+ have_header('ruby/node.h') or have_header('node.h')
6
+
7
+ create_ruby_internal_makefile 'internal/vm/iseq/iseq'
@@ -0,0 +1,30 @@
1
+ #ifndef ruby_internal_insns_info__inc_
2
+ #define ruby_internal_insns_info__inc_
3
+
4
+ #include <ruby.h>
5
+
6
+ #ifndef RUBY_VM
7
+ #include "env.h"
8
+ #endif
9
+
10
+ #ruby <<END
11
+ ruby_version_code = RUBY_VERSION.gsub(/\./, '').to_i
12
+
13
+ if ruby_version_code >= 190 then
14
+
15
+ $: << '../../..'
16
+ require 'ruby_source_dir'
17
+ insns_info_location = "#{RUBY_SOURCE_DIR}/insns_info.inc"
18
+
19
+ File.open(insns_info_location) do |input|
20
+ input.each_line do |line|
21
+ puts line
22
+ end
23
+ end
24
+ end
25
+
26
+ nil
27
+ END
28
+
29
+ #endif
30
+
@@ -0,0 +1,9 @@
1
+ #ifndef ruby_internal_vm__internal_iseq_h_
2
+ #define ruby_internal_vm__internal_iseq_h_
3
+
4
+ #include <ruby.h>
5
+
6
+ void dump_iseq_to_hash(VALUE iseq, VALUE node_hash);
7
+ VALUE load_iseq_from_hash(VALUE iseq, VALUE orig_node_id, VALUE node_hash, VALUE id_hash);
8
+
9
+ #endif
@@ -0,0 +1,555 @@
1
+ #include "internal_iseq.h"
2
+ #include "insns_info.inc"
3
+
4
+ #include "internal/node/ruby_internal_node.h"
5
+ #include "internal/module/module.h"
6
+ #include "internal/vm/instruction/instruction.h"
7
+
8
+ #include <ruby.h>
9
+
10
+ #ifdef RUBY_VM
11
+
12
+ #include "vm_core.h"
13
+
14
+ #ifdef HAVE_ISEQ_H
15
+ #include "iseq.h"
16
+ #endif
17
+
18
+ #ifndef RARRAY_LEN
19
+ #define RARRAY_LEN(a) RARRAY(a)->len
20
+ #endif
21
+
22
+ #ifndef RARRAY_PTR
23
+ #define RARRAY_PTR(a) RARRAY(a)->ptr
24
+ #endif
25
+
26
+ // Defined but not declared by ruby
27
+ VALUE iseq_load(VALUE self, VALUE data, VALUE parent, VALUE opt);
28
+
29
+ static VALUE rb_cModulePlaceholder;
30
+
31
+ static VALUE rb_mMarshal;
32
+
33
+ static VALUE rb_cInlineCache;
34
+
35
+ static VALUE rb_cCatchTableEntry;
36
+
37
+ static VALUE marshal_dump(VALUE obj, VALUE limit)
38
+ {
39
+ return rb_funcall(rb_mMarshal, rb_intern("dump"), 2, obj, limit);
40
+ }
41
+
42
+ static VALUE marshal_load(VALUE obj)
43
+ {
44
+ return rb_funcall(rb_mMarshal, rb_intern("load"), 1, obj);
45
+ }
46
+
47
+ static rb_iseq_t *
48
+ iseq_check(VALUE val)
49
+ {
50
+ rb_iseq_t *iseq;
51
+ if(!rb_obj_is_kind_of(val, rb_cISeq))
52
+ {
53
+ rb_raise(
54
+ rb_eTypeError,
55
+ "Expected VM::InstructionSequence, but got %s",
56
+ rb_class2name(CLASS_OF(val)));
57
+ }
58
+ GetISeqPtr(val, iseq);
59
+ if (!iseq->name) {
60
+ rb_raise(rb_eTypeError, "uninitialized InstructionSequence");
61
+ }
62
+ return iseq;
63
+ }
64
+
65
+ /* call-seq:
66
+ * iseq.self => VM::InstructionSequence
67
+ *
68
+ * Returns the self member of the instruction sequence.
69
+ */
70
+ static VALUE iseq_self(VALUE self)
71
+ {
72
+ rb_iseq_t * iseqdat = iseq_check(self);
73
+ return iseqdat->self;
74
+ }
75
+
76
+ /* call-seq:
77
+ * iseq.parent_iseq => VM::InstructionSequence or nil
78
+ *
79
+ * Returns the parent instruction sequence.
80
+ */
81
+ static VALUE iseq_parent_iseq(VALUE self)
82
+ {
83
+ rb_iseq_t * iseqdat = iseq_check(self);
84
+ rb_iseq_t * parent = iseqdat->parent_iseq;
85
+ if(parent)
86
+ {
87
+ return parent->self;
88
+ }
89
+ else
90
+ {
91
+ return Qnil;
92
+ }
93
+ }
94
+
95
+ /* call-seq:
96
+ * iseq.local_iseq => VM::InstructionSequence or nil
97
+ *
98
+ * Returns the instruction sequence that contains the local variables.
99
+ */
100
+ static VALUE iseq_local_iseq(VALUE self)
101
+ {
102
+ rb_iseq_t * iseqdat = iseq_check(self);
103
+ rb_iseq_t * local_iseq = iseqdat->local_iseq;
104
+ if(local_iseq)
105
+ {
106
+ return local_iseq->self;
107
+ }
108
+ else
109
+ {
110
+ return Qnil;
111
+ }
112
+ }
113
+ /* call-seq:
114
+ * iseq.name => String
115
+ *
116
+ * Returns the name of the instruction sequence.
117
+ */
118
+ static VALUE iseq_name(VALUE self)
119
+ {
120
+ rb_iseq_t *iseqdat = iseq_check(self);
121
+ return iseqdat->name;
122
+ }
123
+
124
+ /* call-seq:
125
+ * iseq.filename => String
126
+ *
127
+ * Returns the filename of the instruction sequence.
128
+ */
129
+ static VALUE iseq_filename(VALUE self)
130
+ {
131
+ rb_iseq_t *iseqdat = iseq_check(self);
132
+ return iseqdat->filename;
133
+ }
134
+
135
+ /* call-seq:
136
+ * iseq.local_table => String
137
+ *
138
+ * Returns the sequence's local table.
139
+ */
140
+ static VALUE iseq_local_table(VALUE self)
141
+ {
142
+ rb_iseq_t *iseqdat = iseq_check(self);
143
+ VALUE ary = rb_ary_new();
144
+ int j;
145
+
146
+ for(j = 0; j < iseqdat->local_table_size; ++j)
147
+ {
148
+ ID id = iseqdat->local_table[j];
149
+ if(rb_id2name(id))
150
+ {
151
+ rb_ary_push(ary, ID2SYM(id));
152
+ }
153
+ else
154
+ {
155
+ // Temporary
156
+ rb_ary_push(ary, Qnil);
157
+ }
158
+ }
159
+
160
+ return ary;
161
+ }
162
+
163
+ /* call-seq:
164
+ * iseq.argc => String
165
+ *
166
+ * Returns the number of non-optional arguments.
167
+ */
168
+ static VALUE iseq_argc(VALUE self)
169
+ {
170
+ rb_iseq_t *iseqdat = iseq_check(self);
171
+ return INT2NUM(iseqdat->argc);
172
+ }
173
+
174
+ /* call-seq:
175
+ * iseq.arg_simple => true or false
176
+ *
177
+ * Returns true if this sequence takes only simple (non-rest, non-opt,
178
+ * non-block) args.
179
+ */
180
+ static VALUE iseq_arg_simple(VALUE self)
181
+ {
182
+ rb_iseq_t *iseqdat = iseq_check(self);
183
+ return iseqdat->arg_simple ? Qtrue : Qfalse;
184
+ }
185
+
186
+ /* call-seq:
187
+ * iseq.arg_rest => true or false
188
+ *
189
+ * Returns the index of the rest (*x) arg.
190
+ */
191
+ static VALUE iseq_arg_rest(VALUE self)
192
+ {
193
+ rb_iseq_t *iseqdat = iseq_check(self);
194
+ return INT2NUM(iseqdat->arg_rest);
195
+ }
196
+
197
+ /* call-seq:
198
+ * iseq.arg_block => true or false
199
+ *
200
+ * Returns the index of the block (&x) arg.
201
+ */
202
+ static VALUE iseq_arg_block(VALUE self)
203
+ {
204
+ rb_iseq_t *iseqdat = iseq_check(self);
205
+ return INT2NUM(iseqdat->arg_block);
206
+ }
207
+
208
+ /* call-seq:
209
+ * iseq.arg_opt_table => Array of Integer
210
+ *
211
+ * Returns optional argument table. The value in the table represent
212
+ * the index into the instruction sequence of the code to set the
213
+ * optional argument. The last element is the index of the start of the
214
+ * code sequence.
215
+ */
216
+ static VALUE iseq_arg_opt_table(VALUE self)
217
+ {
218
+ rb_iseq_t *iseqdat = iseq_check(self);
219
+ VALUE ary = rb_ary_new();
220
+ int j;
221
+
222
+ for(j = 0; j < iseqdat->arg_opts; ++j)
223
+ {
224
+ rb_ary_push(ary, INT2NUM(iseqdat->arg_opt_table[j]));
225
+ }
226
+
227
+ return ary;
228
+ }
229
+
230
+ /* call-seq:
231
+ * iseq.each(pc_start=0, &block) => nil
232
+ *
233
+ * Yields each instruction in the sequence.
234
+ *
235
+ * If pc_start is supplied, begins iteration at the given offset from
236
+ * the beginning of the sequence.
237
+ *
238
+ */
239
+ static VALUE iseq_each(int argc, VALUE * argv, VALUE self)
240
+ {
241
+ rb_iseq_t *iseqdat = iseq_check(self);
242
+ VALUE * seq;
243
+ VALUE pc_start_v = Qnil;
244
+ unsigned long pc_start = 0;
245
+
246
+ rb_scan_args(argc, argv, "01", &pc_start_v);
247
+
248
+ if(RTEST(pc_start_v))
249
+ {
250
+ pc_start = NUM2ULONG(pc_start_v);
251
+ }
252
+
253
+ for(seq = iseqdat->iseq + pc_start;
254
+ seq < iseqdat->iseq + iseqdat->iseq_size;
255
+ )
256
+ {
257
+ VALUE insn = *seq++;
258
+ int op_type_idx;
259
+ int len = insn_len(insn);
260
+ VALUE args = rb_ary_new();
261
+
262
+ for(op_type_idx = 0; op_type_idx < len-1; ++op_type_idx, ++seq)
263
+ {
264
+ switch(insn_op_type(insn, op_type_idx))
265
+ {
266
+ case TS_VALUE:
267
+ rb_ary_push(args, *seq);
268
+ break;
269
+
270
+ case TS_LINDEX:
271
+ case TS_DINDEX:
272
+ case TS_NUM:
273
+ rb_ary_push(args, INT2FIX(*seq));
274
+ break;
275
+
276
+ case TS_ISEQ:
277
+ {
278
+ rb_iseq_t * iseq = (rb_iseq_t *)*seq;
279
+ if(iseq)
280
+ {
281
+ rb_ary_push(args, iseq->self);
282
+ }
283
+ else
284
+ {
285
+ rb_ary_push(args, Qnil);
286
+ }
287
+ break;
288
+ }
289
+
290
+ case TS_GENTRY:
291
+ {
292
+ struct global_entry *entry = (struct global_entry *)*seq;
293
+ rb_ary_push(args, ID2SYM(rb_intern(rb_id2name(entry->id))));
294
+ break;
295
+ }
296
+
297
+ case TS_OFFSET:
298
+ rb_ary_push(args, LONG2NUM(*seq));
299
+ /* TODO */
300
+ break;
301
+
302
+ case TS_VARIABLE:
303
+ rb_ary_push(args, Qnil);
304
+ /* TODO */
305
+ break;
306
+
307
+ case TS_CDHASH:
308
+ rb_ary_push(args, Qnil);
309
+ /* TODO */
310
+ break;
311
+
312
+ case TS_IC:
313
+ {
314
+ NODE * ic = (NODE *)*seq;
315
+ rb_ary_push(args, wrap_node_as(ic, rb_cInlineCache));
316
+ break;
317
+ }
318
+
319
+ case TS_ID:
320
+ rb_ary_push(args, ID2SYM(*seq));
321
+ break;
322
+ }
323
+ }
324
+
325
+ rb_yield(allocate_instruction(insn, args));
326
+ }
327
+
328
+ return Qnil;
329
+ }
330
+
331
+ /* call-seq:
332
+ * iseq.insn_line(n) => Integer
333
+ *
334
+ * Returns the line number of the nth instruction in the sequence.
335
+ */
336
+ static VALUE iseq_insn_line(VALUE self, VALUE n)
337
+ {
338
+ rb_iseq_t *iseqdat = iseq_check(self);
339
+ unsigned long pos = NUM2LONG(n);
340
+ unsigned long i, size = iseqdat->insn_info_size;
341
+ struct iseq_insn_info_entry *iiary = iseqdat->insn_info_table;
342
+
343
+ for (i = 0; i < size; i++) {
344
+ if (iiary[i].position == pos) {
345
+ return INT2NUM(iiary[i].line_no);
346
+ }
347
+ }
348
+ return Qnil;
349
+ }
350
+
351
+ /* call-seq:
352
+ * iseq.catch_table => Array of CatchTableEntry
353
+ *
354
+ * Returns the catch table for the sequence
355
+ */
356
+ static VALUE iseq_catch_table(VALUE self)
357
+ {
358
+ rb_iseq_t *iseqdat = iseq_check(self);
359
+ unsigned long j;
360
+
361
+ VALUE catch_table = rb_ary_new();
362
+
363
+ for(j = 0; j < iseqdat->catch_table_size; ++j)
364
+ {
365
+ VALUE catch_table_entry = rb_struct_new(
366
+ rb_cCatchTableEntry,
367
+ iseqdat->catch_table[j].type,
368
+ iseqdat->catch_table[j].iseq,
369
+ ULONG2NUM(iseqdat->catch_table[j].start),
370
+ ULONG2NUM(iseqdat->catch_table[j].end),
371
+ ULONG2NUM(iseqdat->catch_table[j].cont),
372
+ ULONG2NUM(iseqdat->catch_table[j].sp));
373
+ rb_ary_push(catch_table, catch_table_entry);
374
+ }
375
+
376
+ return catch_table;
377
+ }
378
+
379
+ /* The putobject instruction takes a VALUE as a parameter. But if this
380
+ * value is a class, we'll end up trying to dump the class! That's
381
+ * probably not what we want, so we use a placeholder instead.
382
+ */
383
+ void convert_modules_to_placeholders(VALUE array)
384
+ {
385
+ int j;
386
+
387
+ for(j = 0; j < RARRAY_LEN(array); ++j)
388
+ {
389
+ VALUE v = RARRAY_PTR(array)[j];
390
+ if(TYPE(v) == T_ARRAY)
391
+ {
392
+ convert_modules_to_placeholders(v);
393
+ }
394
+ else if(TYPE(v) == T_MODULE || TYPE(v) == T_CLASS)
395
+ {
396
+ VALUE p = rb_class_new_instance(0, 0, rb_cModulePlaceholder);
397
+ VALUE sym = rb_mod_name(v);
398
+ rb_iv_set(p, "name", sym);
399
+ RARRAY_PTR(array)[j] = p;
400
+ }
401
+ }
402
+ }
403
+
404
+ void convert_placeholders_to_modules(VALUE array)
405
+ {
406
+ int j;
407
+
408
+ for(j = 0; j < RARRAY_LEN(array); ++j)
409
+ {
410
+ VALUE v = RARRAY_PTR(array)[j];
411
+ if(TYPE(v) == T_ARRAY)
412
+ {
413
+ convert_placeholders_to_modules(v);
414
+ }
415
+ else if(CLASS_OF(v) == rb_cModulePlaceholder)
416
+ {
417
+ VALUE sym = rb_ivar_get(v, rb_intern("name"));
418
+ VALUE klass = lookup_module(sym);
419
+ RARRAY_PTR(array)[j] = klass;
420
+ }
421
+ }
422
+ }
423
+
424
+ /*
425
+ * call-seq:
426
+ * iseq.dump(limit) => String
427
+ *
428
+ * Dumps VM::InstuctionSequence to a string (only available on YARV).
429
+ */
430
+ static VALUE iseq_marshal_dump(VALUE self, VALUE limit)
431
+ {
432
+ VALUE arr;
433
+
434
+ if(rb_safe_level() >= 4)
435
+ {
436
+ /* no access to potentially sensitive data from the sandbox */
437
+ rb_raise(rb_eSecurityError, "Insecure: can't dump iseq");
438
+ }
439
+
440
+ arr = rb_funcall(self, rb_intern("to_a"), 0);
441
+ convert_modules_to_placeholders(arr);
442
+
443
+ return marshal_dump(arr, limit);
444
+ }
445
+
446
+ /*
447
+ * call-seq:
448
+ * VM::InstructionSequence.load(String) => VM::InstructionSequence
449
+ *
450
+ * Load a VM::InstuctionSequence from a string (only available on YARV).
451
+ */
452
+ static VALUE iseq_marshal_load(VALUE klass, VALUE str)
453
+ {
454
+ VALUE arr;
455
+
456
+ if( rb_safe_level() >= 4
457
+ || (rb_safe_level() >= 1 && OBJ_TAINTED(str)))
458
+ {
459
+ /* no playing with knives in the sandbox */
460
+ rb_raise(rb_eSecurityError, "Insecure: can't load iseq");
461
+ }
462
+
463
+ arr = marshal_load(str);
464
+ convert_placeholders_to_modules(arr);
465
+
466
+ VALUE iseq = iseq_load(Qnil, arr, 0, Qnil);
467
+ return iseq;
468
+ }
469
+
470
+ void dump_iseq_to_hash(VALUE iseq, VALUE node_hash)
471
+ {
472
+ if(RTEST(rb_hash_aref(node_hash, rb_obj_id(iseq))))
473
+ {
474
+ return;
475
+ }
476
+
477
+ rb_hash_aset(node_hash, rb_obj_id(iseq), iseq);
478
+ }
479
+
480
+ VALUE load_iseq_from_hash(VALUE iseq, VALUE orig_node_id, VALUE node_hash, VALUE id_hash)
481
+ {
482
+ rb_hash_aset(id_hash, orig_node_id, rb_obj_id(iseq));
483
+ return iseq;
484
+ }
485
+
486
+ #endif
487
+
488
+ void Init_iseq(void)
489
+ {
490
+ #ifdef RUBY_VM
491
+ VALUE rb_cRubyVM;
492
+
493
+ rb_require("internal/node");
494
+ rb_require("internal/module");
495
+ rb_require("internal/vm/instruction");
496
+ rb_require("internal/vm/inline_cache");
497
+
498
+ rb_mMarshal = rb_const_get(rb_cObject, rb_intern("Marshal"));
499
+
500
+ rb_cModulePlaceholder = rb_define_class("ModulePlaceholder", rb_cObject);
501
+
502
+ if(!rb_const_defined(rb_cObject, rb_intern("RubyVM")))
503
+ {
504
+ rb_define_const(
505
+ rb_cObject,
506
+ "RubyVM",
507
+ rb_const_get(rb_cObject, rb_intern("VM")));
508
+ }
509
+
510
+ rb_cRubyVM = rb_define_class("RubyVM", rb_cObject);
511
+ rb_cInlineCache = rb_const_get(rb_cRubyVM, rb_intern("InlineCache"));
512
+
513
+ /* For rdoc: rb_cISeq = rb_define_class_under(rb_cRubyVM, "InstructionSequence", rb_cObject) */
514
+ rb_define_method(rb_cISeq, "self", iseq_self, 0);
515
+ rb_define_method(rb_cISeq, "parent_iseq", iseq_parent_iseq, 0);
516
+ rb_define_method(rb_cISeq, "local_iseq", iseq_local_iseq, 0);
517
+ rb_define_method(rb_cISeq, "name", iseq_name, 0);
518
+ rb_define_method(rb_cISeq, "filename", iseq_filename, 0);
519
+ rb_define_method(rb_cISeq, "local_table", iseq_local_table, 0);
520
+ rb_define_method(rb_cISeq, "argc", iseq_argc, 0);
521
+ rb_define_method(rb_cISeq, "arg_simple", iseq_arg_simple, 0);
522
+ rb_define_method(rb_cISeq, "arg_rest", iseq_arg_rest, 0);
523
+ rb_define_method(rb_cISeq, "arg_block", iseq_arg_block, 0);
524
+ rb_define_method(rb_cISeq, "arg_opt_table", iseq_arg_opt_table, 0);
525
+ rb_define_method(rb_cISeq, "each", iseq_each, -1);
526
+ rb_define_method(rb_cISeq, "insn_line", iseq_insn_line, 1);
527
+ rb_define_method(rb_cISeq, "catch_table", iseq_catch_table, 0);
528
+ rb_include_module(rb_cISeq, rb_mEnumerable);
529
+ rb_define_method(rb_cISeq, "_dump", iseq_marshal_dump, 1);
530
+ rb_define_singleton_method(rb_cISeq, "_load", iseq_marshal_load, 1);
531
+
532
+ rb_cCatchTableEntry = rb_struct_define(
533
+ 0,
534
+ "type",
535
+ "iseq",
536
+ "start",
537
+ "end",
538
+ "cont",
539
+ "sp",
540
+ 0);
541
+ rb_const_set(rb_cISeq, rb_intern("CatchTableEntry"), rb_cCatchTableEntry);
542
+
543
+ rb_const_set(rb_cISeq, rb_intern("CATCH_TYPE_RESCUE"), CATCH_TYPE_RESCUE);
544
+ rb_const_set(rb_cISeq, rb_intern("CATCH_TYPE_ENSURE"), CATCH_TYPE_ENSURE);
545
+ rb_const_set(rb_cISeq, rb_intern("CATCH_TYPE_RETRY"), CATCH_TYPE_RETRY);
546
+ rb_const_set(rb_cISeq, rb_intern("CATCH_TYPE_BREAK"), CATCH_TYPE_BREAK);
547
+ rb_const_set(rb_cISeq, rb_intern("CATCH_TYPE_REDO"), CATCH_TYPE_REDO);
548
+ rb_const_set(rb_cISeq, rb_intern("CATCH_TYPE_NEXT"), CATCH_TYPE_NEXT);
549
+
550
+ /* Prevent compiler warnings about unused static functions */
551
+ insn_name(0);
552
+ insn_op_types(0);
553
+ #endif
554
+ }
555
+