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,7 @@
1
+ #ifndef ruby_internal__module__h_
2
+ #define ruby_internal__module__h_
3
+
4
+ VALUE lookup_module(VALUE name);
5
+
6
+ #endif
7
+
@@ -0,0 +1,44 @@
1
+ #ifndef ruby_internal_block__h_
2
+ #define ruby_internal_block__h_
3
+
4
+ #include <ruby.h>
5
+
6
+ #ifndef RUBY_VM
7
+ #include "env.h"
8
+ #endif
9
+
10
+ #ruby <<END
11
+ $: << '../..'
12
+ require 'ruby_source_dir'
13
+ vm_c_location = "#{RUBY_SOURCE_DIR}/vm.c"
14
+ eval_c_location = "#{RUBY_SOURCE_DIR}/eval.c"
15
+
16
+ [ vm_c_location, eval_c_location ].each do |file|
17
+ next if not File.exist?(file)
18
+
19
+ File.open(file) do |eval_c|
20
+ write = false
21
+ stopwrite = false
22
+ while (line = eval_c.gets) != nil do
23
+ case line
24
+ when /^struct (BLOCK)/
25
+ write = true
26
+ stopwrite = false
27
+ when /^\}/
28
+ stopwrite = true
29
+ end
30
+ puts line if write
31
+ if write and stopwrite then
32
+ stopwrite = false
33
+ write = false
34
+ puts ''
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ nil
41
+ END
42
+
43
+ #endif
44
+
@@ -0,0 +1,41 @@
1
+ #ifndef BUILTINS_H
2
+ #define BUILTINS_H
3
+
4
+ #include "ruby.h"
5
+
6
+ /* Macros for manipulating builtins */
7
+
8
+ #ifndef RARRAY_LEN
9
+ #define RARRAY_LEN(a) RARRAY(a)->len
10
+ #endif
11
+
12
+ #ifndef RARRAY_PTR
13
+ #define RARRAY_PTR(a) RARRAY(a)->ptr
14
+ #endif
15
+
16
+ #ifndef RSTRING_LEN
17
+ #define RSTRING_LEN(a) RSTRING(a)->len
18
+ #endif
19
+
20
+ #ifndef RSTRING_PTR
21
+ #define RSTRING_PTR(a) RSTRING(a)->ptr
22
+ #endif
23
+
24
+ #ifndef RCLASS_SUPER
25
+ #define RCLASS_SUPER(c) RCLASS(c)->super
26
+ #endif
27
+
28
+ #ifndef RCLASS_IV_TBL
29
+ #define RCLASS_IV_TBL(c) RCLASS(c)->iv_tbl
30
+ #endif
31
+
32
+ #ifndef RCLASS_M_TBL
33
+ #define RCLASS_M_TBL(c) RCLASS(c)->m_tbl
34
+ #endif
35
+
36
+ #ifndef NEW_NODE
37
+ #define NEW_NODE(t,a0,a1,a2) \
38
+ rb_node_newnode((t),(VALUE)(a0),(VALUE)(a1),(VALUE)(a2))
39
+ #endif
40
+
41
+ #endif
@@ -0,0 +1,66 @@
1
+ $: << '../..'
2
+ require 'mkmf-ruby-internal'
3
+
4
+ module Kernel
5
+ if not method_defined?(:try_const)
6
+ alias_method :try_const, :try_constant
7
+ end
8
+
9
+ if not method_defined?(:checking_message)
10
+ def checking_message(checking_for, headers = nil, opt = "")
11
+ return checking_for
12
+ end
13
+ end
14
+
15
+ if not method_defined?(:have_const)
16
+ def have_const(const, headers = nil, opt = "", &b)
17
+ checking_for checking_message([*const].compact.join(' '), headers, opt) do
18
+ try_const(const, headers, opt, &b)
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ ruby_version_code = RUBY_VERSION.gsub(/\./, '').to_i
25
+
26
+ have_type('st_data_t', [ 'ruby.h', 'st.h' ]) or
27
+ have_type('st_data_t', [ 'ruby.h', 'ruby/st.h'])
28
+
29
+ have_const('NODE_ALLOCA', [ 'ruby.h', 'node.h' ]) or
30
+ have_const('NODE_ALLOCA', [ 'ruby.h', 'ruby/node.h' ])
31
+
32
+ have_func('rb_protect_inspect', 'ruby.h')
33
+ have_func('rb_obj_respond_to', 'ruby.h')
34
+ have_func('rb_define_alloc_func', 'ruby.h')
35
+ have_func('rb_is_local_id', 'ruby.h')
36
+ have_func('rb_source_filename', 'ruby.h')
37
+
38
+ checking_for("ruby_top_cref") do
39
+ if try_link(<<-END) then
40
+ #include <stdio.h>
41
+ extern void * ruby_top_cref;
42
+ int main() { printf("%p\\n", ruby_top_cref); return 0; }
43
+ END
44
+ $defs.push "-DHAVE_RUBY_TOP_CREF"
45
+ end
46
+ end
47
+
48
+ checking_for("ruby_cref") do
49
+ if try_link(<<-END) then
50
+ #include <stdio.h>
51
+ extern void * ruby_cref;
52
+ int main() { printf("%p\\n", ruby_cref); return 0; }
53
+ END
54
+ $defs.push "-DHAVE_RUBY_CREF"
55
+ end
56
+ end
57
+
58
+ have_header('iseq.h')
59
+
60
+ ruby_version_code = RUBY_VERSION.gsub(/\./, '').to_i
61
+ $CPPFLAGS << " -DRUBY_VERSION_CODE=#{ruby_version_code}"
62
+
63
+ have_header('ruby/node.h') or have_header('node.h')
64
+
65
+ create_ruby_internal_makefile 'internal/node/node'
66
+
@@ -0,0 +1,26 @@
1
+ #ifndef global_entry__h_
2
+ #define global_entry__h_
3
+
4
+ #ruby <<END
5
+ $: << '../..'
6
+ require 'ruby_source_dir'
7
+ variable_c_location = "#{RUBY_SOURCE_DIR}/variable.c"
8
+ File.open(variable_c_location) do |variable_c|
9
+ write = false
10
+ stopwrite = false
11
+ while (line = variable_c.gets) != nil do
12
+ case line
13
+ when /^struct global_entry/
14
+ write = true
15
+ stopwrite = false
16
+ when /^\}/
17
+ stopwrite = true if write
18
+ end
19
+ puts line if write
20
+ break if stopwrite
21
+ end
22
+ end
23
+ END
24
+
25
+ #endif
26
+
@@ -0,0 +1,1147 @@
1
+ #include "nodeinfo.h"
2
+ #include "ruby_internal_node.h"
3
+ #include "node_type_descrip.h"
4
+ #include "block.h"
5
+ #include "builtins.h"
6
+ #include "internal/vm/iseq/internal_iseq.h"
7
+
8
+ #include <ruby.h>
9
+
10
+ #ifdef RUBY_VM
11
+ #include <ruby/st.h>
12
+ #else
13
+ #include <rubysig.h>
14
+ #include <st.h>
15
+ #endif
16
+
17
+ #include <ctype.h>
18
+
19
+ #ifdef RUBY_VM
20
+ #include "eval_intern.h"
21
+ #endif
22
+
23
+ #ifdef HAVE_ISEQ_H
24
+ #include "iseq.h"
25
+ #endif
26
+
27
+ #ifndef RARRAY_LEN
28
+ #define RARRAY_LEN(a) RARRAY(a)->len
29
+ #endif
30
+
31
+ #ifndef RARRAY_PTR
32
+ #define RARRAY_PTR(a) RARRAY(a)->ptr
33
+ #endif
34
+
35
+ static VALUE rb_cNode = Qnil;
36
+ static VALUE rb_cNodeType = Qnil;
37
+ VALUE rb_cNodeSubclass[NODE_LAST];
38
+ static VALUE rb_mMarshal = Qnil;
39
+
40
+ #ifndef HAVE_TYPE_ST_DATA_T
41
+ typedef void st_data_t;
42
+ #endif
43
+
44
+ static VALUE wrapped_nodes = Qnil;
45
+
46
+ /* ---------------------------------------------------------------------
47
+ * Node helper functions
48
+ * ---------------------------------------------------------------------
49
+ */
50
+
51
+ static void wrapped_nodes_end_proc(VALUE data)
52
+ {
53
+ wrapped_nodes = Qnil;
54
+ }
55
+
56
+ static void mark_node(
57
+ void * data)
58
+ {
59
+ rb_gc_mark((VALUE)data);
60
+ }
61
+
62
+ static void free_node(
63
+ void * data)
64
+ {
65
+ VALUE key, node_id;
66
+
67
+ if(wrapped_nodes == Qnil)
68
+ {
69
+ /* We're finalizing at exit, so don't clean up */
70
+ return;
71
+ }
72
+
73
+ key = LONG2FIX((long)data / 4);
74
+ node_id = rb_hash_aref(wrapped_nodes, key);
75
+
76
+ if(NIL_P(node_id))
77
+ {
78
+ rb_bug("tried to free a node that wasn't wrapped!");
79
+ return;
80
+ }
81
+ rb_funcall(wrapped_nodes, rb_intern("delete"), 1, LONG2NUM((long)data / 4));
82
+ }
83
+
84
+ VALUE wrap_node_as(NODE * n, VALUE klass)
85
+ {
86
+ VALUE node_id;
87
+
88
+ if(!n)
89
+ {
90
+ return Qnil;
91
+ }
92
+
93
+ if(wrapped_nodes == Qnil)
94
+ {
95
+ /* We're finalizing at exit so we can't function properly */
96
+ rb_raise(rb_eRuntimeError, "Unable to wrap node during cleanup");
97
+ }
98
+
99
+ node_id = rb_hash_aref(wrapped_nodes, LONG2FIX((long)n / 4));
100
+
101
+ if(!NIL_P(node_id))
102
+ {
103
+ return (VALUE)(node_id ^ FIXNUM_FLAG);
104
+ }
105
+ else
106
+ {
107
+ VALUE node = Data_Wrap_Struct(klass, mark_node, free_node, n);
108
+ VALUE node_id = rb_obj_id(node);
109
+ rb_hash_aset(wrapped_nodes, LONG2FIX((long)n / 4), node_id);
110
+ return node;
111
+ }
112
+ }
113
+
114
+ VALUE wrap_node(NODE * n)
115
+ {
116
+ if(!n)
117
+ {
118
+ return Qnil;
119
+ }
120
+
121
+ if(nd_type(n) > NODE_LAST || rb_cNodeSubclass[nd_type(n)] == Qnil)
122
+ {
123
+ rb_raise(rb_eRuntimeError, "Unknown node type %d", nd_type(n));
124
+ }
125
+
126
+ return wrap_node_as(n, rb_cNodeSubclass[nd_type(n)]);
127
+ }
128
+
129
+ NODE * unwrap_node(VALUE r)
130
+ {
131
+ if(!RTEST(r))
132
+ {
133
+ return 0;
134
+ }
135
+ else
136
+ {
137
+ NODE * n;
138
+ if(TYPE(r) == 0)
139
+ {
140
+ rb_bug("Tried to unwrap recycled node");
141
+ }
142
+ if(!rb_obj_is_kind_of(r, rb_cNode))
143
+ {
144
+ rb_raise(rb_eTypeError, "Expected Node");
145
+ }
146
+ Data_Get_Struct(r, NODE, n);
147
+ return n;
148
+ }
149
+ }
150
+
151
+ /* ---------------------------------------------------------------------
152
+ * Marshalling
153
+ * ---------------------------------------------------------------------
154
+ */
155
+
156
+ VALUE marshal_dump(VALUE obj, VALUE limit)
157
+ {
158
+ return rb_funcall(rb_mMarshal, rb_intern("dump"), 2, obj, limit);
159
+ }
160
+
161
+ VALUE marshal_load(VALUE obj)
162
+ {
163
+ return rb_funcall(rb_mMarshal, rb_intern("load"), 1, obj);
164
+ }
165
+
166
+ /* ---------------------------------------------------------------------
167
+ * Node methods
168
+ * ---------------------------------------------------------------------
169
+ */
170
+
171
+ /*
172
+ * Document-class: Node
173
+ *
174
+ * Node is a wrapper for Ruby's Nodes, which are not objects. Nodes
175
+ * can be obtained from many of the other methods in the nodewrap
176
+ * library (see Method#body and Proc#body, for example).
177
+ */
178
+
179
+ #ifdef HAVE_RB_DEFINE_ALLOC_FUNC
180
+ /*
181
+ * call-seq:
182
+ * Node.allocate() => Node
183
+ *
184
+ * Allocate a new node.
185
+ */
186
+ static VALUE node_allocate(VALUE klass)
187
+ {
188
+ NODE * n = NEW_NIL();
189
+ return wrap_node(n);
190
+ }
191
+ #endif
192
+
193
+ /*
194
+ * call-seq:
195
+ * node.address() => Numeric
196
+ *
197
+ * Returns a node's address.
198
+ */
199
+ static VALUE node_address(VALUE self)
200
+ {
201
+ NODE * n;
202
+ Data_Get_Struct(self, NODE, n);
203
+ return ULONG2NUM((unsigned long)(n));
204
+ }
205
+
206
+ /*
207
+ * call-seq:
208
+ * node.flags() => Numeric
209
+ *
210
+ * Returns a node's flags.
211
+ */
212
+ static VALUE node_flags(VALUE self)
213
+ {
214
+ NODE * n;
215
+ Data_Get_Struct(self, NODE, n);
216
+ return INT2NUM(n->flags);
217
+ }
218
+
219
+ /*
220
+ * call-seq:
221
+ * node.nd_file => String or nil
222
+ *
223
+ * Returns the file the node is associated with
224
+ */
225
+ static VALUE node_nd_file(VALUE self)
226
+ {
227
+ NODE * n;
228
+ Data_Get_Struct(self, NODE, n);
229
+ #ifdef HAVE_RB_SOURCE_FILENAME
230
+ if(n->nd_file)
231
+ {
232
+ return rb_str_new2(n->nd_file);
233
+ }
234
+ else
235
+ {
236
+ return Qnil;
237
+ }
238
+ #else
239
+ /* nd_file has been removed in 1.9 */
240
+ return Qnil;
241
+ #endif
242
+ }
243
+
244
+ /*
245
+ * call-seq:
246
+ * node.nd_line => Numeric
247
+ *
248
+ * Returns the line number the node is associated with.
249
+ */
250
+ static VALUE node_nd_line(VALUE self)
251
+ {
252
+ NODE * n;
253
+ Data_Get_Struct(self, NODE, n);
254
+ return LONG2NUM(nd_line(n));
255
+ }
256
+
257
+ /*
258
+ * call-seq:
259
+ * node.nd_type => NodeType
260
+ *
261
+ * Returns a NodeType structure representing the type of the node.
262
+ */
263
+ static VALUE node_nd_type(VALUE self)
264
+ {
265
+ NODE * n;
266
+ const Node_Type_Descrip * descrip;
267
+ Data_Get_Struct(self, NODE, n);
268
+ rb_check_type((VALUE)(self), T_DATA);
269
+ descrip = node_type_descrip(nd_type(n));
270
+ return rb_struct_new(
271
+ rb_cNodeType,
272
+ rb_str_new2(descrip->name),
273
+ INT2NUM(descrip->nt));
274
+ }
275
+
276
+ VALUE node_id(NODE * n)
277
+ {
278
+ return rb_obj_id((VALUE)n);
279
+ }
280
+
281
+ NODE * id_to_node(VALUE id)
282
+ {
283
+ unsigned long n = NUM2INT(id);
284
+ return (NODE *)n;
285
+ }
286
+
287
+ /*
288
+ * call-seq:
289
+ * node.members => Array of String
290
+ *
291
+ * Return an array of strings containing the names of a node's
292
+ * members.
293
+ */
294
+ static VALUE node_members(VALUE node)
295
+ {
296
+ return node_s_members(rb_class_of(node));
297
+ }
298
+
299
+ /*
300
+ * call-seq:
301
+ * node[member] => Object
302
+ *
303
+ * Return the given member of a node.
304
+ */
305
+ static VALUE node_bracket(VALUE node, VALUE member)
306
+ {
307
+ ID id = SYMBOL_P(member)
308
+ ? SYM2ID(member)
309
+ : rb_intern(STR2CSTR(member));
310
+ return rb_funcall(node, id, 0);
311
+ }
312
+
313
+ #ifdef HAVE_RB_PROTECT_INSPECT
314
+ static VALUE node_inspect_protect(VALUE node)
315
+ #else
316
+ static VALUE node_inspect_protect(VALUE node, VALUE dummy, int recur)
317
+ #endif
318
+ {
319
+ VALUE str = rb_str_new2("#<");
320
+ rb_str_cat2(str, rb_class2name(CLASS_OF(node)));
321
+ rb_str_cat2(str, " ");
322
+ VALUE members = node_members(node);
323
+ int j;
324
+
325
+
326
+ for(j = 0; j < RARRAY_LEN(members); ++j)
327
+ {
328
+ VALUE name = RARRAY_PTR(members)[j];
329
+ VALUE value = node_bracket(node, name);
330
+ rb_str_append(str, name);
331
+ rb_str_cat2(str, "=");
332
+ if(TYPE(value) == T_NODE)
333
+ {
334
+ rb_str_append(str, rb_funcall(value, rb_intern("to_s"), 0));
335
+ }
336
+ else
337
+ {
338
+ rb_str_append(str, rb_funcall(value, rb_intern("inspect"), 0));
339
+ }
340
+ if(j != RARRAY_LEN(members) - 1)
341
+ {
342
+ rb_str_cat2(str, ", ");
343
+ }
344
+ }
345
+
346
+ rb_str_cat2(str, ">");
347
+
348
+ return str;
349
+ }
350
+
351
+ /*
352
+ * call-seq:
353
+ * node.inspect => String
354
+ *
355
+ * Returns a string representation of the node's data.
356
+ */
357
+ static VALUE node_inspect(VALUE node)
358
+ {
359
+ #ifdef HAVE_RB_PROTECT_INSPECT
360
+ if(rb_inspecting_p(node))
361
+ {
362
+ VALUE str = rb_str_new2("#<");
363
+ rb_str_cat2(str, rb_class2name(CLASS_OF(node)));
364
+ rb_str_cat2(str, ":...>");
365
+ return str;
366
+ }
367
+ else
368
+ {
369
+ return rb_protect_inspect(node_inspect_protect, node, 0);
370
+ }
371
+ #else
372
+ return rb_exec_recursive(node_inspect_protect, node, 0);
373
+ #endif
374
+ }
375
+
376
+ /*
377
+ * call-seq:
378
+ * node.nd_type => NodeType
379
+ *
380
+ * Returns a NodeType structure representing the type of the node.
381
+ */
382
+ static VALUE node_s_type(VALUE self)
383
+ {
384
+ const Node_Type_Descrip * descrip;
385
+ descrip = node_type_descrip(
386
+ NUM2INT(rb_iv_get(self, "__type__")));
387
+ return rb_struct_new(
388
+ rb_cNodeType,
389
+ rb_str_new2(descrip->name),
390
+ INT2NUM(descrip->nt));
391
+ }
392
+
393
+ /* ---------------------------------------------------------------------
394
+ * NodeType methods
395
+ * ---------------------------------------------------------------------
396
+ */
397
+
398
+ /*
399
+ * Document-class: NodeType
400
+ *
401
+ * NodeType is an abstraction for the C type of a node. It is a Struct
402
+ * which has two members, +name+ and +value+.
403
+ */
404
+
405
+ /*
406
+ * call-seq:
407
+ * node_type.name => String
408
+ *
409
+ * Returns the name of the node.
410
+ */
411
+ static VALUE node_type_to_s(VALUE node_type)
412
+ {
413
+ return rb_struct_getmember(node_type, rb_intern("name"));
414
+ }
415
+
416
+ /*
417
+ * call-seq:
418
+ * node_type.to_i => Numeric
419
+ *
420
+ * Returns an integer representing integer type of a node. This is the
421
+ * value you would see for the type of the node if you were examining it
422
+ * in gdb.
423
+ */
424
+ static VALUE node_type_to_i(VALUE node_type)
425
+ {
426
+ return rb_struct_getmember(node_type, rb_intern("value"));
427
+ }
428
+
429
+ /* ---------------------------------------------------------------------
430
+ * Node evaluation
431
+ * ---------------------------------------------------------------------
432
+ */
433
+
434
+ /* TODO: copied from proc.c */
435
+
436
+ #ifndef RUBY_VM
437
+
438
+ static VALUE create_proc(VALUE klass, VALUE binding, NODE * body, NODE * var)
439
+ {
440
+ /* Calling eval will do a security check */
441
+ VALUE new_proc = rb_funcall(
442
+ rb_cObject, rb_intern("eval"), 2, rb_str_new2("proc { }"), binding);
443
+ struct BLOCK * b;
444
+ Data_Get_Struct(new_proc, struct BLOCK, b);
445
+ b->body = body;
446
+ b->var = var;
447
+ RBASIC(new_proc)->klass = klass;
448
+ return new_proc;
449
+ }
450
+
451
+ #else
452
+
453
+ /* From iseq.c */
454
+ static rb_iseq_t *
455
+ iseq_check(VALUE val)
456
+ {
457
+ rb_iseq_t *iseq;
458
+ if(!rb_obj_is_kind_of(val, rb_cISeq))
459
+ {
460
+ rb_raise(
461
+ rb_eTypeError,
462
+ "Expected VM::InstructionSequence, but got %s",
463
+ rb_class2name(CLASS_OF(val)));
464
+ }
465
+ GetISeqPtr(val, iseq);
466
+ if (!iseq->name) {
467
+ rb_raise(rb_eTypeError, "uninitialized InstructionSequence");
468
+ }
469
+ return iseq;
470
+ }
471
+
472
+ static VALUE create_proc(VALUE klass, VALUE binding, rb_iseq_t * iseq)
473
+ {
474
+ VALUE new_proc;
475
+ rb_proc_t * p;
476
+
477
+ if(binding == Qnil)
478
+ {
479
+ binding = rb_binding_new();
480
+ }
481
+ new_proc = rb_funcall(
482
+ rb_cObject, rb_intern("eval"), 2, rb_str_new2("proc { }"), binding);
483
+ GetProcPtr(new_proc, p);
484
+ p->block.iseq = iseq;
485
+ RBASIC(new_proc)->klass = klass;
486
+ return new_proc;
487
+ }
488
+
489
+ #endif
490
+
491
+ /* TODO: It would be nicer if we could eval the node in the current
492
+ * scope, but we have to create a new scope both on 1.8 and on 1.9. */
493
+ VALUE eval_ruby_node(NODE * node, VALUE self, VALUE cref)
494
+ {
495
+ #ifdef RUBY_VM
496
+ if(RTEST(cref))
497
+ {
498
+ rb_raise(
499
+ rb_eArgError,
500
+ "Cannot set cref on YARV");
501
+ }
502
+ else
503
+ {
504
+ VALUE filename = node->nd_file
505
+ ? rb_str_new2(node->nd_file)
506
+ : rb_str_new2("<unknown>");
507
+ VALUE iseq;
508
+
509
+ if(nd_type(node) != NODE_SCOPE)
510
+ {
511
+ /* TODO: This is kinda hokey */
512
+ ID * local_tbl = ruby_current_thread->cfp->iseq
513
+ ? ruby_current_thread->cfp->iseq->local_table
514
+ : 0;
515
+ node = NEW_NODE(NODE_SCOPE, local_tbl, node, 0);
516
+ }
517
+
518
+ iseq = rb_iseq_new(
519
+ node,
520
+ rb_str_new2("<compiled>"),
521
+ filename,
522
+ self,
523
+ ISEQ_TYPE_TOP);
524
+
525
+ /* VALUE str = ruby_iseq_disasm(iseq);
526
+ rb_io_puts(1, &str, rb_stdout); */
527
+
528
+ /* VALUE result = rb_iseq_eval(iseq);
529
+ return result; */
530
+
531
+ rb_proc_t * p;
532
+ VALUE proc;
533
+
534
+ proc = create_proc(rb_cProc, Qnil, iseq_check(iseq));
535
+ GetProcPtr(proc, p);
536
+ p->block.self = self;
537
+
538
+ /* TODO: cref */
539
+
540
+ return rb_funcall(proc, rb_intern("call"), 0);
541
+ }
542
+ #else
543
+ {
544
+ /* Ruby doesn't give us access to rb_eval, so we have to fake it. */
545
+ struct BLOCK * b;
546
+ VALUE proc;
547
+
548
+ proc = create_proc(rb_cProc, Qnil, node, 0);
549
+ Data_Get_Struct(proc, struct BLOCK, b);
550
+ b->self = self;
551
+
552
+ if(RTEST(cref))
553
+ {
554
+ b->cref = unwrap_node(cref);
555
+ }
556
+
557
+ return rb_funcall(proc, rb_intern("call"), 0);
558
+ }
559
+ #endif
560
+ }
561
+
562
+ /*
563
+ * call-seq:
564
+ * node.eval(Object) => Object
565
+ *
566
+ * Evaluate a node with the given object as self and returns the result.
567
+ */
568
+ static VALUE node_eval(int argc, VALUE * argv, VALUE node)
569
+ {
570
+ NODE * n = unwrap_node(node);
571
+
572
+ VALUE self;
573
+ VALUE cref = Qnil;
574
+ rb_scan_args(argc, argv, "11", &self, &cref);
575
+
576
+ if(rb_safe_level() >= 2)
577
+ {
578
+ /* evaluating a node can cause a crash */
579
+ rb_raise(rb_eSecurityError, "Insecure: can't eval node");
580
+ }
581
+
582
+ return eval_ruby_node(n, self, cref);
583
+ }
584
+
585
+ /* ---------------------------------------------------------------------
586
+ * Node marshalling
587
+ * ---------------------------------------------------------------------
588
+ */
589
+
590
+ void dump_node_to_hash(NODE * n, int node_type, VALUE node_hash)
591
+ {
592
+ VALUE s1 = Qnil, s2 = Qnil, s3 = Qnil;
593
+ Node_Type_Descrip const *descrip = node_type_descrip(node_type);
594
+ VALUE nd_file;
595
+ VALUE arr;
596
+
597
+ if(RTEST(rb_hash_aref(node_hash, node_id(n))))
598
+ {
599
+ return;
600
+ }
601
+
602
+ if(TYPE(n) != T_NODE)
603
+ {
604
+ rb_raise(
605
+ rb_eTypeError,
606
+ "wrong argument type %s (expected Node)",
607
+ rb_class2name(CLASS_OF(n)));
608
+ }
609
+
610
+ s1 = dump_node_elem(descrip->n1, n, node_hash);
611
+ s2 = dump_node_elem(descrip->n2, n, node_hash);
612
+ s3 = dump_node_elem(descrip->n3, n, node_hash);
613
+
614
+ nd_file = Qnil;
615
+ #ifdef HAVE_RB_SOURCE_FILENAME
616
+ if(n->nd_file)
617
+ {
618
+ nd_file = rb_str_new2(n->nd_file);
619
+ }
620
+ #endif
621
+
622
+ arr = rb_ary_new();
623
+ rb_ary_push(arr, INT2NUM(n->flags));
624
+ rb_ary_push(arr, nd_file);
625
+ rb_ary_push(arr, s1);
626
+ rb_ary_push(arr, s2);
627
+ rb_ary_push(arr, s3);
628
+
629
+ rb_hash_aset(node_hash, node_id(n), arr);
630
+ }
631
+
632
+ void dump_node_or_iseq_to_hash(VALUE n, int node_type, VALUE node_hash)
633
+ {
634
+ #ifdef RUBY_VM
635
+ if(TYPE(n) == T_DATA && CLASS_OF(n) == rb_cISeq)
636
+ {
637
+ return dump_iseq_to_hash(n, node_hash);
638
+ }
639
+ #endif
640
+
641
+ dump_node_to_hash((NODE *)n, node_type, node_hash);
642
+ }
643
+
644
+ NODE * load_node_from_hash(VALUE arr, VALUE orig_node_id, VALUE node_hash, VALUE id_hash)
645
+ {
646
+ NODE * n = NEW_NIL();
647
+ VALUE s3, s2, s1, rb_nd_file, rb_flags;
648
+ unsigned long flags;
649
+ char *nd_file = 0;
650
+ Node_Type_Descrip const *descrip;
651
+ NODE tmp_node;
652
+
653
+ nd_set_type(&tmp_node, NODE_NIL);
654
+
655
+ Check_Type(arr, T_ARRAY);
656
+ s3 = rb_ary_pop(arr);
657
+ s2 = rb_ary_pop(arr);
658
+ s1 = rb_ary_pop(arr);
659
+ rb_nd_file = rb_ary_pop(arr);
660
+ rb_flags = rb_ary_pop(arr);
661
+ flags = NUM2INT(rb_flags);
662
+ tmp_node.flags = flags;
663
+
664
+ rb_hash_aset(id_hash, orig_node_id, node_id(n));
665
+
666
+ descrip = node_type_descrip(nd_type(&tmp_node));
667
+ load_node_elem(descrip->n1, s1, &tmp_node, node_hash, id_hash);
668
+ load_node_elem(descrip->n2, s2, &tmp_node, node_hash, id_hash);
669
+ load_node_elem(descrip->n3, s3, &tmp_node, node_hash, id_hash);
670
+
671
+ #ifdef HAVE_RB_SOURCE_FILENAME
672
+ /* Note that the garbage collector CAN be invoked at this point, so
673
+ * any node object the GC knowns about must be in a consistent state.
674
+ */
675
+ if(rb_nd_file != Qnil)
676
+ {
677
+ Check_Type(rb_nd_file, T_STRING);
678
+ nd_file = rb_source_filename(RSTRING_PTR(rb_nd_file));
679
+ }
680
+ #endif
681
+
682
+ /* 1) We must NOT get an exception from here on out, since we are
683
+ * modifying a live node, and so nd_file_buf won't be leaked.
684
+ * 2) We must NOT invoke the garbage collector from here on out, since
685
+ * we are modifying a live node.
686
+ */
687
+ memcpy(n, &tmp_node, sizeof(NODE));
688
+ n->flags = flags;
689
+ n->nd_file = nd_file;
690
+
691
+ return n;
692
+ }
693
+
694
+
695
+ VALUE load_node_or_iseq_from_hash(VALUE orig_node_id, VALUE node_hash, VALUE id_hash)
696
+ {
697
+ VALUE data = rb_hash_aref(node_hash, orig_node_id);
698
+
699
+ if(!RTEST(data))
700
+ {
701
+ rb_raise(rb_eArgError, "Could not find node %d in hash", NUM2INT(orig_node_id));
702
+ }
703
+
704
+ #ifdef RUBY_VM
705
+ if(TYPE(data) == T_DATA)
706
+ {
707
+ return (VALUE)load_iseq_from_hash(data, orig_node_id, node_hash, id_hash);
708
+ }
709
+ #endif
710
+
711
+ return (VALUE)load_node_from_hash(data, orig_node_id, node_hash, id_hash);
712
+ }
713
+
714
+
715
+ static VALUE node_to_hash(NODE * n)
716
+ {
717
+ VALUE node_hash;
718
+ node_hash = rb_hash_new();
719
+ dump_node_to_hash(n, nd_type(n), node_hash);
720
+ return node_hash;
721
+ }
722
+
723
+ #ifndef RUBY_VM
724
+ /* From eval.c */
725
+ static void
726
+ compile_error(at)
727
+ const char *at;
728
+ {
729
+ VALUE str;
730
+
731
+ ruby_nerrs = 0;
732
+ str = rb_str_buf_new2("compile error");
733
+ if (at) {
734
+ rb_str_buf_cat2(str, " in ");
735
+ rb_str_buf_cat2(str, at);
736
+ }
737
+ rb_str_buf_cat(str, "\n", 1);
738
+ if (!NIL_P(ruby_errinfo)) {
739
+ rb_str_append(str, rb_obj_as_string(ruby_errinfo));
740
+ }
741
+ rb_exc_raise(rb_exc_new3(rb_eSyntaxError, str));
742
+ }
743
+ #endif
744
+
745
+ /*
746
+ * call-seq:
747
+ * Node.compile_string(str) => Node
748
+ *
749
+ * Compile a string into a node.
750
+ */
751
+ static VALUE node_compile_string(int argc, VALUE * argv, VALUE self)
752
+ {
753
+ NODE * node;
754
+ VALUE str = Qnil, file = Qnil, line = Qnil;
755
+
756
+ rb_scan_args(argc, argv, "12", &str, &file, &line);
757
+
758
+ file = NIL_P(file) ? rb_str_new2("(compiled)") : file;
759
+ line = NIL_P(line) ? INT2NUM(1) : line;
760
+
761
+ node = rb_compile_string(STR2CSTR(file), str, NUM2INT(line));
762
+
763
+ #ifdef RUBY_VM
764
+ if(!node)
765
+ {
766
+ rb_exc_raise(GET_THREAD()->errinfo);
767
+ }
768
+ #else
769
+ if(ruby_nerrs > 0)
770
+ {
771
+ ruby_nerrs = 0;
772
+ compile_error(0);
773
+ }
774
+ #endif
775
+
776
+ return wrap_node(node);
777
+ }
778
+
779
+ #ifdef RUBY_VM
780
+ /*
781
+ * call-seq:
782
+ * node.bytecode_compile => VM::InstructionSequence
783
+ *
784
+ * Compile a parsed node tree into a bytecode sequence.
785
+ *
786
+ * @param name the name of the new iseq (default <unknown>)
787
+ * @param filename the filename for the new iseq (default same as name)
788
+ */
789
+ static VALUE node_bytecode_compile(int argc, VALUE * argv, VALUE self)
790
+ {
791
+ VALUE name = Qnil;
792
+ VALUE filename = Qnil;
793
+ rb_scan_args(argc, argv, "02", &name, &filename);
794
+
795
+ if(name == Qnil)
796
+ {
797
+ name = rb_str_new2("<unknown>");
798
+ }
799
+
800
+ if(filename == Qnil)
801
+ {
802
+ filename = name;
803
+ }
804
+
805
+ NODE * node = unwrap_node(self);
806
+
807
+ return rb_iseq_new(
808
+ node,
809
+ name,
810
+ filename,
811
+ Qfalse,
812
+ ISEQ_TYPE_TOP);
813
+ }
814
+
815
+ #endif
816
+
817
+ /*
818
+ * call-seq:
819
+ * node._dump => String
820
+ *
821
+ * Dump a node.
822
+ */
823
+ static VALUE node_dump(VALUE self, VALUE limit)
824
+ {
825
+ NODE * n;
826
+ VALUE node_hash, arr;
827
+
828
+ if(rb_safe_level() >= 4)
829
+ {
830
+ /* no access to potentially sensitive data from the sandbox */
831
+ rb_raise(rb_eSecurityError, "Insecure: can't dump node");
832
+ }
833
+
834
+ Data_Get_Struct(self, NODE, n);
835
+ node_hash = node_to_hash(n);
836
+ arr = rb_ary_new();
837
+ rb_ary_push(arr, node_id(n));
838
+ rb_ary_push(arr, node_hash);
839
+ VALUE s = marshal_dump(arr, limit);
840
+ return s;
841
+ }
842
+
843
+ /*
844
+ * call-seq:
845
+ * Node._load(str) => Node
846
+ *
847
+ * Load a dumped node.
848
+ */
849
+ static VALUE node_load(VALUE klass, VALUE str)
850
+ {
851
+ VALUE arr, node_hash, node_id, id_hash;
852
+ NODE * n;
853
+ VALUE data;
854
+
855
+ if( rb_safe_level() >= 4
856
+ || (rb_safe_level() >= 1 && OBJ_TAINTED(str)))
857
+ {
858
+ /* no playing with knives in the sandbox */
859
+ rb_raise(rb_eSecurityError, "Insecure: can't load node");
860
+ }
861
+
862
+ arr = marshal_load(str);
863
+ node_hash = rb_ary_pop(arr);
864
+ node_id = rb_ary_pop(arr);
865
+ id_hash = rb_hash_new();
866
+ data = rb_hash_aref(node_hash, node_id);
867
+ n = load_node_from_hash(data, node_id, node_hash, id_hash);
868
+ /* TODO: Need a free function in this case */
869
+ return wrap_node(n);
870
+ }
871
+
872
+ #ifndef HAVE_RB_OBJ_RESPOND_TO
873
+ static VALUE rb_obj_respond_to(VALUE obj, ID id, int priv)
874
+ {
875
+ VALUE include_private = priv ? Qtrue : Qfalse;
876
+ return rb_funcall(obj, rb_intern("respond_to?"), 2, ID2SYM(id), include_private);
877
+ }
878
+ #endif
879
+
880
+ /*
881
+ * call-seq:
882
+ * node.swap(another_node) => Node
883
+ *
884
+ * Swap one node with another. Both nodes must respond to the #swap
885
+ * method. Returns the receiver.
886
+ */
887
+ static VALUE node_swap(VALUE self, VALUE other)
888
+ {
889
+ NODE * n1;
890
+ NODE * n2;
891
+ NODE tmp;
892
+
893
+ if(!rb_obj_respond_to(other, rb_intern("swap"), 0))
894
+ {
895
+ rb_raise(rb_eArgError, "Argument must respond to #swap");
896
+ }
897
+
898
+ if( rb_safe_level() >= 4
899
+ || (rb_safe_level() >= 1 && (OBJ_TAINTED(other) || OBJ_TAINTED(self))))
900
+ {
901
+ /* no playing with knives in the sandbox */
902
+ rb_raise(rb_eSecurityError, "Insecure: can't swap node");
903
+ }
904
+
905
+ Data_Get_Struct(self, NODE, n1);
906
+ Data_Get_Struct(other, NODE, n2);
907
+
908
+ tmp = *n1;
909
+ *n1 = *n2;
910
+ *n2 = tmp;
911
+
912
+ return self;
913
+ }
914
+
915
+ /* ---------------------------------------------------------------------
916
+ * Eval tree
917
+ * ---------------------------------------------------------------------
918
+ */
919
+
920
+ /* TODO Not quite sure how to get BEGIN nodes on 1.9.x... */
921
+ #ifndef RUBY_VM
922
+ extern NODE *ruby_eval_tree_begin;
923
+
924
+ extern NODE *ruby_eval_tree;
925
+
926
+ static VALUE ruby_eval_tree_begin_getter(ID id, void * data, struct global_entry * entry)
927
+ {
928
+ if(rb_safe_level() >= 4)
929
+ {
930
+ /* no access to potentially sensitive data from the sandbox */
931
+ rb_raise(rb_eSecurityError, "Insecure: can't get eval tree");
932
+ }
933
+
934
+ if(ruby_eval_tree_begin)
935
+ {
936
+ return wrap_node(ruby_eval_tree_begin);
937
+ }
938
+ else
939
+ {
940
+ return Qnil;
941
+ }
942
+ }
943
+
944
+ static void ruby_eval_tree_begin_setter(VALUE val, ID id, void * data, struct global_entry * entry)
945
+ {
946
+ rb_raise(rb_eNotImpError, "ruby_eval_tree_begin_setter() not implemented");
947
+ }
948
+
949
+ static VALUE ruby_eval_tree_getter(ID id, void * data, struct global_entry * entry)
950
+ {
951
+ if(rb_safe_level() >= 4)
952
+ {
953
+ /* no access to potentially sensitive data from the sandbox */
954
+ rb_raise(rb_eSecurityError, "Insecure: can't get eval tree");
955
+ }
956
+
957
+ if(ruby_eval_tree)
958
+ {
959
+ return wrap_node(ruby_eval_tree);
960
+ }
961
+ else
962
+ {
963
+ return Qnil;
964
+ }
965
+ }
966
+
967
+ static void ruby_eval_tree_setter(VALUE val, ID id, void * data, struct global_entry * entry)
968
+ {
969
+ rb_raise(rb_eNotImpError, "ruby_eval_tree_setter() not implemented");
970
+ }
971
+ #endif
972
+
973
+ #ifdef HAVE_RUBY_TOP_CREF
974
+ static VALUE ruby_top_cref_getter(ID id, void * data, struct global_entry * entry)
975
+ {
976
+ if(rb_safe_level() >= 4)
977
+ {
978
+ /* no access to potentially sensitive data from the sandbox */
979
+ rb_raise(rb_eSecurityError, "Insecure: can't get top cref");
980
+ }
981
+
982
+ if(ruby_eval_tree_begin)
983
+ {
984
+ return wrap_node(ruby_eval_tree_begin);
985
+ }
986
+ else
987
+ {
988
+ return Qnil;
989
+ }
990
+ }
991
+
992
+ static void ruby_top_cref_setter(VALUE val, ID id, void * data, struct global_entry * entry)
993
+ {
994
+ if(rb_safe_level() >= 2)
995
+ {
996
+ rb_raise(rb_eSecurityError, "Insecure: can't set top cref");
997
+ }
998
+
999
+ ruby_top_cref = unwrap_node(val);
1000
+ }
1001
+ #endif
1002
+
1003
+ #ifdef HAVE_RUBY_CREF
1004
+ static VALUE ruby_cref_getter(ID id, void * data, struct global_entry * entry)
1005
+ {
1006
+ if(rb_safe_level() >= 4)
1007
+ {
1008
+ /* no access to potentially sensitive data from the sandbox */
1009
+ rb_raise(rb_eSecurityError, "Insecure: can't get current cref");
1010
+ }
1011
+
1012
+ if(ruby_cref)
1013
+ {
1014
+ return wrap_node(ruby_cref);
1015
+ }
1016
+ else
1017
+ {
1018
+ return Qnil;
1019
+ }
1020
+ }
1021
+
1022
+ static void ruby_cref_setter(VALUE val, ID id, void * data, struct global_entry * entry)
1023
+ {
1024
+ if(rb_safe_level() >= 2)
1025
+ {
1026
+ rb_raise(rb_eSecurityError, "Insecure: can't set current cref");
1027
+ }
1028
+
1029
+ ruby_cref = unwrap_node(val);
1030
+ }
1031
+ #endif
1032
+
1033
+ /* ---------------------------------------------------------------------
1034
+ * Initialization
1035
+ * ---------------------------------------------------------------------
1036
+ */
1037
+
1038
+ void Init_node(void)
1039
+ {
1040
+ /* This needs to be defined before we require any other files, because
1041
+ * we have a circular dependency.
1042
+ * (node.so depends on iseq.so depends on module.so depends on
1043
+ * node.so)
1044
+ */
1045
+ rb_cNode = rb_define_class("Node", rb_cObject);
1046
+
1047
+ #ifdef RUBY_VM
1048
+ rb_require("internal/vm/iseq");
1049
+ #endif
1050
+
1051
+ {
1052
+ int actual_ruby_version_code = 0;
1053
+ VALUE ruby_version_str = rb_const_get(rb_cObject, rb_intern("RUBY_VERSION"));
1054
+ char const * s = STR2CSTR(ruby_version_str);
1055
+
1056
+ for(; *s != '\0'; ++s)
1057
+ {
1058
+ if(isdigit(*s))
1059
+ {
1060
+ actual_ruby_version_code *= 10;
1061
+ actual_ruby_version_code += *s - '0';
1062
+ }
1063
+ }
1064
+
1065
+ if(actual_ruby_version_code != RUBY_VERSION_CODE)
1066
+ {
1067
+ rb_raise(
1068
+ rb_eRuntimeError,
1069
+ "This version of Ruby/Internal was built with a different "
1070
+ "version of ruby (built with %d, running on %d)",
1071
+ RUBY_VERSION_CODE,
1072
+ actual_ruby_version_code);
1073
+ }
1074
+ }
1075
+
1076
+ #ifdef HAVE_RB_DEFINE_ALLOC_FUNC
1077
+ rb_define_alloc_func(rb_cNode, node_allocate);
1078
+ #endif
1079
+
1080
+ rb_define_method(rb_cNode, "address", node_address, 0);
1081
+ rb_define_method(rb_cNode, "flags", node_flags, 0);
1082
+ rb_define_method(rb_cNode, "nd_file", node_nd_file, 0);
1083
+ rb_define_method(rb_cNode, "nd_line", node_nd_line, 0);
1084
+ rb_define_method(rb_cNode, "nd_type", node_nd_type, 0);
1085
+ rb_define_method(rb_cNode, "members", node_members, 0);
1086
+ rb_define_method(rb_cNode, "eval", node_eval, -1);
1087
+ rb_define_method(rb_cNode, "[]", node_bracket, 1);
1088
+ rb_define_method(rb_cNode, "inspect", node_inspect, 0);
1089
+ rb_define_singleton_method(rb_cNode, "type", node_s_type, 0);
1090
+
1091
+ rb_define_singleton_method(rb_cNode, "compile_string", node_compile_string, -1);
1092
+ #ifdef RUBY_VM
1093
+ rb_define_method(rb_cNode, "bytecode_compile", node_bytecode_compile, -1);
1094
+ #endif
1095
+ rb_define_method(rb_cNode, "_dump", node_dump, 1);
1096
+ rb_define_singleton_method(rb_cNode, "_load", node_load, 1);
1097
+
1098
+ /* TODO: undefine swap for types that are "unsafe" to swap */
1099
+ rb_define_method(rb_cNode, "swap", node_swap, 1);
1100
+
1101
+ define_node_subclass_methods();
1102
+
1103
+ /* For rdoc: rb_cNodeType = rb_define_class("NodeType", rb_cObject) */
1104
+ rb_cNodeType = rb_funcall(
1105
+ rb_cStruct,
1106
+ rb_intern("new"),
1107
+ 2,
1108
+ ID2SYM(rb_intern("name")),
1109
+ ID2SYM(rb_intern("value")));
1110
+ rb_const_set(rb_cNode, rb_intern("Type"), rb_cNodeType);
1111
+ rb_define_method(rb_cNodeType, "to_s", node_type_to_s, 0);
1112
+ rb_define_method(rb_cNodeType, "to_i", node_type_to_i, 0);
1113
+
1114
+ rb_mMarshal = rb_const_get(rb_cObject, rb_intern("Marshal"));
1115
+
1116
+ wrapped_nodes = rb_hash_new();
1117
+
1118
+ rb_global_variable(&wrapped_nodes);
1119
+ rb_set_end_proc(wrapped_nodes_end_proc, Qnil);
1120
+
1121
+ #ifndef RUBY_VM
1122
+ rb_define_virtual_variable(
1123
+ "$ruby_eval_tree_begin",
1124
+ ruby_eval_tree_begin_getter,
1125
+ ruby_eval_tree_begin_setter);
1126
+
1127
+ rb_define_virtual_variable(
1128
+ "$ruby_eval_tree",
1129
+ ruby_eval_tree_getter,
1130
+ ruby_eval_tree_setter);
1131
+ #endif
1132
+
1133
+ #ifdef HAVE_RUBY_TOP_CREF
1134
+ rb_define_virtual_variable(
1135
+ "$ruby_top_cref",
1136
+ ruby_top_cref_getter,
1137
+ ruby_top_cref_setter);
1138
+ #endif
1139
+
1140
+ #ifdef HAVE_RUBY_CREF
1141
+ rb_define_virtual_variable(
1142
+ "$ruby_cref",
1143
+ ruby_cref_getter,
1144
+ ruby_cref_setter);
1145
+ #endif
1146
+ }
1147
+