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,11 @@
1
+ $: << '../..'
2
+ require 'mkmf-ruby-internal'
3
+
4
+ have_func('vm_get_ruby_level_cfp')
5
+ have_func('vm_get_ruby_level_next_cfp')
6
+ have_header('ruby/node.h') or have_header('node.h')
7
+
8
+ ruby_version_code = RUBY_VERSION.gsub(/\./, '').to_i
9
+ $CPPFLAGS << " -DRUBY_VERSION_CODE=#{ruby_version_code}"
10
+
11
+ create_ruby_internal_makefile 'internal/module/module'
@@ -0,0 +1,797 @@
1
+ #include <ruby.h>
2
+ #include "internal/node/ruby_internal_node.h"
3
+
4
+ #ifdef RUBY_VM
5
+ #include <ruby/st.h>
6
+ #include "vm_core.h"
7
+ #include "eval_intern.h"
8
+ #else
9
+ #include <rubysig.h>
10
+ #include <st.h>
11
+ #endif
12
+
13
+ #ifndef RCLASS_SUPER
14
+ #define RCLASS_SUPER(c) RCLASS(c)->super
15
+ #endif
16
+
17
+ #ifndef RCLASS_IV_TBL
18
+ #define RCLASS_IV_TBL(c) RCLASS(c)->iv_tbl
19
+ #endif
20
+
21
+ #ifndef RCLASS_M_TBL
22
+ #define RCLASS_M_TBL(c) RCLASS(c)->m_tbl
23
+ #endif
24
+
25
+ #ifndef RARRAY_LEN
26
+ #define RARRAY_LEN(a) RARRAY(a)->len
27
+ #endif
28
+
29
+ #ifndef RARRAY_PTR
30
+ #define RARRAY_PTR(a) RARRAY(a)->ptr
31
+ #endif
32
+
33
+ static VALUE rb_cNode;
34
+
35
+ static VALUE rb_mMarshal;
36
+
37
+ static VALUE rb_cClass_Restorer;
38
+
39
+ static VALUE marshal_dump(VALUE obj, VALUE limit)
40
+ {
41
+ return rb_funcall(rb_mMarshal, rb_intern("dump"), 2, obj, limit);
42
+ }
43
+
44
+ static VALUE marshal_load(VALUE obj)
45
+ {
46
+ return rb_funcall(rb_mMarshal, rb_intern("load"), 1, obj);
47
+ }
48
+
49
+ #if RUBY_VERSION_CODE >= 180
50
+ struct Class_Restorer
51
+ {
52
+ VALUE klass;
53
+ struct st_table m_tbl;
54
+ struct st_table iv_tbl;
55
+ #ifndef RUBY_VM
56
+ int thread_critical;
57
+ #endif
58
+ };
59
+
60
+ #if RUBY_VERSION_CODE >= 180
61
+ static void mark_class_restorer(struct Class_Restorer * class_restorer)
62
+ {
63
+ rb_mark_tbl(&class_restorer->m_tbl);
64
+ rb_mark_tbl(&class_restorer->iv_tbl);
65
+ }
66
+
67
+ static VALUE create_class_restorer(VALUE klass)
68
+ {
69
+ /* On Ruby 1.8, there is a check in marshal_dump() to ensure that
70
+ * the object being dumped has no modifications to its singleton
71
+ * class (e.g. no singleton instance variables, and no singleton
72
+ * methods defined). Since we need to dump the class's singleton
73
+ * class in order to dump class methods, we need a way around this
74
+ * restriction. The solution found here temporarily removes the
75
+ * singleton instance variables and singleton methods while the
76
+ * class is being dumped, and sets a special singleton instance
77
+ * variable that restores the tables when dumping is complete. A
78
+ * hack for sure, but it seems to work.
79
+ */
80
+ struct RClass * singleton_class = RCLASS(CLASS_OF(klass));
81
+ struct Class_Restorer * class_restorer;
82
+
83
+ if(!RCLASS_IV_TBL(singleton_class))
84
+ {
85
+ rb_raise(
86
+ rb_eTypeError,
87
+ "can't dump singleton class on Ruby 1.8 without iv_tbl");
88
+ }
89
+
90
+ class_restorer = ALLOC(struct Class_Restorer);
91
+ class_restorer->klass = CLASS_OF(klass);
92
+ class_restorer->m_tbl = *RCLASS_M_TBL(singleton_class);
93
+ class_restorer->iv_tbl = *RCLASS_IV_TBL(singleton_class);
94
+ #ifndef RUBY_VM
95
+ class_restorer->thread_critical = rb_thread_critical;
96
+ #endif
97
+ return Data_Wrap_Struct(
98
+ rb_cClass_Restorer, mark_class_restorer, ruby_xfree,
99
+ class_restorer);
100
+ }
101
+
102
+ static void set_class_restore_state(VALUE klass)
103
+ {
104
+ struct RClass * singleton_class = RCLASS(CLASS_OF(klass));
105
+ RCLASS_IV_TBL(singleton_class)->num_entries = 1;
106
+ RCLASS_M_TBL(singleton_class)->num_entries = 0;
107
+ #ifndef RUBY_VM
108
+ rb_thread_critical = 1;
109
+ #endif
110
+ }
111
+
112
+ static void restore_class(VALUE ruby_class_restorer)
113
+ {
114
+ struct Class_Restorer * class_restorer;
115
+ struct RClass * klass;
116
+
117
+ Data_Get_Struct(
118
+ ruby_class_restorer,
119
+ struct Class_Restorer,
120
+ class_restorer);
121
+ klass = RCLASS(class_restorer->klass);
122
+ *RCLASS_M_TBL(klass) = class_restorer->m_tbl;
123
+ *RCLASS_IV_TBL(klass) = class_restorer->iv_tbl;
124
+ #ifndef RUBY_VM
125
+ rb_thread_critical = class_restorer->thread_critical;
126
+ #endif
127
+ }
128
+
129
+ /*
130
+ * call-seq:
131
+ * class_restorer.dump => String
132
+ *
133
+ * Do not call this function.
134
+ */
135
+ static VALUE class_restorer_dump(VALUE ruby_class_restorer, VALUE limit)
136
+ {
137
+ restore_class(ruby_class_restorer);
138
+ return rb_str_new2("");
139
+ }
140
+
141
+ /*
142
+ * call-seq:
143
+ * Nodewrap::ClassRestorer.load => ClassRestorer
144
+ *
145
+ * Do not call this function.
146
+ */
147
+ static VALUE class_restorer_load(VALUE klass, VALUE str)
148
+ {
149
+ return Qnil;
150
+ }
151
+
152
+ #endif
153
+
154
+ static VALUE rb_cClass_Restorer = Qnil;
155
+
156
+ #if RUBY_VERSION_CODE == 180
157
+
158
+ static VALUE ruby180_marshal_dump(int argc, VALUE * argv, VALUE klass)
159
+ {
160
+ VALUE class_restorer = Qnil;
161
+
162
+ if(argc >= 1 && (TYPE(argv[0]) == T_CLASS || TYPE(argv[0]) == T_MODULE))
163
+ {
164
+ class_restorer = create_class_restorer(argv[0]);
165
+ set_class_restore_state(argv[0]);
166
+ }
167
+
168
+ VALUE str = rb_funcall2(klass, rb_intern("_Nodewrap__orig_dump"), argc, argv);
169
+
170
+ if(class_restorer != Qnil)
171
+ {
172
+ restore_class(class_restorer);
173
+ }
174
+
175
+ return str;
176
+ }
177
+
178
+ #endif
179
+
180
+ #if RUBY_VERSION_CODE >= 180
181
+ static VALUE module_instance_allocate(VALUE klass)
182
+ {
183
+ NEWOBJ(obj, struct RClass);
184
+ OBJSETUP(obj, klass, T_CLASS);
185
+ return (VALUE)obj;
186
+ }
187
+ #endif
188
+
189
+ static int add_to_method_hash(ID id, NODE * body, VALUE methods)
190
+ {
191
+ VALUE v = wrap_node(body);
192
+ rb_hash_aset(methods, ID2SYM(id), v);
193
+
194
+ return ST_CONTINUE;
195
+ }
196
+
197
+ static VALUE instance_method_hash(VALUE module)
198
+ {
199
+ VALUE methods = rb_hash_new();
200
+ st_foreach(
201
+ RCLASS(module)->m_tbl,
202
+ add_to_method_hash,
203
+ #ifdef ST_DATA_T_DEFINED
204
+ (st_data_t)methods
205
+ #else
206
+ methods
207
+ #endif
208
+ );
209
+ return methods;
210
+ }
211
+
212
+ static VALUE included_modules_list(VALUE module)
213
+ {
214
+ VALUE included_modules = rb_mod_included_modules(module);
215
+ VALUE included_module_list = rb_ary_new();
216
+ size_t j;
217
+
218
+ for(j = 0; j < RARRAY_LEN(included_modules); ++j)
219
+ {
220
+ rb_ary_push(
221
+ included_module_list,
222
+ rb_mod_name(RARRAY_PTR(included_modules)[j]));
223
+ }
224
+
225
+ return included_module_list;
226
+ }
227
+
228
+ static VALUE superclass_name(VALUE module)
229
+ {
230
+ if(TYPE(module) == T_MODULE)
231
+ {
232
+ return Qnil;
233
+ }
234
+ else
235
+ {
236
+ VALUE super = RCLASS_SUPER(module);
237
+
238
+ while(TYPE(super) == T_ICLASS)
239
+ {
240
+ super = RCLASS_SUPER(super);
241
+ }
242
+
243
+ if(!super)
244
+ {
245
+ return Qnil;
246
+ }
247
+
248
+ if(FL_TEST(super, FL_SINGLETON))
249
+ {
250
+ VALUE v = rb_iv_get(super, "__attached__");
251
+ VALUE name = rb_mod_name(v);
252
+ rb_str_cat2(name, "::<Singleton>");
253
+ return name;
254
+ }
255
+ else
256
+ {
257
+ return rb_mod_name(super);
258
+ }
259
+ }
260
+ }
261
+
262
+ static int add_var_to_hash(ID key, VALUE value, VALUE hash)
263
+ {
264
+ /* These are special variables and should not be dumped */
265
+ if( key != rb_intern("__classpath__")
266
+ && key != rb_intern("__classid__")
267
+ && key != rb_intern("__attached__"))
268
+ {
269
+ rb_hash_aset(hash, ID2SYM(key), value);
270
+ }
271
+ return ST_CONTINUE;
272
+ }
273
+
274
+ static VALUE class_variable_hash(VALUE module)
275
+ {
276
+ VALUE class_variables = rb_hash_new();
277
+ #if RUBY_VERSION_CODE < 190
278
+ struct st_table * iv_tbl = ROBJECT(module)->iv_tbl;
279
+ if (iv_tbl)
280
+ {
281
+ st_foreach(iv_tbl, add_var_to_hash, class_variables);
282
+ }
283
+ #else
284
+ rb_ivar_foreach(module, add_var_to_hash, class_variables);
285
+ #endif
286
+ return class_variables;
287
+ }
288
+
289
+ static void mark_class_restorer(struct Class_Restorer * class_restorer);
290
+ #endif
291
+
292
+ static char const * lookup_module_str =
293
+ "proc { |name|\n"
294
+ " o = Object\n"
295
+ " name.to_s.split('::').each do |subname|\n"
296
+ " if subname == '<Singleton>' then\n"
297
+ " o = o.singleton_class\n"
298
+ " else\n"
299
+ " o = o.const_get(subname)\n"
300
+ " end\n"
301
+ " end\n"
302
+ " o\n"
303
+ "}\n";
304
+ static VALUE lookup_module_proc = Qnil;
305
+
306
+ VALUE lookup_module(VALUE name)
307
+ {
308
+ return rb_funcall(lookup_module_proc, rb_intern("call"), 1, name);
309
+ }
310
+
311
+ static char const * outer_module_str =
312
+ "proc { |name|\n"
313
+ " o = Object\n"
314
+ " names = name.to_s.split('::')\n"
315
+ " names.pop\n"
316
+ " names.each do |subname|\n"
317
+ " if subname == '<Singleton>' then\n"
318
+ " o = o.singleton_class\n"
319
+ " else\n"
320
+ " o = o.const_get(subname)\n"
321
+ " end\n"
322
+ " end\n"
323
+ " o\n"
324
+ "}\n";
325
+
326
+ static VALUE outer_module_proc = Qnil;
327
+
328
+ static char const * module_name_str =
329
+ "proc { |name|\n"
330
+ " names = name.to_s.split('::')\n"
331
+ " names[-1].intern\n"
332
+ "}\n";
333
+
334
+ static VALUE module_name_proc = Qnil;
335
+
336
+ #ifdef RUBY_VM
337
+
338
+ #if defined(HAVE_VM_GET_RUBY_LEVEL_NEXT_CFP)
339
+ /* Declared and defined in vm.c */
340
+ rb_control_frame_t *
341
+ vm_get_ruby_level_next_cfp(rb_thread_t *th, rb_control_frame_t *cfp);
342
+ #endif
343
+
344
+ static void set_cref_stack(rb_iseq_t * iseqdat, VALUE klass, VALUE noex)
345
+ {
346
+ rb_thread_t * th = GET_THREAD();
347
+ #if defined(HAVE_VM_GET_RUBY_LEVEL_NEXT_CFP)
348
+ rb_control_frame_t * cfp = vm_get_ruby_level_next_cfp(th, th->cfp);
349
+ #elif defined(HAVE_VM_GET_RUBY_LEVEL_CFP)
350
+ rb_control_frame_t * cfp = vm_get_ruby_level_cfp(th, th->cfp);
351
+ #else
352
+ #error No function to get cfp
353
+ #endif
354
+ iseqdat->cref_stack = NEW_BLOCK(klass);
355
+ iseqdat->cref_stack->nd_visi = noex;
356
+ iseqdat->cref_stack->nd_next = cfp->iseq->cref_stack; /* TODO: use lfp? */
357
+ }
358
+
359
+ /* From iseq.c */
360
+ static rb_iseq_t *
361
+ iseq_check(VALUE val)
362
+ {
363
+ rb_iseq_t *iseq;
364
+ if(!rb_obj_is_kind_of(val, rb_cISeq))
365
+ {
366
+ rb_raise(
367
+ rb_eTypeError,
368
+ "Expected VM::InstructionSequence, but got %s",
369
+ rb_class2name(CLASS_OF(val)));
370
+ }
371
+ GetISeqPtr(val, iseq);
372
+ if (!iseq->name) {
373
+ rb_raise(rb_eTypeError, "uninitialized InstructionSequence");
374
+ }
375
+ return iseq;
376
+ }
377
+
378
+ #endif
379
+
380
+ /*
381
+ * call-seq:
382
+ * class.add_method(id, node or iseq, noex) #=> nil
383
+ *
384
+ * Adds the method as an instance method to the given class.
385
+ *
386
+ * To add a singleton method to a class, add the method to its singleton
387
+ * class.
388
+ */
389
+ static VALUE module_add_method(VALUE klass, VALUE id, VALUE node, VALUE noex)
390
+ {
391
+ NODE * n = 0;
392
+
393
+ if(rb_safe_level() >= 2)
394
+ {
395
+ /* adding a method with the wrong node type can cause a crash */
396
+ rb_raise(rb_eSecurityError, "Insecure: can't add method");
397
+ }
398
+
399
+ #ifdef RUBY_VM
400
+ if(rb_obj_is_kind_of(node, rb_cISeq))
401
+ {
402
+ rb_iseq_t *iseqdat = iseq_check(node);
403
+ /* TODO: any restrictions on what kinds of iseqs we can add here?
404
+ */
405
+ set_cref_stack(iseqdat, klass, noex);
406
+ iseqdat->klass = klass;
407
+ iseqdat->defined_method_id = SYM2ID(id);
408
+ n = NEW_METHOD(iseqdat->self, klass, NUM2INT(noex));
409
+ goto add_node;
410
+ }
411
+ #endif
412
+
413
+ if(!rb_obj_is_kind_of(node, rb_cNode))
414
+ {
415
+ rb_raise(
416
+ rb_eTypeError,
417
+ "Expected Node for 2nd parameter, got %s",
418
+ rb_class2name(CLASS_OF(n)));
419
+ }
420
+
421
+ Data_Get_Struct(node, NODE, n);
422
+
423
+ #ifdef RUBY_VM
424
+ if(nd_type(n) != NODE_METHOD)
425
+ {
426
+ rb_raise(
427
+ rb_eTypeError,
428
+ "Expected METHOD node, got %s",
429
+ rb_class2name(CLASS_OF(n)));
430
+ }
431
+
432
+ rb_iseq_t *iseqdat = iseq_check((VALUE)n->nd_body);
433
+ set_cref_stack(iseqdat, klass, noex);
434
+ iseqdat->klass = klass;
435
+ iseqdat->defined_method_id = SYM2ID(id);
436
+ n = NEW_METHOD(iseqdat->self, klass, NUM2INT(noex));
437
+
438
+ add_node:
439
+ #endif
440
+ /* TODO: if noex is NOEX_MODFUNC, add this method as a module function
441
+ * (that is, both as an instance and singleton method)
442
+ */
443
+ rb_add_method(klass, SYM2ID(id), n, NUM2INT(noex));
444
+ return Qnil;
445
+ }
446
+
447
+ /*
448
+ * call-seq:
449
+ * uninclude(module, ...) => self
450
+ *
451
+ * Removes the specified module(s) from the inheritance chain.
452
+ */
453
+ static VALUE module_uninclude(int argc, VALUE * argv, VALUE module)
454
+ {
455
+ int i;
456
+
457
+ for (i = 0; i < argc; i++)
458
+ Check_Type(argv[i], T_MODULE);
459
+ while (argc--) {
460
+ rb_funcall(argv[argc], rb_intern("remove_features"), 1, module);
461
+ rb_funcall(argv[argc], rb_intern("unincluded"), 1, module);
462
+ }
463
+ return module;
464
+ }
465
+
466
+ /*
467
+ * call-seq:
468
+ * remove_features(mod) => mod
469
+ *
470
+ * When this module is unincluded from another, Nodewrap calls
471
+ * remove_features in this module. The default behavior is to remove
472
+ * the constants, methods, and module variables of this module from
473
+ * _mod_. If this module has not been included by _mod_, an exception
474
+ * will be raised.
475
+ */
476
+ static VALUE module_remove_features(VALUE module, VALUE uninclude)
477
+ {
478
+ VALUE prev, mod;
479
+
480
+ if(TYPE(uninclude) != T_CLASS && TYPE(uninclude) != T_MODULE)
481
+ {
482
+ Check_Type(uninclude, T_CLASS);
483
+ }
484
+
485
+ rb_frozen_class_p(uninclude);
486
+ if(!OBJ_TAINTED(uninclude))
487
+ {
488
+ rb_secure(4);
489
+ }
490
+
491
+ OBJ_INFECT(uninclude, module);
492
+
493
+ if(RCLASS(uninclude)->m_tbl == RCLASS(module)->m_tbl)
494
+ {
495
+ rb_raise(rb_eArgError, "Cannot remove module from itself");
496
+ }
497
+
498
+ prev = uninclude;
499
+ mod = RCLASS_SUPER(uninclude);
500
+
501
+ while(mod)
502
+ {
503
+ if(RCLASS(module)->m_tbl == RCLASS(mod)->m_tbl)
504
+ {
505
+ RCLASS_SUPER(prev) = RCLASS_SUPER(mod);
506
+ rb_clear_cache();
507
+ return module;
508
+ }
509
+
510
+ if(BUILTIN_TYPE(mod) == T_CLASS)
511
+ {
512
+ break;
513
+ }
514
+
515
+ prev = mod;
516
+ mod = RCLASS_SUPER(mod);
517
+ }
518
+
519
+ rb_raise(rb_eArgError, "Could not find included module");
520
+ return module;
521
+ }
522
+
523
+ /*
524
+ * call-seq:
525
+ * module.unincluded(uninclude) => nil
526
+ *
527
+ * Callback when a module is unincluded. Should not normally be called
528
+ * by the user.
529
+ */
530
+ static VALUE module_unincluded(VALUE module, VALUE uninclude)
531
+ {
532
+ return Qnil;
533
+ }
534
+
535
+ /*
536
+ * call-seq:
537
+ * class.real_superclass => Class
538
+ *
539
+ * Return the immediate superclass of a class or module. This may be a
540
+ * base class, a singleton class, or a module singleton.
541
+ */
542
+ VALUE module_real_superclass(VALUE self)
543
+ {
544
+ VALUE super = RCLASS_SUPER(self);
545
+ rb_include_module(rb_class_of(super), rb_mKernel);
546
+ return super;
547
+ }
548
+
549
+ /*
550
+ * call-seq:
551
+ * module.dump(limit) => String
552
+ *
553
+ * Dump a module to a string. The module will be dumped along with its
554
+ * instance methods, class variables, names of included modules, name of
555
+ * superclass, its entire metaclass, and the name of the class.
556
+ *
557
+ * Note that on ruby 1.8 and newer the module is temporarily modified
558
+ * while dumping in order to allow singleton classes to be dumped. To
559
+ * prevent access to the modifed module, Thread.critical is temporarily
560
+ * set, then restored to its original value once dumping is complete.
561
+ * Note also that because YARV does not support Thread.critical, the
562
+ * user must synchronize access to the class with a Mutex in order to
563
+ * prevent accessing the modified class.
564
+ */
565
+ static VALUE module_dump(VALUE self, VALUE limit)
566
+ {
567
+ VALUE flags, instance_methods, class_variables;
568
+ VALUE included_modules, superclass, metaclass, arr, str, class_name;
569
+
570
+ limit = INT2NUM(NUM2INT(limit) - 1);
571
+
572
+ if(rb_safe_level() >= 4)
573
+ {
574
+ /* no access to potentially sensitive data from the sandbox */
575
+ rb_raise(rb_eSecurityError, "Insecure: can't dump module");
576
+ }
577
+
578
+ flags = INT2NUM(RBASIC(self)->flags);
579
+ instance_methods = instance_method_hash(self);
580
+ class_variables = class_variable_hash(self);
581
+ included_modules = included_modules_list(self);
582
+ superclass = superclass_name(self);
583
+ arr = rb_ary_new();
584
+
585
+ if(FL_TEST(self, FL_SINGLETON))
586
+ {
587
+ metaclass = Qnil;
588
+ class_name = Qnil;
589
+ }
590
+ else
591
+ {
592
+ metaclass = rb_singleton_class(self);
593
+ class_name = rb_class_path(self);
594
+ }
595
+
596
+ rb_ary_push(arr, flags);
597
+ rb_ary_push(arr, marshal_dump(instance_methods, limit));
598
+ rb_ary_push(arr, marshal_dump(class_variables, limit));
599
+ rb_ary_push(arr, included_modules);
600
+ rb_ary_push(arr, superclass);
601
+ rb_ary_push(arr, marshal_dump(metaclass, limit));
602
+ rb_ary_push(arr, class_name);
603
+
604
+ str = marshal_dump(arr, limit);
605
+
606
+ #if RUBY_VERSION_CODE > 180
607
+ {
608
+ VALUE class_restorer = create_class_restorer(self);
609
+ rb_iv_set(str, "__class_restorer__", class_restorer);
610
+ set_class_restore_state(self);
611
+ }
612
+ #endif
613
+
614
+ return str;
615
+ }
616
+
617
+ static void include_modules(module, included_modules)
618
+ {
619
+ size_t j;
620
+ VALUE v;
621
+ VALUE name;
622
+
623
+ rb_check_type(included_modules, T_ARRAY);
624
+ for(j = 0; j < RARRAY_LEN(included_modules); ++j)
625
+ {
626
+ name = RARRAY_PTR(included_modules)[j];
627
+ v = lookup_module(name);
628
+ rb_funcall(module, rb_intern("include"), 1, v);
629
+ }
630
+ }
631
+
632
+ static int add_method_iter(VALUE name, VALUE value, VALUE module)
633
+ {
634
+ NODE * n;
635
+ rb_check_type(name, T_SYMBOL);
636
+ if(!rb_obj_is_kind_of(value, rb_cNode))
637
+ {
638
+ rb_raise(
639
+ rb_eTypeError,
640
+ "Expected Node, but got %s",
641
+ rb_class2name(CLASS_OF(value)));
642
+ }
643
+ Data_Get_Struct(value, NODE, n);
644
+ rb_add_method(module, SYM2ID(name), n->nd_body, n->nd_noex);
645
+ return ST_CONTINUE;
646
+ }
647
+
648
+ static void add_methods(VALUE module, VALUE methods)
649
+ {
650
+ rb_check_type(methods, T_HASH);
651
+ #ifdef RUBY_VM
652
+ if(RHASH(methods)->ntbl)
653
+ {
654
+ st_foreach(RHASH(methods)->ntbl, add_method_iter, module);
655
+ }
656
+ #else
657
+ st_foreach(RHASH(methods)->tbl, add_method_iter, module);
658
+ #endif
659
+ }
660
+
661
+ static int set_cvar_from_hash(VALUE key, VALUE value, VALUE module)
662
+ {
663
+ #ifdef RB_CVAR_SET_4ARGS
664
+ rb_cvar_set(module, SYM2ID(key), value, Qtrue);
665
+ #else
666
+ rb_cvar_set(module, SYM2ID(key), value);
667
+ #endif
668
+ return ST_CONTINUE;
669
+ }
670
+
671
+ static void add_class_variables(VALUE module, VALUE class_variables)
672
+ {
673
+ rb_check_type(class_variables, T_HASH);
674
+ #ifdef RUBY_VM
675
+ if(RHASH(class_variables)->ntbl)
676
+ {
677
+ st_foreach(RHASH(class_variables)->ntbl, set_cvar_from_hash, module);
678
+ }
679
+ #else
680
+ st_foreach(RHASH(class_variables)->tbl, set_cvar_from_hash, module);
681
+ #endif
682
+ }
683
+
684
+ /*
685
+ * call-seq:
686
+ * Module.load(String) => Module
687
+ *
688
+ * Load a module from a string.
689
+ */
690
+ static VALUE module_load(VALUE klass, VALUE str)
691
+ {
692
+ VALUE arr, class_name, metaclass_str, metaclass, superclass_name,
693
+ included_modules, class_variables_str, class_variables,
694
+ instance_methods_str, instance_methods, flags, module;
695
+
696
+ if( rb_safe_level() >= 4
697
+ || (rb_safe_level() >= 1 && OBJ_TAINTED(str)))
698
+ {
699
+ /* no playing with knives in the sandbox */
700
+ rb_raise(rb_eSecurityError, "Insecure: can't load module");
701
+ }
702
+
703
+ arr = marshal_load(str);
704
+ class_name = rb_ary_pop(arr);
705
+ metaclass_str = rb_ary_pop(arr);
706
+ superclass_name = rb_ary_pop(arr);
707
+ included_modules = rb_ary_pop(arr);
708
+ class_variables_str = rb_ary_pop(arr);
709
+ instance_methods_str = rb_ary_pop(arr);
710
+ flags = rb_ary_pop(arr);
711
+
712
+ if(RTEST(superclass_name))
713
+ {
714
+ VALUE superclass;
715
+ rb_check_type(superclass_name, T_STRING);
716
+ superclass = rb_funcall(
717
+ lookup_module_proc,
718
+ rb_intern("call"),
719
+ 1,
720
+ superclass_name);
721
+ #if RUBY_VERSION_CODE >= 180
722
+ /* Can't make subclass of Class on 1.8.x */
723
+ module = rb_class_boot(superclass);
724
+ rb_define_alloc_func(module, module_instance_allocate);
725
+ #else
726
+ module = rb_class_new(superclass);
727
+ #endif
728
+ }
729
+ else
730
+ {
731
+ module = rb_module_new();
732
+ }
733
+
734
+ if(!NIL_P(class_name))
735
+ {
736
+ VALUE outer_module = rb_funcall(outer_module_proc, rb_intern("call"), 1, class_name);
737
+ VALUE module_name = rb_funcall(module_name_proc, rb_intern("call"), 1, class_name);
738
+ rb_const_set(outer_module, SYM2ID(module_name), module);
739
+ }
740
+
741
+ RBASIC(module)->flags = NUM2INT(flags);
742
+ include_modules(module, included_modules);
743
+ class_variables = marshal_load(class_variables_str);
744
+ add_class_variables(module, class_variables);
745
+ instance_methods = marshal_load(instance_methods_str);
746
+ add_methods(module, instance_methods);
747
+
748
+ metaclass = marshal_load(metaclass_str);
749
+ if(RTEST(metaclass))
750
+ {
751
+ rb_singleton_class_attached(metaclass, module);
752
+ RBASIC(module)->klass = metaclass;
753
+ }
754
+
755
+ return module;
756
+ }
757
+
758
+ void Init_module(void)
759
+ {
760
+ rb_require("internal/node");
761
+ rb_cNode = rb_const_get(rb_cObject, rb_intern("Node"));
762
+
763
+ rb_mMarshal = rb_const_get(rb_cObject, rb_intern("Marshal"));
764
+
765
+ /* For rdoc: rb_cModule = rb_define_class("Module", rb_cObject) */
766
+ rb_cModule = rb_const_get(rb_cObject, rb_intern("Module"));
767
+ rb_define_method(rb_cModule, "add_method", module_add_method, 3);
768
+ rb_define_private_method(rb_cModule, "uninclude", module_uninclude, -1);
769
+ rb_define_private_method(rb_cModule, "remove_features", module_remove_features, 1);
770
+ rb_define_private_method(rb_cModule, "unincluded", module_unincluded, 1);
771
+ rb_define_method(rb_cModule, "real_superclass", module_real_superclass, 0);
772
+
773
+ lookup_module_proc = rb_eval_string(lookup_module_str);
774
+ rb_global_variable(&lookup_module_proc);
775
+
776
+ outer_module_proc = rb_eval_string(outer_module_str);
777
+ rb_global_variable(&outer_module_proc);
778
+
779
+ module_name_proc = rb_eval_string(module_name_str);
780
+ rb_global_variable(&module_name_proc);
781
+
782
+ #if RUBY_VERSION_CODE >= 180
783
+ VALUE rb_mNodewrap = rb_define_module("Nodewrap");
784
+ rb_cClass_Restorer = rb_define_class_under(rb_mNodewrap, "ClassRestorer", rb_cObject);
785
+ rb_define_method(rb_cClass_Restorer, "_dump", class_restorer_dump, 1);
786
+ rb_define_singleton_method(rb_cClass_Restorer, "_load", class_restorer_load, 1);
787
+ #endif
788
+
789
+ #if RUBY_VERSION_CODE == 180
790
+ rb_alias(CLASS_OF(rb_mMarshal), rb_intern("_Nodewrap__orig_dump"), rb_intern("dump"));
791
+ rb_define_singleton_method(rb_mMarshal, "dump", ruby180_marshal_dump, -1);
792
+ #endif
793
+
794
+ rb_define_method(rb_cModule, "_dump", module_dump, 1);
795
+ rb_define_singleton_method(rb_cModule, "_load", module_load, 1);
796
+ }
797
+