ruby-internal 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (310) hide show
  1. data/COPYING +59 -0
  2. data/LGPL +515 -0
  3. data/LICENSE +9 -0
  4. data/README +31 -0
  5. data/Rakefile +20 -0
  6. data/TODO +9 -0
  7. data/example/README +5 -0
  8. data/example/simple_client.rb +12 -0
  9. data/example/simple_server.rb +11 -0
  10. data/example/triangle_client.rb +7 -0
  11. data/example/triangle_server.rb +24 -0
  12. data/ext/cached/ruby-1.8.0/internal/binding/block.h +37 -0
  13. data/ext/cached/ruby-1.8.0/internal/method/method.h +19 -0
  14. data/ext/cached/ruby-1.8.0/internal/module/classpath.c +27 -0
  15. data/ext/cached/ruby-1.8.0/internal/module/classpath.h +14 -0
  16. data/ext/cached/ruby-1.8.0/internal/node/block.h +37 -0
  17. data/ext/cached/ruby-1.8.0/internal/node/global_entry.h +10 -0
  18. data/ext/cached/ruby-1.8.0/internal/node/node_type_descrip.c +155 -0
  19. data/ext/cached/ruby-1.8.0/internal/node/nodeinfo.c +5741 -0
  20. data/ext/cached/ruby-1.8.0/internal/node/nodeinfo.h +69 -0
  21. data/ext/cached/ruby-1.8.0/internal/proc/block.h +37 -0
  22. data/ext/cached/ruby-1.8.0/internal/tag/tag.h +15 -0
  23. data/ext/cached/ruby-1.8.0/internal/vm/instruction/insns_info.c +39 -0
  24. data/ext/cached/ruby-1.8.0/internal/vm/instruction/insns_info.h +21 -0
  25. data/ext/cached/ruby-1.8.0/internal/vm/iseq/insns_info.inc +12 -0
  26. data/ext/cached/ruby-1.8.1/internal/binding/block.h +31 -0
  27. data/ext/cached/ruby-1.8.1/internal/method/method.h +19 -0
  28. data/ext/cached/ruby-1.8.1/internal/module/classpath.c +27 -0
  29. data/ext/cached/ruby-1.8.1/internal/module/classpath.h +14 -0
  30. data/ext/cached/ruby-1.8.1/internal/node/block.h +31 -0
  31. data/ext/cached/ruby-1.8.1/internal/node/global_entry.h +10 -0
  32. data/ext/cached/ruby-1.8.1/internal/node/node_type_descrip.c +154 -0
  33. data/ext/cached/ruby-1.8.1/internal/node/nodeinfo.c +5733 -0
  34. data/ext/cached/ruby-1.8.1/internal/node/nodeinfo.h +69 -0
  35. data/ext/cached/ruby-1.8.1/internal/proc/block.h +31 -0
  36. data/ext/cached/ruby-1.8.1/internal/tag/tag.h +16 -0
  37. data/ext/cached/ruby-1.8.1/internal/vm/instruction/insns_info.c +39 -0
  38. data/ext/cached/ruby-1.8.1/internal/vm/instruction/insns_info.h +21 -0
  39. data/ext/cached/ruby-1.8.1/internal/vm/iseq/insns_info.inc +12 -0
  40. data/ext/cached/ruby-1.8.2/internal/binding/block.h +32 -0
  41. data/ext/cached/ruby-1.8.2/internal/method/method.h +19 -0
  42. data/ext/cached/ruby-1.8.2/internal/module/classpath.c +45 -0
  43. data/ext/cached/ruby-1.8.2/internal/module/classpath.h +17 -0
  44. data/ext/cached/ruby-1.8.2/internal/node/block.h +32 -0
  45. data/ext/cached/ruby-1.8.2/internal/node/global_entry.h +10 -0
  46. data/ext/cached/ruby-1.8.2/internal/node/node_type_descrip.c +154 -0
  47. data/ext/cached/ruby-1.8.2/internal/node/nodeinfo.c +5733 -0
  48. data/ext/cached/ruby-1.8.2/internal/node/nodeinfo.h +69 -0
  49. data/ext/cached/ruby-1.8.2/internal/proc/block.h +32 -0
  50. data/ext/cached/ruby-1.8.2/internal/tag/tag.h +16 -0
  51. data/ext/cached/ruby-1.8.2/internal/vm/instruction/insns_info.c +39 -0
  52. data/ext/cached/ruby-1.8.2/internal/vm/instruction/insns_info.h +21 -0
  53. data/ext/cached/ruby-1.8.2/internal/vm/iseq/insns_info.inc +12 -0
  54. data/ext/cached/ruby-1.8.3/internal/binding/block.h +32 -0
  55. data/ext/cached/ruby-1.8.3/internal/method/method.h +20 -0
  56. data/ext/cached/ruby-1.8.3/internal/module/classpath.c +45 -0
  57. data/ext/cached/ruby-1.8.3/internal/module/classpath.h +17 -0
  58. data/ext/cached/ruby-1.8.3/internal/node/block.h +32 -0
  59. data/ext/cached/ruby-1.8.3/internal/node/global_entry.h +10 -0
  60. data/ext/cached/ruby-1.8.3/internal/node/node_type_descrip.c +154 -0
  61. data/ext/cached/ruby-1.8.3/internal/node/nodeinfo.c +5733 -0
  62. data/ext/cached/ruby-1.8.3/internal/node/nodeinfo.h +69 -0
  63. data/ext/cached/ruby-1.8.3/internal/proc/block.h +32 -0
  64. data/ext/cached/ruby-1.8.3/internal/tag/tag.h +16 -0
  65. data/ext/cached/ruby-1.8.3/internal/vm/instruction/insns_info.c +39 -0
  66. data/ext/cached/ruby-1.8.3/internal/vm/instruction/insns_info.h +21 -0
  67. data/ext/cached/ruby-1.8.3/internal/vm/iseq/insns_info.inc +12 -0
  68. data/ext/cached/ruby-1.8.4/internal/binding/block.h +32 -0
  69. data/ext/cached/ruby-1.8.4/internal/method/method.h +20 -0
  70. data/ext/cached/ruby-1.8.4/internal/module/classpath.c +45 -0
  71. data/ext/cached/ruby-1.8.4/internal/module/classpath.h +17 -0
  72. data/ext/cached/ruby-1.8.4/internal/node/block.h +32 -0
  73. data/ext/cached/ruby-1.8.4/internal/node/global_entry.h +10 -0
  74. data/ext/cached/ruby-1.8.4/internal/node/node_type_descrip.c +154 -0
  75. data/ext/cached/ruby-1.8.4/internal/node/nodeinfo.c +5733 -0
  76. data/ext/cached/ruby-1.8.4/internal/node/nodeinfo.h +69 -0
  77. data/ext/cached/ruby-1.8.4/internal/proc/block.h +32 -0
  78. data/ext/cached/ruby-1.8.4/internal/tag/tag.h +16 -0
  79. data/ext/cached/ruby-1.8.4/internal/vm/instruction/insns_info.c +39 -0
  80. data/ext/cached/ruby-1.8.4/internal/vm/instruction/insns_info.h +21 -0
  81. data/ext/cached/ruby-1.8.4/internal/vm/iseq/insns_info.inc +12 -0
  82. data/ext/cached/ruby-1.8.5/internal/binding/block.h +32 -0
  83. data/ext/cached/ruby-1.8.5/internal/method/method.h +20 -0
  84. data/ext/cached/ruby-1.8.5/internal/module/classpath.c +45 -0
  85. data/ext/cached/ruby-1.8.5/internal/module/classpath.h +17 -0
  86. data/ext/cached/ruby-1.8.5/internal/node/block.h +32 -0
  87. data/ext/cached/ruby-1.8.5/internal/node/global_entry.h +10 -0
  88. data/ext/cached/ruby-1.8.5/internal/node/node_type_descrip.c +154 -0
  89. data/ext/cached/ruby-1.8.5/internal/node/nodeinfo.c +5732 -0
  90. data/ext/cached/ruby-1.8.5/internal/node/nodeinfo.h +67 -0
  91. data/ext/cached/ruby-1.8.5/internal/proc/block.h +32 -0
  92. data/ext/cached/ruby-1.8.5/internal/tag/tag.h +16 -0
  93. data/ext/cached/ruby-1.8.5/internal/vm/instruction/insns_info.c +39 -0
  94. data/ext/cached/ruby-1.8.5/internal/vm/instruction/insns_info.h +21 -0
  95. data/ext/cached/ruby-1.8.5/internal/vm/iseq/insns_info.inc +12 -0
  96. data/ext/cached/ruby-1.8.6/internal/binding/block.h +32 -0
  97. data/ext/cached/ruby-1.8.6/internal/method/method.h +20 -0
  98. data/ext/cached/ruby-1.8.6/internal/module/classpath.c +45 -0
  99. data/ext/cached/ruby-1.8.6/internal/module/classpath.h +17 -0
  100. data/ext/cached/ruby-1.8.6/internal/node/block.h +32 -0
  101. data/ext/cached/ruby-1.8.6/internal/node/global_entry.h +10 -0
  102. data/ext/cached/ruby-1.8.6/internal/node/node_type_descrip.c +154 -0
  103. data/ext/cached/ruby-1.8.6/internal/node/nodeinfo.c +5732 -0
  104. data/ext/cached/ruby-1.8.6/internal/node/nodeinfo.h +67 -0
  105. data/ext/cached/ruby-1.8.6/internal/proc/block.h +32 -0
  106. data/ext/cached/ruby-1.8.6/internal/tag/tag.h +16 -0
  107. data/ext/cached/ruby-1.8.6/internal/vm/instruction/insns_info.c +39 -0
  108. data/ext/cached/ruby-1.8.6/internal/vm/instruction/insns_info.h +21 -0
  109. data/ext/cached/ruby-1.8.6/internal/vm/iseq/insns_info.inc +12 -0
  110. data/ext/cached/ruby-1.8.7/internal/binding/block.h +32 -0
  111. data/ext/cached/ruby-1.8.7/internal/method/method.h +20 -0
  112. data/ext/cached/ruby-1.8.7/internal/module/classpath.c +45 -0
  113. data/ext/cached/ruby-1.8.7/internal/module/classpath.h +17 -0
  114. data/ext/cached/ruby-1.8.7/internal/node/block.h +32 -0
  115. data/ext/cached/ruby-1.8.7/internal/node/global_entry.h +10 -0
  116. data/ext/cached/ruby-1.8.7/internal/node/node_type_descrip.c +154 -0
  117. data/ext/cached/ruby-1.8.7/internal/node/nodeinfo.c +5732 -0
  118. data/ext/cached/ruby-1.8.7/internal/node/nodeinfo.h +67 -0
  119. data/ext/cached/ruby-1.8.7/internal/proc/block.h +32 -0
  120. data/ext/cached/ruby-1.8.7/internal/tag/tag.h +16 -0
  121. data/ext/cached/ruby-1.8.7/internal/vm/instruction/insns_info.c +39 -0
  122. data/ext/cached/ruby-1.8.7/internal/vm/instruction/insns_info.h +21 -0
  123. data/ext/cached/ruby-1.8.7/internal/vm/iseq/insns_info.inc +12 -0
  124. data/ext/cached/ruby-1.9.0/internal/binding/block.h +12 -0
  125. data/ext/cached/ruby-1.9.0/internal/method/method.h +20 -0
  126. data/ext/cached/ruby-1.9.0/internal/module/classpath.c +42 -0
  127. data/ext/cached/ruby-1.9.0/internal/module/classpath.h +17 -0
  128. data/ext/cached/ruby-1.9.0/internal/node/block.h +12 -0
  129. data/ext/cached/ruby-1.9.0/internal/node/global_entry.h +10 -0
  130. data/ext/cached/ruby-1.9.0/internal/node/node_type_descrip.c +149 -0
  131. data/ext/cached/ruby-1.9.0/internal/node/nodeinfo.c +5579 -0
  132. data/ext/cached/ruby-1.9.0/internal/node/nodeinfo.h +70 -0
  133. data/ext/cached/ruby-1.9.0/internal/proc/block.h +12 -0
  134. data/ext/cached/ruby-1.9.0/internal/tag/tag.h +6 -0
  135. data/ext/cached/ruby-1.9.0/internal/vm/instruction/insns_info.c +5936 -0
  136. data/ext/cached/ruby-1.9.0/internal/vm/instruction/insns_info.h +891 -0
  137. data/ext/cached/ruby-1.9.0/internal/vm/iseq/insns_info.inc +700 -0
  138. data/ext/cached/ruby-1.9.0/internal/yarv-headers/debug.h +36 -0
  139. data/ext/cached/ruby-1.9.0/internal/yarv-headers/dln.h +41 -0
  140. data/ext/cached/ruby-1.9.0/internal/yarv-headers/encdb.h +147 -0
  141. data/ext/cached/ruby-1.9.0/internal/yarv-headers/eval_intern.h +221 -0
  142. data/ext/cached/ruby-1.9.0/internal/yarv-headers/gc.h +75 -0
  143. data/ext/cached/ruby-1.9.0/internal/yarv-headers/id.h +83 -0
  144. data/ext/cached/ruby-1.9.0/internal/yarv-headers/iseq.h +94 -0
  145. data/ext/cached/ruby-1.9.0/internal/yarv-headers/node.h +516 -0
  146. data/ext/cached/ruby-1.9.0/internal/yarv-headers/parse.h +303 -0
  147. data/ext/cached/ruby-1.9.0/internal/yarv-headers/regenc.h +207 -0
  148. data/ext/cached/ruby-1.9.0/internal/yarv-headers/regint.h +842 -0
  149. data/ext/cached/ruby-1.9.0/internal/yarv-headers/regparse.h +351 -0
  150. data/ext/cached/ruby-1.9.0/internal/yarv-headers/revision.h +1 -0
  151. data/ext/cached/ruby-1.9.0/internal/yarv-headers/thread_pthread.h +24 -0
  152. data/ext/cached/ruby-1.9.0/internal/yarv-headers/thread_win32.h +33 -0
  153. data/ext/cached/ruby-1.9.0/internal/yarv-headers/transcode_data.h +99 -0
  154. data/ext/cached/ruby-1.9.0/internal/yarv-headers/transdb.h +67 -0
  155. data/ext/cached/ruby-1.9.0/internal/yarv-headers/version.h +57 -0
  156. data/ext/cached/ruby-1.9.0/internal/yarv-headers/vm_core.h +663 -0
  157. data/ext/cached/ruby-1.9.0/internal/yarv-headers/vm_exec.h +187 -0
  158. data/ext/cached/ruby-1.9.0/internal/yarv-headers/vm_insnhelper.h +191 -0
  159. data/ext/cached/ruby-1.9.0/internal/yarv-headers/vm_opts.h +51 -0
  160. data/ext/cached/ruby-1.9.1/internal/binding/block.h +12 -0
  161. data/ext/cached/ruby-1.9.1/internal/method/method.h +20 -0
  162. data/ext/cached/ruby-1.9.1/internal/module/classpath.c +42 -0
  163. data/ext/cached/ruby-1.9.1/internal/module/classpath.h +17 -0
  164. data/ext/cached/ruby-1.9.1/internal/node/block.h +12 -0
  165. data/ext/cached/ruby-1.9.1/internal/node/global_entry.h +10 -0
  166. data/ext/cached/ruby-1.9.1/internal/node/node_type_descrip.c +149 -0
  167. data/ext/cached/ruby-1.9.1/internal/node/nodeinfo.c +5579 -0
  168. data/ext/cached/ruby-1.9.1/internal/node/nodeinfo.h +70 -0
  169. data/ext/cached/ruby-1.9.1/internal/proc/block.h +12 -0
  170. data/ext/cached/ruby-1.9.1/internal/tag/tag.h +6 -0
  171. data/ext/cached/ruby-1.9.1/internal/vm/instruction/insns_info.c +5936 -0
  172. data/ext/cached/ruby-1.9.1/internal/vm/instruction/insns_info.h +891 -0
  173. data/ext/cached/ruby-1.9.1/internal/vm/iseq/insns_info.inc +700 -0
  174. data/ext/cached/ruby-1.9.1/internal/yarv-headers/debug.h +36 -0
  175. data/ext/cached/ruby-1.9.1/internal/yarv-headers/dln.h +41 -0
  176. data/ext/cached/ruby-1.9.1/internal/yarv-headers/encdb.h +147 -0
  177. data/ext/cached/ruby-1.9.1/internal/yarv-headers/eval_intern.h +209 -0
  178. data/ext/cached/ruby-1.9.1/internal/yarv-headers/gc.h +75 -0
  179. data/ext/cached/ruby-1.9.1/internal/yarv-headers/id.h +184 -0
  180. data/ext/cached/ruby-1.9.1/internal/yarv-headers/iseq.h +94 -0
  181. data/ext/cached/ruby-1.9.1/internal/yarv-headers/node.h +516 -0
  182. data/ext/cached/ruby-1.9.1/internal/yarv-headers/parse.h +303 -0
  183. data/ext/cached/ruby-1.9.1/internal/yarv-headers/regenc.h +207 -0
  184. data/ext/cached/ruby-1.9.1/internal/yarv-headers/regint.h +842 -0
  185. data/ext/cached/ruby-1.9.1/internal/yarv-headers/regparse.h +351 -0
  186. data/ext/cached/ruby-1.9.1/internal/yarv-headers/revision.h +1 -0
  187. data/ext/cached/ruby-1.9.1/internal/yarv-headers/thread_pthread.h +24 -0
  188. data/ext/cached/ruby-1.9.1/internal/yarv-headers/thread_win32.h +33 -0
  189. data/ext/cached/ruby-1.9.1/internal/yarv-headers/transcode_data.h +99 -0
  190. data/ext/cached/ruby-1.9.1/internal/yarv-headers/transdb.h +85 -0
  191. data/ext/cached/ruby-1.9.1/internal/yarv-headers/version.h +60 -0
  192. data/ext/cached/ruby-1.9.1/internal/yarv-headers/vm_core.h +655 -0
  193. data/ext/cached/ruby-1.9.1/internal/yarv-headers/vm_exec.h +187 -0
  194. data/ext/cached/ruby-1.9.1/internal/yarv-headers/vm_insnhelper.h +194 -0
  195. data/ext/cached/ruby-1.9.1/internal/yarv-headers/vm_opts.h +51 -0
  196. data/ext/internal/binding/binding.c +45 -0
  197. data/ext/internal/binding/block.h.rpp +44 -0
  198. data/ext/internal/binding/extconf.rb +6 -0
  199. data/ext/internal/method/extconf.rb +8 -0
  200. data/ext/internal/method/method.c +269 -0
  201. data/ext/internal/method/method.h.rpp +58 -0
  202. data/ext/internal/module/classpath.c.rpp +29 -0
  203. data/ext/internal/module/classpath.h.rpp +36 -0
  204. data/ext/internal/module/extconf.rb +11 -0
  205. data/ext/internal/module/module.c +797 -0
  206. data/ext/internal/module/module.h +7 -0
  207. data/ext/internal/node/block.h.rpp +44 -0
  208. data/ext/internal/node/builtins.h +41 -0
  209. data/ext/internal/node/extconf.rb +66 -0
  210. data/ext/internal/node/global_entry.h.rpp +26 -0
  211. data/ext/internal/node/node.c +1147 -0
  212. data/ext/internal/node/node_type_descrip.c.rpp +72 -0
  213. data/ext/internal/node/node_type_descrip.h +17 -0
  214. data/ext/internal/node/node_type_descrip.rb +39 -0
  215. data/ext/internal/node/nodeinfo.c.rpp +587 -0
  216. data/ext/internal/node/nodeinfo.h.rpp +30 -0
  217. data/ext/internal/node/nodes.rb +78 -0
  218. data/ext/internal/node/read_node_h.rb +34 -0
  219. data/ext/internal/node/ruby_internal_node.h +31 -0
  220. data/ext/internal/noex/extconf.rb +6 -0
  221. data/ext/internal/noex/noex.c +44 -0
  222. data/ext/internal/object/extconf.rb +4 -0
  223. data/ext/internal/object/object.c +75 -0
  224. data/ext/internal/proc/block.h.rpp +44 -0
  225. data/ext/internal/proc/extconf.rb +9 -0
  226. data/ext/internal/proc/proc.c +331 -0
  227. data/ext/internal/tag/extconf.rb +3 -0
  228. data/ext/internal/tag/tag.c +17 -0
  229. data/ext/internal/tag/tag.h.rpp +22 -0
  230. data/ext/internal/thread/extconf.rb +3 -0
  231. data/ext/internal/thread/thread.c +107 -0
  232. data/ext/internal/vm/constants/constants.c +33 -0
  233. data/ext/internal/vm/constants/extconf.rb +3 -0
  234. data/ext/internal/vm/control_frame/control_frame.c +185 -0
  235. data/ext/internal/vm/control_frame/control_frame.h +18 -0
  236. data/ext/internal/vm/control_frame/extconf.rb +3 -0
  237. data/ext/internal/vm/extconf.rb +3 -0
  238. data/ext/internal/vm/inline_cache/extconf.rb +6 -0
  239. data/ext/internal/vm/inline_cache/inline_cache.c +79 -0
  240. data/ext/internal/vm/instruction/extconf.rb +6 -0
  241. data/ext/internal/vm/instruction/insns_info.c.rpp +213 -0
  242. data/ext/internal/vm/instruction/insns_info.h.rpp +53 -0
  243. data/ext/internal/vm/instruction/instruction.c +78 -0
  244. data/ext/internal/vm/instruction/instruction.h +10 -0
  245. data/ext/internal/vm/iseq/extconf.rb +7 -0
  246. data/ext/internal/vm/iseq/insns_info.inc.rpp +30 -0
  247. data/ext/internal/vm/iseq/internal_iseq.h +9 -0
  248. data/ext/internal/vm/iseq/iseq.c +555 -0
  249. data/ext/internal/vm/vm.c +55 -0
  250. data/ext/mkmf-ruby-internal.rb +111 -0
  251. data/ext/ruby_source_dir.rb +24 -0
  252. data/ext/rubypp.rb +97 -0
  253. data/generate_rdoc.rb +33 -0
  254. data/lib/internal/binding.rb +1 -0
  255. data/lib/internal/classtree.rb +55 -0
  256. data/lib/internal/debug.rb +16 -0
  257. data/lib/internal/method.rb +1 -0
  258. data/lib/internal/method/as_code.rb +33 -0
  259. data/lib/internal/method/as_expression.rb +34 -0
  260. data/lib/internal/method/signature.rb +442 -0
  261. data/lib/internal/module.rb +1 -0
  262. data/lib/internal/module/as_code.rb +45 -0
  263. data/lib/internal/node.rb +3 -0
  264. data/lib/internal/node/as_code.rb +233 -0
  265. data/lib/internal/node/as_expression.rb +619 -0
  266. data/lib/internal/node/dump.rb +53 -0
  267. data/lib/internal/node/pp.rb +72 -0
  268. data/lib/internal/node/to_a.rb +52 -0
  269. data/lib/internal/noex.rb +1 -0
  270. data/lib/internal/obfusc.rb +57 -0
  271. data/lib/internal/object.rb +1 -0
  272. data/lib/internal/object/as_code.rb +10 -0
  273. data/lib/internal/proc.rb +1 -0
  274. data/lib/internal/proc/as_code.rb +21 -0
  275. data/lib/internal/proc/as_expression.rb +14 -0
  276. data/lib/internal/proc/signature.rb +184 -0
  277. data/lib/internal/tag.rb +1 -0
  278. data/lib/internal/thread.rb +1 -0
  279. data/lib/internal/vm.rb +1 -0
  280. data/lib/internal/vm/bytedecoder.rb +866 -0
  281. data/lib/internal/vm/constants.rb +1 -0
  282. data/lib/internal/vm/control_frame.rb +1 -0
  283. data/lib/internal/vm/inline_cache.rb +1 -0
  284. data/lib/internal/vm/instruction.rb +1 -0
  285. data/lib/internal/vm/iseq.rb +1 -0
  286. data/lib/internal/vm/iseq/as_code.rb +27 -0
  287. data/lib/internal/vm/iseq/as_expression.rb +26 -0
  288. data/metaconfig +19 -0
  289. data/post-config.rb +1 -0
  290. data/post-install.rb +4 -0
  291. data/post-setup.rb +7 -0
  292. data/pre-config.rb +96 -0
  293. data/pre-install.rb +13 -0
  294. data/pre-setup.rb +8 -0
  295. data/run_tests.rb +26 -0
  296. data/setup.rb +1599 -0
  297. data/test/expression_samples.rb +160 -0
  298. data/test/node_samples.rb +122 -0
  299. data/test/test_as_code.rb +261 -0
  300. data/test/test_as_expression.rb +229 -0
  301. data/test/test_dump_class.rb +187 -0
  302. data/test/test_dump_method.rb +144 -0
  303. data/test/test_dump_proc.rb +118 -0
  304. data/test/test_helpers.rb +61 -0
  305. data/test/test_method.rb +72 -0
  306. data/test/test_methodsig.rb +267 -0
  307. data/test/test_module.rb +49 -0
  308. data/test/test_node.rb +77 -0
  309. data/test/test_proc.rb +47 -0
  310. metadata +377 -0
@@ -0,0 +1,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
+