enclave 0.1.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 (739) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +182 -0
  3. data/Rakefile +30 -0
  4. data/ext/enclave/enclave.c +390 -0
  5. data/ext/enclave/extconf.rb +33 -0
  6. data/ext/enclave/mruby/Makefile +63 -0
  7. data/ext/enclave/mruby/Rakefile +102 -0
  8. data/ext/enclave/mruby/benchmark/bm_ao_render.rb +309 -0
  9. data/ext/enclave/mruby/benchmark/bm_app_lc_fizzbuzz.rb +51 -0
  10. data/ext/enclave/mruby/benchmark/bm_fib.rb +6 -0
  11. data/ext/enclave/mruby/benchmark/bm_mandel_term.rb +34 -0
  12. data/ext/enclave/mruby/benchmark/bm_so_lists.rb +49 -0
  13. data/ext/enclave/mruby/benchmark/bm_so_mandelbrot.rb +65 -0
  14. data/ext/enclave/mruby/benchmark/vm_dispatch_bench.c +197 -0
  15. data/ext/enclave/mruby/benchmark/vm_optimization_bench.rb +513 -0
  16. data/ext/enclave/mruby/build/host/include/mrbconf.h +230 -0
  17. data/ext/enclave/mruby/build/host/include/mruby/array.h +303 -0
  18. data/ext/enclave/mruby/build/host/include/mruby/boxing_nan.h +169 -0
  19. data/ext/enclave/mruby/build/host/include/mruby/boxing_no.h +59 -0
  20. data/ext/enclave/mruby/build/host/include/mruby/boxing_word.h +248 -0
  21. data/ext/enclave/mruby/build/host/include/mruby/class.h +157 -0
  22. data/ext/enclave/mruby/build/host/include/mruby/common.h +127 -0
  23. data/ext/enclave/mruby/build/host/include/mruby/compile.h +187 -0
  24. data/ext/enclave/mruby/build/host/include/mruby/data.h +76 -0
  25. data/ext/enclave/mruby/build/host/include/mruby/debug.h +75 -0
  26. data/ext/enclave/mruby/build/host/include/mruby/dump.h +159 -0
  27. data/ext/enclave/mruby/build/host/include/mruby/endian.h +44 -0
  28. data/ext/enclave/mruby/build/host/include/mruby/error.h +168 -0
  29. data/ext/enclave/mruby/build/host/include/mruby/gc.h +77 -0
  30. data/ext/enclave/mruby/build/host/include/mruby/hash.h +234 -0
  31. data/ext/enclave/mruby/build/host/include/mruby/internal.h +278 -0
  32. data/ext/enclave/mruby/build/host/include/mruby/irep.h +142 -0
  33. data/ext/enclave/mruby/build/host/include/mruby/istruct.h +50 -0
  34. data/ext/enclave/mruby/build/host/include/mruby/khash.h +455 -0
  35. data/ext/enclave/mruby/build/host/include/mruby/mempool.h +19 -0
  36. data/ext/enclave/mruby/build/host/include/mruby/numeric.h +174 -0
  37. data/ext/enclave/mruby/build/host/include/mruby/object.h +44 -0
  38. data/ext/enclave/mruby/build/host/include/mruby/opcode.h +73 -0
  39. data/ext/enclave/mruby/build/host/include/mruby/ops.h +133 -0
  40. data/ext/enclave/mruby/build/host/include/mruby/presym/id.h +895 -0
  41. data/ext/enclave/mruby/build/host/include/mruby/presym/scanning.h +82 -0
  42. data/ext/enclave/mruby/build/host/include/mruby/presym/table.h +1787 -0
  43. data/ext/enclave/mruby/build/host/include/mruby/presym.h +65 -0
  44. data/ext/enclave/mruby/build/host/include/mruby/proc.h +184 -0
  45. data/ext/enclave/mruby/build/host/include/mruby/range.h +77 -0
  46. data/ext/enclave/mruby/build/host/include/mruby/re.h +16 -0
  47. data/ext/enclave/mruby/build/host/include/mruby/string.h +428 -0
  48. data/ext/enclave/mruby/build/host/include/mruby/throw.h +81 -0
  49. data/ext/enclave/mruby/build/host/include/mruby/value.h +471 -0
  50. data/ext/enclave/mruby/build/host/include/mruby/variable.h +108 -0
  51. data/ext/enclave/mruby/build/host/include/mruby/version.h +143 -0
  52. data/ext/enclave/mruby/build/host/include/mruby.h +1632 -0
  53. data/ext/enclave/mruby/build/host/mrbc/include/mruby/presym/id.h +281 -0
  54. data/ext/enclave/mruby/build/host/mrbc/include/mruby/presym/table.h +559 -0
  55. data/ext/enclave/mruby/build/host/mrbgems/gem_init.c +164 -0
  56. data/ext/enclave/mruby/build/host/mrbgems/mruby-array-ext/gem_init.c +650 -0
  57. data/ext/enclave/mruby/build/host/mrbgems/mruby-binding/gem_init.c +21 -0
  58. data/ext/enclave/mruby/build/host/mrbgems/mruby-catch/gem_init.c +86 -0
  59. data/ext/enclave/mruby/build/host/mrbgems/mruby-class-ext/gem_init.c +21 -0
  60. data/ext/enclave/mruby/build/host/mrbgems/mruby-compar-ext/gem_init.c +99 -0
  61. data/ext/enclave/mruby/build/host/mrbgems/mruby-complex/gem_init.c +362 -0
  62. data/ext/enclave/mruby/build/host/mrbgems/mruby-data/gem_init.c +21 -0
  63. data/ext/enclave/mruby/build/host/mrbgems/mruby-enum-chain/gem_init.c +229 -0
  64. data/ext/enclave/mruby/build/host/mrbgems/mruby-enum-ext/gem_init.c +1420 -0
  65. data/ext/enclave/mruby/build/host/mrbgems/mruby-enum-lazy/gem_init.c +602 -0
  66. data/ext/enclave/mruby/build/host/mrbgems/mruby-enumerator/gem_init.c +822 -0
  67. data/ext/enclave/mruby/build/host/mrbgems/mruby-eval/gem_init.c +21 -0
  68. data/ext/enclave/mruby/build/host/mrbgems/mruby-fiber/gem_init.c +21 -0
  69. data/ext/enclave/mruby/build/host/mrbgems/mruby-hash-ext/gem_init.c +591 -0
  70. data/ext/enclave/mruby/build/host/mrbgems/mruby-kernel-ext/gem_init.c +21 -0
  71. data/ext/enclave/mruby/build/host/mrbgems/mruby-math/gem_init.c +21 -0
  72. data/ext/enclave/mruby/build/host/mrbgems/mruby-metaprog/gem_init.c +21 -0
  73. data/ext/enclave/mruby/build/host/mrbgems/mruby-method/gem_init.c +153 -0
  74. data/ext/enclave/mruby/build/host/mrbgems/mruby-numeric-ext/gem_init.c +211 -0
  75. data/ext/enclave/mruby/build/host/mrbgems/mruby-object-ext/gem_init.c +94 -0
  76. data/ext/enclave/mruby/build/host/mrbgems/mruby-objectspace/gem_init.c +21 -0
  77. data/ext/enclave/mruby/build/host/mrbgems/mruby-pack/gem_init.c +21 -0
  78. data/ext/enclave/mruby/build/host/mrbgems/mruby-proc-binding/gem_init.c +21 -0
  79. data/ext/enclave/mruby/build/host/mrbgems/mruby-proc-ext/gem_init.c +237 -0
  80. data/ext/enclave/mruby/build/host/mrbgems/mruby-random/gem_init.c +21 -0
  81. data/ext/enclave/mruby/build/host/mrbgems/mruby-range-ext/gem_init.c +205 -0
  82. data/ext/enclave/mruby/build/host/mrbgems/mruby-rational/gem_init.c +147 -0
  83. data/ext/enclave/mruby/build/host/mrbgems/mruby-set/gem_init.c +487 -0
  84. data/ext/enclave/mruby/build/host/mrbgems/mruby-sprintf/gem_init.c +83 -0
  85. data/ext/enclave/mruby/build/host/mrbgems/mruby-string-ext/gem_init.c +220 -0
  86. data/ext/enclave/mruby/build/host/mrbgems/mruby-struct/gem_init.c +175 -0
  87. data/ext/enclave/mruby/build/host/mrbgems/mruby-symbol-ext/gem_init.c +153 -0
  88. data/ext/enclave/mruby/build/host/mrbgems/mruby-time/gem_init.c +21 -0
  89. data/ext/enclave/mruby/build/host/mrbgems/mruby-toplevel-ext/gem_init.c +78 -0
  90. data/ext/enclave/mruby/build/host/mrblib/mrblib.c +1758 -0
  91. data/ext/enclave/mruby/build_config/ArduinoDue.rb +72 -0
  92. data/ext/enclave/mruby/build_config/IntelEdison.rb +69 -0
  93. data/ext/enclave/mruby/build_config/IntelGalileo.rb +88 -0
  94. data/ext/enclave/mruby/build_config/RX630.rb +63 -0
  95. data/ext/enclave/mruby/build_config/android_arm64_v8a.rb +11 -0
  96. data/ext/enclave/mruby/build_config/android_armeabi_v7a_neon_hard.rb +13 -0
  97. data/ext/enclave/mruby/build_config/bench.rb +11 -0
  98. data/ext/enclave/mruby/build_config/boxing.rb +19 -0
  99. data/ext/enclave/mruby/build_config/chipKITMax32.rb +68 -0
  100. data/ext/enclave/mruby/build_config/ci/gcc-clang.rb +40 -0
  101. data/ext/enclave/mruby/build_config/ci/msvc.rb +20 -0
  102. data/ext/enclave/mruby/build_config/clang-asan.rb +11 -0
  103. data/ext/enclave/mruby/build_config/cosmopolitan.rb +86 -0
  104. data/ext/enclave/mruby/build_config/cross-32bit.rb +14 -0
  105. data/ext/enclave/mruby/build_config/cross-mingw-winetest.rb +90 -0
  106. data/ext/enclave/mruby/build_config/cross-mingw.rb +14 -0
  107. data/ext/enclave/mruby/build_config/default.rb +83 -0
  108. data/ext/enclave/mruby/build_config/dreamcast_shelf.rb +81 -0
  109. data/ext/enclave/mruby/build_config/emscripten-cxx.rb +12 -0
  110. data/ext/enclave/mruby/build_config/emscripten.rb +10 -0
  111. data/ext/enclave/mruby/build_config/gameboyadvance.rb +72 -0
  112. data/ext/enclave/mruby/build_config/helpers/wine_runner.rb +71 -0
  113. data/ext/enclave/mruby/build_config/host-cxx.rb +12 -0
  114. data/ext/enclave/mruby/build_config/host-debug.rb +20 -0
  115. data/ext/enclave/mruby/build_config/host-f32.rb +14 -0
  116. data/ext/enclave/mruby/build_config/host-gprof.rb +14 -0
  117. data/ext/enclave/mruby/build_config/host-m32.rb +15 -0
  118. data/ext/enclave/mruby/build_config/host-nofloat.rb +22 -0
  119. data/ext/enclave/mruby/build_config/host-shared.rb +36 -0
  120. data/ext/enclave/mruby/build_config/i586-pc-msdosdjgpp.rb +76 -0
  121. data/ext/enclave/mruby/build_config/luckfox_pico.rb +106 -0
  122. data/ext/enclave/mruby/build_config/milkv_duo.rb +106 -0
  123. data/ext/enclave/mruby/build_config/minimal.rb +4 -0
  124. data/ext/enclave/mruby/build_config/mrbc.rb +10 -0
  125. data/ext/enclave/mruby/build_config/nintendo_switch.rb +73 -0
  126. data/ext/enclave/mruby/build_config/nintendo_wii.rb +95 -0
  127. data/ext/enclave/mruby/build_config/no-float.rb +17 -0
  128. data/ext/enclave/mruby/build_config/playstationportable.rb +78 -0
  129. data/ext/enclave/mruby/build_config/serenity.rb +26 -0
  130. data/ext/enclave/mruby/build_config.rb +9 -0
  131. data/ext/enclave/mruby/examples/mrbgems/c_and_ruby_extension_example/mrblib/example.rb +5 -0
  132. data/ext/enclave/mruby/examples/mrbgems/c_and_ruby_extension_example/src/example.c +23 -0
  133. data/ext/enclave/mruby/examples/mrbgems/c_and_ruby_extension_example/test/example.rb +7 -0
  134. data/ext/enclave/mruby/examples/mrbgems/c_extension_example/src/example.c +23 -0
  135. data/ext/enclave/mruby/examples/mrbgems/c_extension_example/test/example.c +7 -0
  136. data/ext/enclave/mruby/examples/mrbgems/c_extension_example/test/example.rb +3 -0
  137. data/ext/enclave/mruby/examples/mrbgems/cdata_extension_example/src/example.c +77 -0
  138. data/ext/enclave/mruby/examples/mrbgems/cdata_extension_example/test/example.c +7 -0
  139. data/ext/enclave/mruby/examples/mrbgems/mruby-YOUR-bigint/core/bigint.c +70 -0
  140. data/ext/enclave/mruby/examples/mrbgems/ruby_extension_example/mrblib/example.rb +5 -0
  141. data/ext/enclave/mruby/examples/mrbgems/ruby_extension_example/test/example.rb +3 -0
  142. data/ext/enclave/mruby/include/mrbconf.h +230 -0
  143. data/ext/enclave/mruby/include/mruby/array.h +303 -0
  144. data/ext/enclave/mruby/include/mruby/boxing_nan.h +169 -0
  145. data/ext/enclave/mruby/include/mruby/boxing_no.h +59 -0
  146. data/ext/enclave/mruby/include/mruby/boxing_word.h +248 -0
  147. data/ext/enclave/mruby/include/mruby/class.h +157 -0
  148. data/ext/enclave/mruby/include/mruby/common.h +127 -0
  149. data/ext/enclave/mruby/include/mruby/compile.h +187 -0
  150. data/ext/enclave/mruby/include/mruby/data.h +76 -0
  151. data/ext/enclave/mruby/include/mruby/debug.h +75 -0
  152. data/ext/enclave/mruby/include/mruby/dump.h +159 -0
  153. data/ext/enclave/mruby/include/mruby/endian.h +44 -0
  154. data/ext/enclave/mruby/include/mruby/error.h +168 -0
  155. data/ext/enclave/mruby/include/mruby/gc.h +77 -0
  156. data/ext/enclave/mruby/include/mruby/hash.h +234 -0
  157. data/ext/enclave/mruby/include/mruby/internal.h +278 -0
  158. data/ext/enclave/mruby/include/mruby/irep.h +142 -0
  159. data/ext/enclave/mruby/include/mruby/istruct.h +50 -0
  160. data/ext/enclave/mruby/include/mruby/khash.h +455 -0
  161. data/ext/enclave/mruby/include/mruby/mempool.h +19 -0
  162. data/ext/enclave/mruby/include/mruby/numeric.h +174 -0
  163. data/ext/enclave/mruby/include/mruby/object.h +44 -0
  164. data/ext/enclave/mruby/include/mruby/opcode.h +73 -0
  165. data/ext/enclave/mruby/include/mruby/ops.h +133 -0
  166. data/ext/enclave/mruby/include/mruby/presym/scanning.h +82 -0
  167. data/ext/enclave/mruby/include/mruby/presym.h +65 -0
  168. data/ext/enclave/mruby/include/mruby/proc.h +184 -0
  169. data/ext/enclave/mruby/include/mruby/range.h +77 -0
  170. data/ext/enclave/mruby/include/mruby/re.h +16 -0
  171. data/ext/enclave/mruby/include/mruby/string.h +428 -0
  172. data/ext/enclave/mruby/include/mruby/throw.h +81 -0
  173. data/ext/enclave/mruby/include/mruby/value.h +471 -0
  174. data/ext/enclave/mruby/include/mruby/variable.h +108 -0
  175. data/ext/enclave/mruby/include/mruby/version.h +143 -0
  176. data/ext/enclave/mruby/include/mruby.h +1632 -0
  177. data/ext/enclave/mruby/lib/mruby/amalgam.rb +568 -0
  178. data/ext/enclave/mruby/lib/mruby/build/command.rb +383 -0
  179. data/ext/enclave/mruby/lib/mruby/build/load_gems.rb +383 -0
  180. data/ext/enclave/mruby/lib/mruby/build.rb +616 -0
  181. data/ext/enclave/mruby/lib/mruby/core_ext.rb +61 -0
  182. data/ext/enclave/mruby/lib/mruby/doc.rb +51 -0
  183. data/ext/enclave/mruby/lib/mruby/gem.rb +585 -0
  184. data/ext/enclave/mruby/lib/mruby/lockfile.rb +81 -0
  185. data/ext/enclave/mruby/lib/mruby/presym.rb +167 -0
  186. data/ext/enclave/mruby/lib/mruby/source.rb +32 -0
  187. data/ext/enclave/mruby/mrbgems/default-no-fpu.gembox +3 -0
  188. data/ext/enclave/mruby/mrbgems/default-no-stdio.gembox +4 -0
  189. data/ext/enclave/mruby/mrbgems/default.gembox +25 -0
  190. data/ext/enclave/mruby/mrbgems/full-core.gembox +6 -0
  191. data/ext/enclave/mruby/mrbgems/hal-posix-dir/mrbgem.rake +7 -0
  192. data/ext/enclave/mruby/mrbgems/hal-posix-dir/src/dir_hal.c +193 -0
  193. data/ext/enclave/mruby/mrbgems/hal-posix-io/mrbgem.rake +8 -0
  194. data/ext/enclave/mruby/mrbgems/hal-posix-io/src/io_hal.c +602 -0
  195. data/ext/enclave/mruby/mrbgems/hal-posix-socket/mrbgem.rake +8 -0
  196. data/ext/enclave/mruby/mrbgems/hal-posix-socket/src/socket_hal.c +158 -0
  197. data/ext/enclave/mruby/mrbgems/hal-posix-task/README.md +102 -0
  198. data/ext/enclave/mruby/mrbgems/hal-posix-task/mrbgem.rake +8 -0
  199. data/ext/enclave/mruby/mrbgems/hal-posix-task/src/task_hal.c +252 -0
  200. data/ext/enclave/mruby/mrbgems/hal-win-dir/mrbgem.rake +7 -0
  201. data/ext/enclave/mruby/mrbgems/hal-win-dir/src/dir_hal.c +249 -0
  202. data/ext/enclave/mruby/mrbgems/hal-win-io/mrbgem.rake +11 -0
  203. data/ext/enclave/mruby/mrbgems/hal-win-io/src/io_hal.c +646 -0
  204. data/ext/enclave/mruby/mrbgems/hal-win-socket/mrbgem.rake +12 -0
  205. data/ext/enclave/mruby/mrbgems/hal-win-socket/src/socket_hal.c +177 -0
  206. data/ext/enclave/mruby/mrbgems/hal-win-task/README.md +109 -0
  207. data/ext/enclave/mruby/mrbgems/hal-win-task/mrbgem.rake +11 -0
  208. data/ext/enclave/mruby/mrbgems/hal-win-task/src/task_hal.c +187 -0
  209. data/ext/enclave/mruby/mrbgems/math.gembox +12 -0
  210. data/ext/enclave/mruby/mrbgems/metaprog.gembox +21 -0
  211. data/ext/enclave/mruby/mrbgems/mruby-array-ext/README.md +87 -0
  212. data/ext/enclave/mruby/mrbgems/mruby-array-ext/mrbgem.rake +5 -0
  213. data/ext/enclave/mruby/mrbgems/mruby-array-ext/mrblib/array.rb +784 -0
  214. data/ext/enclave/mruby/mrbgems/mruby-array-ext/src/array.c +1583 -0
  215. data/ext/enclave/mruby/mrbgems/mruby-array-ext/test/array.rb +849 -0
  216. data/ext/enclave/mruby/mrbgems/mruby-benchmark/README.md +257 -0
  217. data/ext/enclave/mruby/mrbgems/mruby-benchmark/mrbgem.rake +10 -0
  218. data/ext/enclave/mruby/mrbgems/mruby-benchmark/mrblib/benchmark.rb +131 -0
  219. data/ext/enclave/mruby/mrbgems/mruby-benchmark/test/benchmark.rb +244 -0
  220. data/ext/enclave/mruby/mrbgems/mruby-bigint/README-fgmp.md +154 -0
  221. data/ext/enclave/mruby/mrbgems/mruby-bigint/README.md +44 -0
  222. data/ext/enclave/mruby/mrbgems/mruby-bigint/core/bigint.c +6335 -0
  223. data/ext/enclave/mruby/mrbgems/mruby-bigint/core/bigint.h +117 -0
  224. data/ext/enclave/mruby/mrbgems/mruby-bigint/mrbgem.rake +10 -0
  225. data/ext/enclave/mruby/mrbgems/mruby-bigint/test/bigint.rb +157 -0
  226. data/ext/enclave/mruby/mrbgems/mruby-bin-config/README.md +46 -0
  227. data/ext/enclave/mruby/mrbgems/mruby-bin-config/mrbgem.rake +49 -0
  228. data/ext/enclave/mruby/mrbgems/mruby-bin-config/mruby-config +46 -0
  229. data/ext/enclave/mruby/mrbgems/mruby-bin-config/mruby-config.bat +92 -0
  230. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/README.md +63 -0
  231. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/bintest/mrdb.rb +283 -0
  232. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/bintest/print.rb +703 -0
  233. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/mrbgem.rake +10 -0
  234. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c +523 -0
  235. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.h +26 -0
  236. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c +238 -0
  237. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.h +14 -0
  238. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.c +88 -0
  239. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.h +13 -0
  240. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apistring.c +34 -0
  241. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apistring.h +14 -0
  242. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdbreak.c +436 -0
  243. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c +509 -0
  244. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdprint.c +71 -0
  245. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c +64 -0
  246. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c +768 -0
  247. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.h +159 -0
  248. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdbconf.h +24 -0
  249. data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdberror.h +19 -0
  250. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/README.md +94 -0
  251. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/bintest/mirb.rb +58 -0
  252. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/mrbgem.rake +7 -0
  253. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c +808 -0
  254. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_buffer.c +1035 -0
  255. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_buffer.h +185 -0
  256. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_completion.c +797 -0
  257. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_completion.h +132 -0
  258. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_editor.c +1118 -0
  259. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_editor.h +153 -0
  260. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_highlight.c +516 -0
  261. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_highlight.h +95 -0
  262. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_history.c +185 -0
  263. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_history.h +76 -0
  264. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_term.c +491 -0
  265. data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_term.h +137 -0
  266. data/ext/enclave/mruby/mrbgems/mruby-bin-mrbc/README.md +58 -0
  267. data/ext/enclave/mruby/mrbgems/mruby-bin-mrbc/bintest/mrbc.rb +30 -0
  268. data/ext/enclave/mruby/mrbgems/mruby-bin-mrbc/mrbgem.rake +15 -0
  269. data/ext/enclave/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c +362 -0
  270. data/ext/enclave/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/stub.c +104 -0
  271. data/ext/enclave/mruby/mrbgems/mruby-bin-mruby/README.md +47 -0
  272. data/ext/enclave/mruby/mrbgems/mruby-bin-mruby/bintest/mruby.rb +178 -0
  273. data/ext/enclave/mruby/mrbgems/mruby-bin-mruby/mrbgem.rake +7 -0
  274. data/ext/enclave/mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c +380 -0
  275. data/ext/enclave/mruby/mrbgems/mruby-bin-strip/README.md +38 -0
  276. data/ext/enclave/mruby/mrbgems/mruby-bin-strip/bintest/mruby_strip.rb +73 -0
  277. data/ext/enclave/mruby/mrbgems/mruby-bin-strip/mrbgem.rake +7 -0
  278. data/ext/enclave/mruby/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby_strip.c +139 -0
  279. data/ext/enclave/mruby/mrbgems/mruby-binding/README.md +256 -0
  280. data/ext/enclave/mruby/mrbgems/mruby-binding/mrbgem.rake +7 -0
  281. data/ext/enclave/mruby/mrbgems/mruby-binding/src/binding.c +518 -0
  282. data/ext/enclave/mruby/mrbgems/mruby-binding/test/binding.c +14 -0
  283. data/ext/enclave/mruby/mrbgems/mruby-binding/test/binding.rb +64 -0
  284. data/ext/enclave/mruby/mrbgems/mruby-catch/README.md +94 -0
  285. data/ext/enclave/mruby/mrbgems/mruby-catch/mrbgem.rake +5 -0
  286. data/ext/enclave/mruby/mrbgems/mruby-catch/mrblib/catch.rb +29 -0
  287. data/ext/enclave/mruby/mrbgems/mruby-catch/src/catch.c +149 -0
  288. data/ext/enclave/mruby/mrbgems/mruby-catch/test/catch.rb +86 -0
  289. data/ext/enclave/mruby/mrbgems/mruby-class-ext/README.md +81 -0
  290. data/ext/enclave/mruby/mrbgems/mruby-class-ext/mrbgem.rake +5 -0
  291. data/ext/enclave/mruby/mrbgems/mruby-class-ext/src/class.c +377 -0
  292. data/ext/enclave/mruby/mrbgems/mruby-class-ext/test/class.rb +46 -0
  293. data/ext/enclave/mruby/mrbgems/mruby-class-ext/test/module.rb +109 -0
  294. data/ext/enclave/mruby/mrbgems/mruby-cmath/README.md +45 -0
  295. data/ext/enclave/mruby/mrbgems/mruby-cmath/mrbgem.rake +8 -0
  296. data/ext/enclave/mruby/mrbgems/mruby-cmath/src/cmath.c +426 -0
  297. data/ext/enclave/mruby/mrbgems/mruby-cmath/test/cmath.rb +41 -0
  298. data/ext/enclave/mruby/mrbgems/mruby-compar-ext/README.md +65 -0
  299. data/ext/enclave/mruby/mrbgems/mruby-compar-ext/mrbgem.rake +5 -0
  300. data/ext/enclave/mruby/mrbgems/mruby-compar-ext/mrblib/compar.rb +75 -0
  301. data/ext/enclave/mruby/mrbgems/mruby-compar-ext/test/compar.rb +21 -0
  302. data/ext/enclave/mruby/mrbgems/mruby-compiler/README.md +28 -0
  303. data/ext/enclave/mruby/mrbgems/mruby-compiler/core/codegen.c +7316 -0
  304. data/ext/enclave/mruby/mrbgems/mruby-compiler/core/keywords +52 -0
  305. data/ext/enclave/mruby/mrbgems/mruby-compiler/core/lex.def +207 -0
  306. data/ext/enclave/mruby/mrbgems/mruby-compiler/core/node.h +784 -0
  307. data/ext/enclave/mruby/mrbgems/mruby-compiler/core/parse.y +8977 -0
  308. data/ext/enclave/mruby/mrbgems/mruby-compiler/core/y.tab.c +16136 -0
  309. data/ext/enclave/mruby/mrbgems/mruby-compiler/mrbgem.rake +42 -0
  310. data/ext/enclave/mruby/mrbgems/mruby-complex/README.md +55 -0
  311. data/ext/enclave/mruby/mrbgems/mruby-complex/mrbgem.rake +7 -0
  312. data/ext/enclave/mruby/mrbgems/mruby-complex/mrblib/complex.rb +259 -0
  313. data/ext/enclave/mruby/mrbgems/mruby-complex/src/complex.c +597 -0
  314. data/ext/enclave/mruby/mrbgems/mruby-complex/test/complex.rb +174 -0
  315. data/ext/enclave/mruby/mrbgems/mruby-data/README.md +126 -0
  316. data/ext/enclave/mruby/mrbgems/mruby-data/mrbgem.rake +5 -0
  317. data/ext/enclave/mruby/mrbgems/mruby-data/src/data.c +550 -0
  318. data/ext/enclave/mruby/mrbgems/mruby-data/test/data.rb +76 -0
  319. data/ext/enclave/mruby/mrbgems/mruby-dir/README.md +53 -0
  320. data/ext/enclave/mruby/mrbgems/mruby-dir/include/dir_hal.h +79 -0
  321. data/ext/enclave/mruby/mrbgems/mruby-dir/mrbgem.rake +35 -0
  322. data/ext/enclave/mruby/mrbgems/mruby-dir/mrblib/dir.rb +124 -0
  323. data/ext/enclave/mruby/mrbgems/mruby-dir/src/dir.c +493 -0
  324. data/ext/enclave/mruby/mrbgems/mruby-dir/test/dir.rb +138 -0
  325. data/ext/enclave/mruby/mrbgems/mruby-dir/test/dirtest.c +125 -0
  326. data/ext/enclave/mruby/mrbgems/mruby-encoding/README.md +96 -0
  327. data/ext/enclave/mruby/mrbgems/mruby-encoding/mrbgem.rake +8 -0
  328. data/ext/enclave/mruby/mrbgems/mruby-encoding/src/encoding.c +128 -0
  329. data/ext/enclave/mruby/mrbgems/mruby-encoding/test/numeric.rb +27 -0
  330. data/ext/enclave/mruby/mrbgems/mruby-encoding/test/string.rb +30 -0
  331. data/ext/enclave/mruby/mrbgems/mruby-enum-chain/README.md +80 -0
  332. data/ext/enclave/mruby/mrbgems/mruby-enum-chain/mrbgem.rake +6 -0
  333. data/ext/enclave/mruby/mrbgems/mruby-enum-chain/mrblib/chain.rb +149 -0
  334. data/ext/enclave/mruby/mrbgems/mruby-enum-chain/test/enum_chain.rb +108 -0
  335. data/ext/enclave/mruby/mrbgems/mruby-enum-ext/README.md +487 -0
  336. data/ext/enclave/mruby/mrbgems/mruby-enum-ext/mrbgem.rake +5 -0
  337. data/ext/enclave/mruby/mrbgems/mruby-enum-ext/mrblib/enum.rb +938 -0
  338. data/ext/enclave/mruby/mrbgems/mruby-enum-ext/test/enum.rb +223 -0
  339. data/ext/enclave/mruby/mrbgems/mruby-enum-lazy/README.md +91 -0
  340. data/ext/enclave/mruby/mrbgems/mruby-enum-lazy/mrbgem.rake +7 -0
  341. data/ext/enclave/mruby/mrbgems/mruby-enum-lazy/mrblib/lazy.rb +363 -0
  342. data/ext/enclave/mruby/mrbgems/mruby-enum-lazy/test/lazy.rb +59 -0
  343. data/ext/enclave/mruby/mrbgems/mruby-enumerator/README.md +89 -0
  344. data/ext/enclave/mruby/mrbgems/mruby-enumerator/mrbgem.rake +6 -0
  345. data/ext/enclave/mruby/mrbgems/mruby-enumerator/mrblib/enumerator.rb +861 -0
  346. data/ext/enclave/mruby/mrbgems/mruby-enumerator/test/enumerator.rb +664 -0
  347. data/ext/enclave/mruby/mrbgems/mruby-errno/README.md +83 -0
  348. data/ext/enclave/mruby/mrbgems/mruby-errno/mrbgem.rake +5 -0
  349. data/ext/enclave/mruby/mrbgems/mruby-errno/mrblib/errno.rb +50 -0
  350. data/ext/enclave/mruby/mrbgems/mruby-errno/src/errno.c +335 -0
  351. data/ext/enclave/mruby/mrbgems/mruby-errno/src/gen.rb +18 -0
  352. data/ext/enclave/mruby/mrbgems/mruby-errno/src/known_errors.def +156 -0
  353. data/ext/enclave/mruby/mrbgems/mruby-errno/src/known_errors_def.cstub +780 -0
  354. data/ext/enclave/mruby/mrbgems/mruby-errno/test/errno.rb +57 -0
  355. data/ext/enclave/mruby/mrbgems/mruby-error/README.md +103 -0
  356. data/ext/enclave/mruby/mrbgems/mruby-error/mrbgem.rake +5 -0
  357. data/ext/enclave/mruby/mrbgems/mruby-error/src/exception.c +143 -0
  358. data/ext/enclave/mruby/mrbgems/mruby-error/test/exception.c +60 -0
  359. data/ext/enclave/mruby/mrbgems/mruby-error/test/exception.rb +55 -0
  360. data/ext/enclave/mruby/mrbgems/mruby-eval/README.md +26 -0
  361. data/ext/enclave/mruby/mrbgems/mruby-eval/mrbgem.rake +10 -0
  362. data/ext/enclave/mruby/mrbgems/mruby-eval/src/eval.c +437 -0
  363. data/ext/enclave/mruby/mrbgems/mruby-eval/test/binding.rb +81 -0
  364. data/ext/enclave/mruby/mrbgems/mruby-eval/test/eval.rb +185 -0
  365. data/ext/enclave/mruby/mrbgems/mruby-exit/mrbgem.rake +5 -0
  366. data/ext/enclave/mruby/mrbgems/mruby-exit/src/mruby_exit.c +83 -0
  367. data/ext/enclave/mruby/mrbgems/mruby-fiber/mrbgem.rake +5 -0
  368. data/ext/enclave/mruby/mrbgems/mruby-fiber/src/fiber.c +575 -0
  369. data/ext/enclave/mruby/mrbgems/mruby-fiber/test/fiber.rb +210 -0
  370. data/ext/enclave/mruby/mrbgems/mruby-fiber/test/fiber2.rb +155 -0
  371. data/ext/enclave/mruby/mrbgems/mruby-fiber/test/fibertest.c +87 -0
  372. data/ext/enclave/mruby/mrbgems/mruby-hash-ext/README.md +392 -0
  373. data/ext/enclave/mruby/mrbgems/mruby-hash-ext/mrbgem.rake +6 -0
  374. data/ext/enclave/mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb +408 -0
  375. data/ext/enclave/mruby/mrbgems/mruby-hash-ext/src/hash_ext.c +392 -0
  376. data/ext/enclave/mruby/mrbgems/mruby-hash-ext/test/hash.rb +317 -0
  377. data/ext/enclave/mruby/mrbgems/mruby-io/README.md +198 -0
  378. data/ext/enclave/mruby/mrbgems/mruby-io/include/io_hal.h +451 -0
  379. data/ext/enclave/mruby/mrbgems/mruby-io/include/mruby/io.h +76 -0
  380. data/ext/enclave/mruby/mrbgems/mruby-io/mrbgem.rake +34 -0
  381. data/ext/enclave/mruby/mrbgems/mruby-io/mrblib/file.rb +109 -0
  382. data/ext/enclave/mruby/mrbgems/mruby-io/mrblib/file_constants.rb +24 -0
  383. data/ext/enclave/mruby/mrbgems/mruby-io/mrblib/io.rb +303 -0
  384. data/ext/enclave/mruby/mrbgems/mruby-io/mrblib/kernel.rb +175 -0
  385. data/ext/enclave/mruby/mrbgems/mruby-io/src/file.c +1192 -0
  386. data/ext/enclave/mruby/mrbgems/mruby-io/src/file_test.c +403 -0
  387. data/ext/enclave/mruby/mrbgems/mruby-io/src/io.c +2260 -0
  388. data/ext/enclave/mruby/mrbgems/mruby-io/src/mruby_io_gem.c +21 -0
  389. data/ext/enclave/mruby/mrbgems/mruby-io/test/file.rb +415 -0
  390. data/ext/enclave/mruby/mrbgems/mruby-io/test/file_test.rb +112 -0
  391. data/ext/enclave/mruby/mrbgems/mruby-io/test/io.rb +668 -0
  392. data/ext/enclave/mruby/mrbgems/mruby-io/test/mruby_io_test.c +293 -0
  393. data/ext/enclave/mruby/mrbgems/mruby-kernel-ext/README.md +165 -0
  394. data/ext/enclave/mruby/mrbgems/mruby-kernel-ext/mrbgem.rake +5 -0
  395. data/ext/enclave/mruby/mrbgems/mruby-kernel-ext/src/kernel.c +316 -0
  396. data/ext/enclave/mruby/mrbgems/mruby-kernel-ext/test/kernel.rb +134 -0
  397. data/ext/enclave/mruby/mrbgems/mruby-math/README.md +77 -0
  398. data/ext/enclave/mruby/mrbgems/mruby-math/mrbgem.rake +5 -0
  399. data/ext/enclave/mruby/mrbgems/mruby-math/src/math.c +753 -0
  400. data/ext/enclave/mruby/mrbgems/mruby-math/test/math.rb +201 -0
  401. data/ext/enclave/mruby/mrbgems/mruby-metaprog/README.md +123 -0
  402. data/ext/enclave/mruby/mrbgems/mruby-metaprog/mrbgem.rake +5 -0
  403. data/ext/enclave/mruby/mrbgems/mruby-metaprog/src/metaprog.c +739 -0
  404. data/ext/enclave/mruby/mrbgems/mruby-metaprog/test/metaprog.rb +465 -0
  405. data/ext/enclave/mruby/mrbgems/mruby-method/README.md +66 -0
  406. data/ext/enclave/mruby/mrbgems/mruby-method/mrbgem.rake +7 -0
  407. data/ext/enclave/mruby/mrbgems/mruby-method/mrblib/method.rb +73 -0
  408. data/ext/enclave/mruby/mrbgems/mruby-method/src/method.c +890 -0
  409. data/ext/enclave/mruby/mrbgems/mruby-method/test/method.rb +514 -0
  410. data/ext/enclave/mruby/mrbgems/mruby-numeric-ext/README.md +78 -0
  411. data/ext/enclave/mruby/mrbgems/mruby-numeric-ext/mrbgem.rake +5 -0
  412. data/ext/enclave/mruby/mrbgems/mruby-numeric-ext/mrblib/numeric_ext.rb +125 -0
  413. data/ext/enclave/mruby/mrbgems/mruby-numeric-ext/src/numeric_ext.c +527 -0
  414. data/ext/enclave/mruby/mrbgems/mruby-numeric-ext/test/numeric.rb +137 -0
  415. data/ext/enclave/mruby/mrbgems/mruby-object-ext/README.md +144 -0
  416. data/ext/enclave/mruby/mrbgems/mruby-object-ext/mrbgem.rake +5 -0
  417. data/ext/enclave/mruby/mrbgems/mruby-object-ext/mrblib/object.rb +33 -0
  418. data/ext/enclave/mruby/mrbgems/mruby-object-ext/src/object.c +128 -0
  419. data/ext/enclave/mruby/mrbgems/mruby-object-ext/test/nil.rb +16 -0
  420. data/ext/enclave/mruby/mrbgems/mruby-object-ext/test/object.rb +67 -0
  421. data/ext/enclave/mruby/mrbgems/mruby-object-ext/test/object_ext.c +17 -0
  422. data/ext/enclave/mruby/mrbgems/mruby-objectspace/README.md +59 -0
  423. data/ext/enclave/mruby/mrbgems/mruby-objectspace/mrbgem.rake +5 -0
  424. data/ext/enclave/mruby/mrbgems/mruby-objectspace/src/mruby_objectspace.c +188 -0
  425. data/ext/enclave/mruby/mrbgems/mruby-objectspace/test/objectspace.rb +60 -0
  426. data/ext/enclave/mruby/mrbgems/mruby-os-memsize/README.md +75 -0
  427. data/ext/enclave/mruby/mrbgems/mruby-os-memsize/mrbgem.rake +10 -0
  428. data/ext/enclave/mruby/mrbgems/mruby-os-memsize/src/memsize.c +271 -0
  429. data/ext/enclave/mruby/mrbgems/mruby-os-memsize/test/memsize.rb +63 -0
  430. data/ext/enclave/mruby/mrbgems/mruby-pack/README.md +140 -0
  431. data/ext/enclave/mruby/mrbgems/mruby-pack/mrbgem.rake +5 -0
  432. data/ext/enclave/mruby/mrbgems/mruby-pack/src/pack.c +2129 -0
  433. data/ext/enclave/mruby/mrbgems/mruby-pack/test/pack.rb +202 -0
  434. data/ext/enclave/mruby/mrbgems/mruby-proc-binding/README.md +140 -0
  435. data/ext/enclave/mruby/mrbgems/mruby-proc-binding/mrbgem.rake +10 -0
  436. data/ext/enclave/mruby/mrbgems/mruby-proc-binding/src/proc_binding.c +76 -0
  437. data/ext/enclave/mruby/mrbgems/mruby-proc-binding/test/proc_binding.c +14 -0
  438. data/ext/enclave/mruby/mrbgems/mruby-proc-binding/test/proc_binding.rb +22 -0
  439. data/ext/enclave/mruby/mrbgems/mruby-proc-ext/README.md +107 -0
  440. data/ext/enclave/mruby/mrbgems/mruby-proc-ext/mrbgem.rake +5 -0
  441. data/ext/enclave/mruby/mrbgems/mruby-proc-ext/mrblib/proc.rb +130 -0
  442. data/ext/enclave/mruby/mrbgems/mruby-proc-ext/src/proc.c +267 -0
  443. data/ext/enclave/mruby/mrbgems/mruby-proc-ext/test/proc.c +62 -0
  444. data/ext/enclave/mruby/mrbgems/mruby-proc-ext/test/proc.rb +130 -0
  445. data/ext/enclave/mruby/mrbgems/mruby-random/README.md +272 -0
  446. data/ext/enclave/mruby/mrbgems/mruby-random/mrbgem.rake +5 -0
  447. data/ext/enclave/mruby/mrbgems/mruby-random/src/random.c +608 -0
  448. data/ext/enclave/mruby/mrbgems/mruby-random/test/random.rb +151 -0
  449. data/ext/enclave/mruby/mrbgems/mruby-range-ext/README.md +93 -0
  450. data/ext/enclave/mruby/mrbgems/mruby-range-ext/mrbgem.rake +5 -0
  451. data/ext/enclave/mruby/mrbgems/mruby-range-ext/mrblib/range.rb +155 -0
  452. data/ext/enclave/mruby/mrbgems/mruby-range-ext/src/range.c +236 -0
  453. data/ext/enclave/mruby/mrbgems/mruby-range-ext/test/range.rb +211 -0
  454. data/ext/enclave/mruby/mrbgems/mruby-rational/README.md +61 -0
  455. data/ext/enclave/mruby/mrbgems/mruby-rational/mrbgem.rake +7 -0
  456. data/ext/enclave/mruby/mrbgems/mruby-rational/mrblib/rational.rb +66 -0
  457. data/ext/enclave/mruby/mrbgems/mruby-rational/src/rational.c +1269 -0
  458. data/ext/enclave/mruby/mrbgems/mruby-rational/test/rational.rb +316 -0
  459. data/ext/enclave/mruby/mrbgems/mruby-set/LICENSE +24 -0
  460. data/ext/enclave/mruby/mrbgems/mruby-set/README.md +260 -0
  461. data/ext/enclave/mruby/mrbgems/mruby-set/mrbgem.rake +9 -0
  462. data/ext/enclave/mruby/mrbgems/mruby-set/mrblib/set.rb +325 -0
  463. data/ext/enclave/mruby/mrbgems/mruby-set/mruby-set.gem +6 -0
  464. data/ext/enclave/mruby/mrbgems/mruby-set/src/set.c +1535 -0
  465. data/ext/enclave/mruby/mrbgems/mruby-set/test/set.rb +764 -0
  466. data/ext/enclave/mruby/mrbgems/mruby-sleep/README.md +29 -0
  467. data/ext/enclave/mruby/mrbgems/mruby-sleep/example/sleep.rb +2 -0
  468. data/ext/enclave/mruby/mrbgems/mruby-sleep/mrbgem.rake +5 -0
  469. data/ext/enclave/mruby/mrbgems/mruby-sleep/src/sleep.c +187 -0
  470. data/ext/enclave/mruby/mrbgems/mruby-sleep/test/sleep_test.rb +29 -0
  471. data/ext/enclave/mruby/mrbgems/mruby-socket/README.md +56 -0
  472. data/ext/enclave/mruby/mrbgems/mruby-socket/include/socket_hal.h +83 -0
  473. data/ext/enclave/mruby/mrbgems/mruby-socket/mrbgem.rake +37 -0
  474. data/ext/enclave/mruby/mrbgems/mruby-socket/mrblib/socket.rb +1131 -0
  475. data/ext/enclave/mruby/mrbgems/mruby-socket/src/const.cstub +480 -0
  476. data/ext/enclave/mruby/mrbgems/mruby-socket/src/const.def +172 -0
  477. data/ext/enclave/mruby/mrbgems/mruby-socket/src/gen.rb +17 -0
  478. data/ext/enclave/mruby/mrbgems/mruby-socket/src/socket.c +1374 -0
  479. data/ext/enclave/mruby/mrbgems/mruby-socket/test/addrinfo.rb +91 -0
  480. data/ext/enclave/mruby/mrbgems/mruby-socket/test/basicsocket.rb +17 -0
  481. data/ext/enclave/mruby/mrbgems/mruby-socket/test/ipsocket.rb +44 -0
  482. data/ext/enclave/mruby/mrbgems/mruby-socket/test/socket.rb +38 -0
  483. data/ext/enclave/mruby/mrbgems/mruby-socket/test/sockettest.c +84 -0
  484. data/ext/enclave/mruby/mrbgems/mruby-socket/test/tcpsocket.rb +4 -0
  485. data/ext/enclave/mruby/mrbgems/mruby-socket/test/udpsocket.rb +16 -0
  486. data/ext/enclave/mruby/mrbgems/mruby-socket/test/unix.rb +130 -0
  487. data/ext/enclave/mruby/mrbgems/mruby-sprintf/README.md +235 -0
  488. data/ext/enclave/mruby/mrbgems/mruby-sprintf/mrbgem.rake +5 -0
  489. data/ext/enclave/mruby/mrbgems/mruby-sprintf/mrblib/string.rb +24 -0
  490. data/ext/enclave/mruby/mrbgems/mruby-sprintf/src/sprintf.c +1195 -0
  491. data/ext/enclave/mruby/mrbgems/mruby-sprintf/test/sprintf.rb +92 -0
  492. data/ext/enclave/mruby/mrbgems/mruby-strftime/README.md +140 -0
  493. data/ext/enclave/mruby/mrbgems/mruby-strftime/mrbgem.rake +7 -0
  494. data/ext/enclave/mruby/mrbgems/mruby-strftime/src/strftime.c +119 -0
  495. data/ext/enclave/mruby/mrbgems/mruby-strftime/test/strftime.rb +152 -0
  496. data/ext/enclave/mruby/mrbgems/mruby-string-ext/README.md +886 -0
  497. data/ext/enclave/mruby/mrbgems/mruby-string-ext/mrbgem.rake +5 -0
  498. data/ext/enclave/mruby/mrbgems/mruby-string-ext/mrblib/string.rb +166 -0
  499. data/ext/enclave/mruby/mrbgems/mruby-string-ext/src/string.c +2290 -0
  500. data/ext/enclave/mruby/mrbgems/mruby-string-ext/test/numeric.rb +27 -0
  501. data/ext/enclave/mruby/mrbgems/mruby-string-ext/test/range.rb +26 -0
  502. data/ext/enclave/mruby/mrbgems/mruby-string-ext/test/string.rb +765 -0
  503. data/ext/enclave/mruby/mrbgems/mruby-struct/README.md +105 -0
  504. data/ext/enclave/mruby/mrbgems/mruby-struct/mrbgem.rake +5 -0
  505. data/ext/enclave/mruby/mrbgems/mruby-struct/mrblib/struct.rb +69 -0
  506. data/ext/enclave/mruby/mrbgems/mruby-struct/src/struct.c +812 -0
  507. data/ext/enclave/mruby/mrbgems/mruby-struct/test/struct.rb +303 -0
  508. data/ext/enclave/mruby/mrbgems/mruby-symbol-ext/README.md +50 -0
  509. data/ext/enclave/mruby/mrbgems/mruby-symbol-ext/mrbgem.rake +5 -0
  510. data/ext/enclave/mruby/mrbgems/mruby-symbol-ext/mrblib/symbol.rb +72 -0
  511. data/ext/enclave/mruby/mrbgems/mruby-symbol-ext/src/symbol.c +79 -0
  512. data/ext/enclave/mruby/mrbgems/mruby-symbol-ext/test/symbol.rb +55 -0
  513. data/ext/enclave/mruby/mrbgems/mruby-task/README.md +770 -0
  514. data/ext/enclave/mruby/mrbgems/mruby-task/examples/inspection.rb +65 -0
  515. data/ext/enclave/mruby/mrbgems/mruby-task/examples/priority.rb +41 -0
  516. data/ext/enclave/mruby/mrbgems/mruby-task/examples/producer_consumer.rb +58 -0
  517. data/ext/enclave/mruby/mrbgems/mruby-task/examples/simple.rb +27 -0
  518. data/ext/enclave/mruby/mrbgems/mruby-task/examples/statistics.rb +59 -0
  519. data/ext/enclave/mruby/mrbgems/mruby-task/examples/suspend_resume.rb +47 -0
  520. data/ext/enclave/mruby/mrbgems/mruby-task/examples/task_pass.rb +21 -0
  521. data/ext/enclave/mruby/mrbgems/mruby-task/include/task.h +143 -0
  522. data/ext/enclave/mruby/mrbgems/mruby-task/include/task_hal.h +162 -0
  523. data/ext/enclave/mruby/mrbgems/mruby-task/mrbgem.rake +36 -0
  524. data/ext/enclave/mruby/mrbgems/mruby-task/src/task.c +1573 -0
  525. data/ext/enclave/mruby/mrbgems/mruby-task/test/task.rb +185 -0
  526. data/ext/enclave/mruby/mrbgems/mruby-test/README.md +7 -0
  527. data/ext/enclave/mruby/mrbgems/mruby-test/driver.c +315 -0
  528. data/ext/enclave/mruby/mrbgems/mruby-test/mrbgem.rake +173 -0
  529. data/ext/enclave/mruby/mrbgems/mruby-test/vformat.c +151 -0
  530. data/ext/enclave/mruby/mrbgems/mruby-test-inline-struct/mrbgem.rake +5 -0
  531. data/ext/enclave/mruby/mrbgems/mruby-test-inline-struct/test/inline.c +92 -0
  532. data/ext/enclave/mruby/mrbgems/mruby-test-inline-struct/test/inline.rb +118 -0
  533. data/ext/enclave/mruby/mrbgems/mruby-time/README.md +102 -0
  534. data/ext/enclave/mruby/mrbgems/mruby-time/include/mruby/time.h +27 -0
  535. data/ext/enclave/mruby/mrbgems/mruby-time/mrbgem.rake +5 -0
  536. data/ext/enclave/mruby/mrbgems/mruby-time/src/time.c +1739 -0
  537. data/ext/enclave/mruby/mrbgems/mruby-time/test/time.rb +313 -0
  538. data/ext/enclave/mruby/mrbgems/mruby-toplevel-ext/README.md +32 -0
  539. data/ext/enclave/mruby/mrbgems/mruby-toplevel-ext/mrbgem.rake +5 -0
  540. data/ext/enclave/mruby/mrbgems/mruby-toplevel-ext/mrblib/toplevel.rb +24 -0
  541. data/ext/enclave/mruby/mrbgems/mruby-toplevel-ext/test/toplevel.rb +23 -0
  542. data/ext/enclave/mruby/mrbgems/stdlib-ext.gembox +21 -0
  543. data/ext/enclave/mruby/mrbgems/stdlib-io.gembox +15 -0
  544. data/ext/enclave/mruby/mrbgems/stdlib.gembox +63 -0
  545. data/ext/enclave/mruby/mrblib/10error.rb +23 -0
  546. data/ext/enclave/mruby/mrblib/array.rb +102 -0
  547. data/ext/enclave/mruby/mrblib/compar.rb +102 -0
  548. data/ext/enclave/mruby/mrblib/enum.rb +358 -0
  549. data/ext/enclave/mruby/mrblib/hash.rb +276 -0
  550. data/ext/enclave/mruby/mrblib/kernel.rb +45 -0
  551. data/ext/enclave/mruby/mrblib/numeric.rb +160 -0
  552. data/ext/enclave/mruby/mrblib/range.rb +98 -0
  553. data/ext/enclave/mruby/mrblib/string.rb +173 -0
  554. data/ext/enclave/mruby/mrblib/symbol.rb +8 -0
  555. data/ext/enclave/mruby/oss-fuzz/mruby_fuzzer.c +18 -0
  556. data/ext/enclave/mruby/oss-fuzz/proto_to_ruby.h +55 -0
  557. data/ext/enclave/mruby/src/allocf.c +37 -0
  558. data/ext/enclave/mruby/src/array.c +2302 -0
  559. data/ext/enclave/mruby/src/backtrace.c +294 -0
  560. data/ext/enclave/mruby/src/cdump.c +498 -0
  561. data/ext/enclave/mruby/src/class.c +4394 -0
  562. data/ext/enclave/mruby/src/codedump.c +693 -0
  563. data/ext/enclave/mruby/src/debug.c +290 -0
  564. data/ext/enclave/mruby/src/dump.c +998 -0
  565. data/ext/enclave/mruby/src/enum.c +30 -0
  566. data/ext/enclave/mruby/src/error.c +937 -0
  567. data/ext/enclave/mruby/src/etc.c +421 -0
  568. data/ext/enclave/mruby/src/fmt_fp.c +372 -0
  569. data/ext/enclave/mruby/src/gc.c +1610 -0
  570. data/ext/enclave/mruby/src/hash.c +2355 -0
  571. data/ext/enclave/mruby/src/init.c +50 -0
  572. data/ext/enclave/mruby/src/kernel.c +718 -0
  573. data/ext/enclave/mruby/src/load.c +760 -0
  574. data/ext/enclave/mruby/src/mempool.c +225 -0
  575. data/ext/enclave/mruby/src/numeric.c +2420 -0
  576. data/ext/enclave/mruby/src/numops.c +112 -0
  577. data/ext/enclave/mruby/src/object.c +883 -0
  578. data/ext/enclave/mruby/src/print.c +136 -0
  579. data/ext/enclave/mruby/src/proc.c +572 -0
  580. data/ext/enclave/mruby/src/range.c +597 -0
  581. data/ext/enclave/mruby/src/readfloat.c +228 -0
  582. data/ext/enclave/mruby/src/readint.c +27 -0
  583. data/ext/enclave/mruby/src/readnum.c +43 -0
  584. data/ext/enclave/mruby/src/state.c +247 -0
  585. data/ext/enclave/mruby/src/string.c +3577 -0
  586. data/ext/enclave/mruby/src/symbol.c +1023 -0
  587. data/ext/enclave/mruby/src/value_array.h +28 -0
  588. data/ext/enclave/mruby/src/variable.c +1475 -0
  589. data/ext/enclave/mruby/src/version.c +17 -0
  590. data/ext/enclave/mruby/src/vm.c +3696 -0
  591. data/ext/enclave/mruby/tasks/amalgam.rake +34 -0
  592. data/ext/enclave/mruby/tasks/benchmark.rake +93 -0
  593. data/ext/enclave/mruby/tasks/bin.rake +23 -0
  594. data/ext/enclave/mruby/tasks/core.rake +12 -0
  595. data/ext/enclave/mruby/tasks/doc.rake +118 -0
  596. data/ext/enclave/mruby/tasks/install.rake +40 -0
  597. data/ext/enclave/mruby/tasks/libmruby.rake +90 -0
  598. data/ext/enclave/mruby/tasks/mrbgems.rake +152 -0
  599. data/ext/enclave/mruby/tasks/mrblib.rake +29 -0
  600. data/ext/enclave/mruby/tasks/presym.rake +57 -0
  601. data/ext/enclave/mruby/tasks/test.rake +84 -0
  602. data/ext/enclave/mruby/tasks/toolchains/android.rake +228 -0
  603. data/ext/enclave/mruby/tasks/toolchains/clang.rake +8 -0
  604. data/ext/enclave/mruby/tasks/toolchains/emscripten.rake +57 -0
  605. data/ext/enclave/mruby/tasks/toolchains/gcc.rake +74 -0
  606. data/ext/enclave/mruby/tasks/toolchains/openwrt.rake +32 -0
  607. data/ext/enclave/mruby/tasks/toolchains/visualcpp.rake +48 -0
  608. data/ext/enclave/mruby/test/assert.rb +404 -0
  609. data/ext/enclave/mruby/test/bintest.rb +55 -0
  610. data/ext/enclave/mruby/test/t/argumenterror.rb +37 -0
  611. data/ext/enclave/mruby/test/t/array.rb +478 -0
  612. data/ext/enclave/mruby/test/t/basicobject.rb +10 -0
  613. data/ext/enclave/mruby/test/t/bs_block.rb +621 -0
  614. data/ext/enclave/mruby/test/t/bs_literal.rb +38 -0
  615. data/ext/enclave/mruby/test/t/class.rb +505 -0
  616. data/ext/enclave/mruby/test/t/codegen.rb +196 -0
  617. data/ext/enclave/mruby/test/t/comparable.rb +79 -0
  618. data/ext/enclave/mruby/test/t/ensure.rb +36 -0
  619. data/ext/enclave/mruby/test/t/enumerable.rb +134 -0
  620. data/ext/enclave/mruby/test/t/exception.rb +425 -0
  621. data/ext/enclave/mruby/test/t/false.rb +31 -0
  622. data/ext/enclave/mruby/test/t/float.rb +296 -0
  623. data/ext/enclave/mruby/test/t/gc.rb +45 -0
  624. data/ext/enclave/mruby/test/t/hash.rb +976 -0
  625. data/ext/enclave/mruby/test/t/indexerror.rb +6 -0
  626. data/ext/enclave/mruby/test/t/integer.rb +247 -0
  627. data/ext/enclave/mruby/test/t/iterations.rb +61 -0
  628. data/ext/enclave/mruby/test/t/kernel.rb +462 -0
  629. data/ext/enclave/mruby/test/t/lang.rb +74 -0
  630. data/ext/enclave/mruby/test/t/literals.rb +386 -0
  631. data/ext/enclave/mruby/test/t/localjumperror.rb +13 -0
  632. data/ext/enclave/mruby/test/t/methods.rb +138 -0
  633. data/ext/enclave/mruby/test/t/module.rb +931 -0
  634. data/ext/enclave/mruby/test/t/nameerror.rb +28 -0
  635. data/ext/enclave/mruby/test/t/nil.rb +39 -0
  636. data/ext/enclave/mruby/test/t/nomethoderror.rb +22 -0
  637. data/ext/enclave/mruby/test/t/numeric.rb +114 -0
  638. data/ext/enclave/mruby/test/t/object.rb +10 -0
  639. data/ext/enclave/mruby/test/t/proc.rb +198 -0
  640. data/ext/enclave/mruby/test/t/range.rb +194 -0
  641. data/ext/enclave/mruby/test/t/rangeerror.rb +6 -0
  642. data/ext/enclave/mruby/test/t/regexperror.rb +4 -0
  643. data/ext/enclave/mruby/test/t/runtimeerror.rb +6 -0
  644. data/ext/enclave/mruby/test/t/standarderror.rb +6 -0
  645. data/ext/enclave/mruby/test/t/string.rb +981 -0
  646. data/ext/enclave/mruby/test/t/superclass.rb +46 -0
  647. data/ext/enclave/mruby/test/t/symbol.rb +30 -0
  648. data/ext/enclave/mruby/test/t/syntax.rb +1296 -0
  649. data/ext/enclave/mruby/test/t/true.rb +31 -0
  650. data/ext/enclave/mruby/test/t/typeerror.rb +6 -0
  651. data/ext/enclave/mruby/test/t/unicode.rb +39 -0
  652. data/ext/enclave/mruby/test/t/vformat.rb +57 -0
  653. data/ext/enclave/mruby/tools/lrama/LEGAL.md +12 -0
  654. data/ext/enclave/mruby/tools/lrama/MIT +21 -0
  655. data/ext/enclave/mruby/tools/lrama/NEWS.md +696 -0
  656. data/ext/enclave/mruby/tools/lrama/exe/lrama +7 -0
  657. data/ext/enclave/mruby/tools/lrama/lib/lrama/bitmap.rb +34 -0
  658. data/ext/enclave/mruby/tools/lrama/lib/lrama/command.rb +68 -0
  659. data/ext/enclave/mruby/tools/lrama/lib/lrama/context.rb +499 -0
  660. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/derivation.rb +66 -0
  661. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/example.rb +129 -0
  662. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/path.rb +29 -0
  663. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/production_path.rb +19 -0
  664. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/start_path.rb +23 -0
  665. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/state_item.rb +8 -0
  666. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/transition_path.rb +19 -0
  667. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/triple.rb +23 -0
  668. data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples.rb +298 -0
  669. data/ext/enclave/mruby/tools/lrama/lib/lrama/diagnostics.rb +36 -0
  670. data/ext/enclave/mruby/tools/lrama/lib/lrama/digraph.rb +83 -0
  671. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/auxiliary.rb +9 -0
  672. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/binding.rb +67 -0
  673. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/code/destructor_code.rb +42 -0
  674. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/code/initial_action_code.rb +36 -0
  675. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/code/no_reference_code.rb +30 -0
  676. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/code/printer_code.rb +42 -0
  677. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/code/rule_action.rb +92 -0
  678. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/code.rb +53 -0
  679. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/counter.rb +17 -0
  680. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/destructor.rb +11 -0
  681. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/error_token.rb +11 -0
  682. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/parameterizing_rule/resolver.rb +62 -0
  683. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/parameterizing_rule/rhs.rb +40 -0
  684. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/parameterizing_rule/rule.rb +24 -0
  685. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/parameterizing_rule.rb +5 -0
  686. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/percent_code.rb +14 -0
  687. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/precedence.rb +13 -0
  688. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/printer.rb +11 -0
  689. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/reference.rb +16 -0
  690. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/rule.rb +75 -0
  691. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/rule_builder.rb +255 -0
  692. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/stdlib.y +122 -0
  693. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/symbol.rb +105 -0
  694. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/symbols/resolver.rb +301 -0
  695. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/symbols.rb +3 -0
  696. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/type.rb +20 -0
  697. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/union.rb +12 -0
  698. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar.rb +407 -0
  699. data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar_validator.rb +37 -0
  700. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/grammar_file.rb +40 -0
  701. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/location.rb +115 -0
  702. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/token/char.rb +11 -0
  703. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/token/ident.rb +11 -0
  704. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/token/instantiate_rule.rb +30 -0
  705. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/token/tag.rb +16 -0
  706. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/token/user_code.rb +83 -0
  707. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/token.rb +70 -0
  708. data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer.rb +191 -0
  709. data/ext/enclave/mruby/tools/lrama/lib/lrama/logger.rb +21 -0
  710. data/ext/enclave/mruby/tools/lrama/lib/lrama/option_parser.rb +169 -0
  711. data/ext/enclave/mruby/tools/lrama/lib/lrama/options.rb +28 -0
  712. data/ext/enclave/mruby/tools/lrama/lib/lrama/output.rb +459 -0
  713. data/ext/enclave/mruby/tools/lrama/lib/lrama/parser.rb +2144 -0
  714. data/ext/enclave/mruby/tools/lrama/lib/lrama/report/duration.rb +27 -0
  715. data/ext/enclave/mruby/tools/lrama/lib/lrama/report/profile.rb +16 -0
  716. data/ext/enclave/mruby/tools/lrama/lib/lrama/report.rb +4 -0
  717. data/ext/enclave/mruby/tools/lrama/lib/lrama/state/reduce.rb +37 -0
  718. data/ext/enclave/mruby/tools/lrama/lib/lrama/state/reduce_reduce_conflict.rb +11 -0
  719. data/ext/enclave/mruby/tools/lrama/lib/lrama/state/resolved_conflict.rb +31 -0
  720. data/ext/enclave/mruby/tools/lrama/lib/lrama/state/shift.rb +15 -0
  721. data/ext/enclave/mruby/tools/lrama/lib/lrama/state/shift_reduce_conflict.rb +11 -0
  722. data/ext/enclave/mruby/tools/lrama/lib/lrama/state.rb +433 -0
  723. data/ext/enclave/mruby/tools/lrama/lib/lrama/states/item.rb +91 -0
  724. data/ext/enclave/mruby/tools/lrama/lib/lrama/states.rb +595 -0
  725. data/ext/enclave/mruby/tools/lrama/lib/lrama/states_reporter.rb +362 -0
  726. data/ext/enclave/mruby/tools/lrama/lib/lrama/trace_reporter.rb +45 -0
  727. data/ext/enclave/mruby/tools/lrama/lib/lrama/version.rb +5 -0
  728. data/ext/enclave/mruby/tools/lrama/lib/lrama.rb +22 -0
  729. data/ext/enclave/mruby/tools/lrama/template/bison/_yacc.h +71 -0
  730. data/ext/enclave/mruby/tools/lrama/template/bison/yacc.c +2068 -0
  731. data/ext/enclave/mruby/tools/lrama/template/bison/yacc.h +40 -0
  732. data/ext/enclave/sandbox_build_config.rb +15 -0
  733. data/ext/enclave/sandbox_core.c +722 -0
  734. data/ext/enclave/sandbox_core.h +87 -0
  735. data/lib/enclave/result.rb +29 -0
  736. data/lib/enclave/tool.rb +38 -0
  737. data/lib/enclave/version.rb +3 -0
  738. data/lib/enclave.rb +73 -0
  739. metadata +819 -0
@@ -0,0 +1,4394 @@
1
+ /*
2
+ ** class.c - Class class
3
+ **
4
+ ** See Copyright Notice in mruby.h
5
+ */
6
+
7
+ #include <mruby.h>
8
+ #include <mruby/array.h>
9
+ #include <mruby/hash.h>
10
+ #include <mruby/class.h>
11
+ #include <mruby/numeric.h>
12
+ #include <mruby/proc.h>
13
+ #include <mruby/string.h>
14
+ #include <mruby/variable.h>
15
+ #include <mruby/error.h>
16
+ #include <mruby/data.h>
17
+ #include <mruby/istruct.h>
18
+ #include <mruby/opcode.h>
19
+ #include <mruby/internal.h>
20
+ #include <mruby/presym.h>
21
+
22
+ /* mrb_mt_tbl, union mrb_mt_ptr, mrb_mt_entry defined in internal.h */
23
+ #define MT_PROTECTED MRB_METHOD_PROTECTED_FL
24
+ #define MT_VDEFAULT MRB_METHOD_VDEFAULT_FL
25
+ #define MT_VMASK MRB_METHOD_VISIBILITY_MASK
26
+
27
+ #define MRB_MT_FLAG_BITS (MRB_MT_READONLY_BIT | MRB_MT_FROZEN_BIT)
28
+ #define MT_ALLOC(t) ((t)->alloc & ~MRB_MT_FLAG_BITS)
29
+ #define mt_readonly_p(t) ((t)->alloc & MRB_MT_READONLY_BIT)
30
+ #define mt_frozen_p(t) ((t)->alloc & MRB_MT_FROZEN_BIT)
31
+
32
+ /* Allocates or grows the method table to exactly new_alloc entries */
33
+ static void
34
+ mt_grow(mrb_state *mrb, mrb_mt_tbl *t, int new_alloc)
35
+ {
36
+ t->ptr = (mrb_mt_entry*)mrb_realloc(mrb, t->ptr,
37
+ new_alloc * sizeof(mrb_mt_entry));
38
+ t->alloc = (t->alloc & MRB_MT_FLAG_BITS) | new_alloc;
39
+ }
40
+
41
+ /* Creates a new empty method table */
42
+ static mrb_mt_tbl*
43
+ mt_new(mrb_state *mrb)
44
+ {
45
+ mrb_mt_tbl *t;
46
+
47
+ t = (mrb_mt_tbl*)mrb_malloc(mrb, sizeof(mrb_mt_tbl));
48
+ t->size = 0;
49
+ t->alloc = 0;
50
+ t->ptr = NULL;
51
+ t->next = NULL;
52
+
53
+ return t;
54
+ }
55
+
56
+ /* Inserts or updates an entry in the method table (linear scan) */
57
+ static void
58
+ mt_put(mrb_state *mrb, mrb_mt_tbl *t, mrb_sym sym, uint32_t flags, union mrb_mt_ptr ptrval)
59
+ {
60
+ mrb_mt_entry *entries = t->ptr;
61
+
62
+ /* Linear scan for existing key */
63
+ for (int i = 0; i < t->size; i++) {
64
+ if (entries[i].key == sym) {
65
+ entries[i].flags = flags;
66
+ entries[i].val = ptrval;
67
+ return;
68
+ }
69
+ }
70
+
71
+ /* Not found — append to end */
72
+ if (MT_ALLOC(t) == 0) {
73
+ mt_grow(mrb, t, 8);
74
+ }
75
+ else if (t->size == MT_ALLOC(t)) {
76
+ mt_grow(mrb, t, MT_ALLOC(t) * 2);
77
+ }
78
+ entries = t->ptr;
79
+ entries[t->size].key = sym;
80
+ entries[t->size].flags = flags;
81
+ entries[t->size].val = ptrval;
82
+ t->size++;
83
+ }
84
+
85
+ /* Retrieves a value from the method table (walks chain, linear scan).
86
+ Returns TRUE if found, FALSE if not found.
87
+ On success, *pp and *fp are set. */
88
+ static mrb_bool
89
+ mt_get(mrb_state *mrb, mrb_mt_tbl *t, mrb_sym sym, union mrb_mt_ptr *pp, uint32_t *fp)
90
+ {
91
+ while (t) {
92
+ mrb_mt_entry *entries = t->ptr;
93
+ for (int i = 0; i < t->size; i++) {
94
+ if (entries[i].key == sym) {
95
+ if (MRB_MT_REMOVED_P(entries[i])) return FALSE;
96
+ *pp = entries[i].val;
97
+ *fp = entries[i].flags;
98
+ return TRUE;
99
+ }
100
+ }
101
+ t = t->next;
102
+ }
103
+ return FALSE;
104
+ }
105
+
106
+ /* Deletes an entry from the method table (swap with last) */
107
+ static mrb_bool
108
+ mt_del(mrb_state *mrb, mrb_mt_tbl *t, mrb_sym sym)
109
+ {
110
+ if (!t || t->size == 0) return FALSE;
111
+
112
+ mrb_mt_entry *entries = t->ptr;
113
+ for (int i = 0; i < t->size; i++) {
114
+ if (entries[i].key == sym) {
115
+ t->size--;
116
+ if (i < t->size) {
117
+ entries[i] = entries[t->size];
118
+ }
119
+ return TRUE;
120
+ }
121
+ }
122
+ return FALSE;
123
+ }
124
+
125
+ /* Checks if any layer in the chain contains the given symbol */
126
+ static mrb_bool
127
+ mt_chain_has(mrb_mt_tbl *t, mrb_sym sym)
128
+ {
129
+ while (t) {
130
+ mrb_mt_entry *entries = t->ptr;
131
+ for (int i = 0; i < t->size; i++) {
132
+ if (entries[i].key == sym) return TRUE;
133
+ }
134
+ t = t->next;
135
+ }
136
+ return FALSE;
137
+ }
138
+
139
+ /* Creates a copy of the method table */
140
+ static mrb_mt_tbl*
141
+ mt_copy(mrb_state *mrb, mrb_mt_tbl *t)
142
+ {
143
+ if (!t) return NULL;
144
+ if (mt_readonly_p(t)) {
145
+ /* source is ROM — new class gets empty mutable top + shared ROM chain */
146
+ if (t->size == 0 && !t->next) return NULL;
147
+ mrb_mt_tbl *t2 = mt_new(mrb);
148
+ t2->next = t;
149
+ return t2;
150
+ }
151
+ if (t->size == 0 && !t->next) return NULL;
152
+ mrb_mt_tbl *t2 = mt_new(mrb);
153
+ if (t->size > 0) {
154
+ mt_grow(mrb, t2, t->size);
155
+ memcpy(t2->ptr, t->ptr, t->size * sizeof(mrb_mt_entry));
156
+ t2->size = t->size;
157
+ }
158
+ t2->next = t->next; /* share ROM chain */
159
+ return t2;
160
+ }
161
+
162
+ /* Frees memory of the method table (mutable layers only).
163
+ Stops at the first readonly (ROM) layer; ROM wrappers are
164
+ shared (by iclasses, dup, etc.) and freed via mrb->rom_mt
165
+ at state close. */
166
+ static void
167
+ mt_free(mrb_state *mrb, mrb_mt_tbl *t)
168
+ {
169
+ while (t && !mt_readonly_p(t)) {
170
+ mrb_mt_tbl *next = t->next;
171
+ mrb_free(mrb, t->ptr);
172
+ mrb_free(mrb, t);
173
+ t = next;
174
+ }
175
+ }
176
+
177
+ /* Allocates a per-state ROM wrapper for the const entries array
178
+ and pushes it onto the class's method table chain.
179
+ The wrapper is also registered in mrb->rom_mt for cleanup
180
+ at mrb_close, since ROM layers are shared and must not be
181
+ freed by mt_free during normal GC. */
182
+ void
183
+ mrb_mt_init_rom(mrb_state *mrb, struct RClass *c,
184
+ const mrb_mt_entry *entries, int size)
185
+ {
186
+ mrb_mt_tbl *rom = (mrb_mt_tbl*)mrb_malloc(mrb, sizeof(mrb_mt_tbl));
187
+ rom->size = size;
188
+ rom->alloc = size | MRB_MT_READONLY_BIT;
189
+ rom->ptr = (mrb_mt_entry*)entries;
190
+
191
+ /* register for cleanup at mrb_close */
192
+ struct mrb_mt_rom_list *node =
193
+ (struct mrb_mt_rom_list*)mrb_malloc(mrb, sizeof(struct mrb_mt_rom_list));
194
+ node->tbl = rom;
195
+ node->next = mrb->rom_mt;
196
+ mrb->rom_mt = node;
197
+
198
+ /* push ROM layer */
199
+ mrb_mt_tbl *t = c->mt;
200
+ if (!t || mt_readonly_p(t)) {
201
+ rom->next = t;
202
+ c->mt = rom;
203
+ }
204
+ else {
205
+ /* freeze mutable top, insert ROM behind it;
206
+ * c->mt must not change because iclasses (module inclusion)
207
+ * hold a copy of the mt pointer */
208
+ t->alloc |= MRB_MT_FROZEN_BIT;
209
+ rom->next = t->next;
210
+ t->next = rom;
211
+ }
212
+ }
213
+
214
+ /* Creates a method value structure from flags and pointer */
215
+ static inline mrb_method_t
216
+ create_method_value(mrb_state *mrb, uint32_t flags, union mrb_mt_ptr val)
217
+ {
218
+ mrb_method_t m = { flags, { val.proc } };
219
+ return m;
220
+ }
221
+
222
+ /* Iterates over methods in a class's method table with callback function */
223
+ MRB_API void
224
+ mrb_mt_foreach(mrb_state *mrb, struct RClass *c, mrb_mt_foreach_func *fn, void *p)
225
+ {
226
+ mrb_mt_tbl *t = c->mt;
227
+ if (!t) return;
228
+
229
+ /* fast path: single layer */
230
+ if (!t->next) {
231
+ mrb_mt_entry *entries = t->ptr;
232
+ for (int i = 0; i < t->size; i++) {
233
+ if (MRB_MT_REMOVED_P(entries[i])) continue;
234
+ if (fn(mrb, entries[i].key,
235
+ create_method_value(mrb, entries[i].flags, entries[i].val), p) != 0)
236
+ return;
237
+ }
238
+ return;
239
+ }
240
+
241
+ /* multi-layer: iterate each layer, skip if shadowed by a higher one */
242
+ for (mrb_mt_tbl *layer = t; layer; layer = layer->next) {
243
+ mrb_mt_entry *entries = layer->ptr;
244
+ for (int i = 0; i < layer->size; i++) {
245
+ if (MRB_MT_REMOVED_P(entries[i])) continue;
246
+ mrb_sym sym = entries[i].key;
247
+ /* check if shadowed by a higher layer */
248
+ if (layer != t) {
249
+ mrb_bool shadowed = FALSE;
250
+ for (mrb_mt_tbl *upper = t; upper != layer; upper = upper->next) {
251
+ mrb_mt_entry *up = upper->ptr;
252
+ for (int j = 0; j < upper->size; j++) {
253
+ if (up[j].key == sym) {
254
+ shadowed = TRUE;
255
+ break;
256
+ }
257
+ }
258
+ if (shadowed) break;
259
+ }
260
+ if (shadowed) continue;
261
+ }
262
+ if (fn(mrb, sym, create_method_value(mrb, entries[i].flags, entries[i].val), p) != 0)
263
+ return;
264
+ }
265
+ }
266
+ }
267
+
268
+ /* Marks method table entries for garbage collection */
269
+ size_t
270
+ mrb_gc_mark_mt(mrb_state *mrb, struct RClass *c)
271
+ {
272
+ size_t children = 0;
273
+ for (mrb_mt_tbl *t = c->mt; t; t = t->next) {
274
+ if (mt_readonly_p(t)) continue; /* ROM layers need no GC marking */
275
+ if (t->size == 0) continue;
276
+ mrb_mt_entry *entries = t->ptr;
277
+ for (int i = 0; i < t->size; i++) {
278
+ if (entries[i].key != 0 && (entries[i].flags & MRB_MT_FUNC) == 0) {
279
+ mrb_gc_mark(mrb, (struct RBasic*)entries[i].val.proc);
280
+ }
281
+ }
282
+ children += (size_t)t->size;
283
+ }
284
+ return children;
285
+ }
286
+
287
+ /* Returns memory size of class method table (mutable layers only) */
288
+ size_t
289
+ mrb_class_mt_memsize(mrb_state *mrb, struct RClass *c)
290
+ {
291
+ size_t total = 0;
292
+ for (mrb_mt_tbl *h = c->mt; h && !mt_readonly_p(h); h = h->next)
293
+ total += sizeof(mrb_mt_tbl) + (size_t)MT_ALLOC(h) * sizeof(mrb_mt_entry);
294
+ return total;
295
+ }
296
+
297
+ /* Frees mutable layers of the class method table for GC.
298
+ ROM layers are left intact (freed via mrb->rom_mt at close). */
299
+ void
300
+ mrb_gc_free_mt(mrb_state *mrb, struct RClass *c)
301
+ {
302
+ if (c->mt) mt_free(mrb, c->mt);
303
+ }
304
+
305
+ /* Sets the name of a class within an outer namespace */
306
+ void
307
+ mrb_class_name_class(mrb_state *mrb, struct RClass *outer, struct RClass *c, mrb_sym id)
308
+ {
309
+ mrb_value name;
310
+ mrb_sym nsym = MRB_SYM(__classname__);
311
+
312
+ if (mrb_obj_iv_defined(mrb, (struct RObject*)c, nsym)) return;
313
+ if (outer == NULL || outer == mrb->object_class) {
314
+ name = mrb_symbol_value(id);
315
+ }
316
+ else {
317
+ name = mrb_class_path(mrb, outer);
318
+ if (mrb_nil_p(name)) { /* unnamed outer class */
319
+ if (outer != mrb->object_class && outer != c) {
320
+ mrb_obj_iv_set_force(mrb, (struct RObject*)c, MRB_SYM(__outer__),
321
+ mrb_obj_value(outer));
322
+ }
323
+ return;
324
+ }
325
+ else {
326
+ mrb_int len;
327
+ const char *n = mrb_sym_name_len(mrb, id, &len);
328
+
329
+ mrb_str_cat_lit(mrb, name, "::");
330
+ mrb_str_cat(mrb, name, n, len);
331
+ }
332
+ }
333
+ mrb_obj_iv_set_force(mrb, (struct RObject*)c, nsym, name);
334
+ }
335
+
336
+ /* Checks if a name is a valid constant name */
337
+ mrb_bool
338
+ mrb_const_name_p(mrb_state *mrb, const char *name, mrb_int len)
339
+ {
340
+ return len > 0 && ISUPPER(name[0]) && mrb_ident_p(name+1, len-1);
341
+ }
342
+
343
+ /* Sets up a class by defining it as a constant in the outer namespace */
344
+ static void
345
+ setup_class(mrb_state *mrb, struct RClass *outer, struct RClass *c, mrb_sym id)
346
+ {
347
+ mrb_const_set(mrb, mrb_obj_value(outer), id, mrb_obj_value(c));
348
+ }
349
+
350
+ #define make_metaclass(mrb, c) prepare_singleton_class((mrb), (struct RBasic*)(c))
351
+
352
+ /* Prepares and creates a singleton class for an object */
353
+ static void
354
+ prepare_singleton_class(mrb_state *mrb, struct RBasic *o)
355
+ {
356
+ struct RClass *c;
357
+
358
+ mrb_assert(o->c);
359
+ if (o->c->tt == MRB_TT_SCLASS) return;
360
+ struct RClass *sc = MRB_OBJ_ALLOC(mrb, MRB_TT_SCLASS, mrb->class_class);
361
+ sc->flags |= MRB_FL_CLASS_IS_INHERITED;
362
+ sc->mt = NULL;
363
+ sc->iv = NULL;
364
+ if (o->tt == MRB_TT_CLASS) {
365
+ c = (struct RClass*)o;
366
+ if (!c->super) {
367
+ sc->super = mrb->class_class;
368
+ }
369
+ else {
370
+ sc->super = c->super->c;
371
+ }
372
+ }
373
+ else if (o->tt == MRB_TT_SCLASS) {
374
+ c = (struct RClass*)o;
375
+ while (c->super->tt == MRB_TT_ICLASS)
376
+ c = c->super;
377
+ make_metaclass(mrb, c->super);
378
+ sc->super = c->super->c;
379
+ }
380
+ else {
381
+ sc->super = o->c;
382
+ prepare_singleton_class(mrb, (struct RBasic*)sc);
383
+ }
384
+ o->c = sc;
385
+ mrb_field_write_barrier(mrb, (struct RBasic*)o, (struct RBasic*)sc);
386
+ mrb_obj_iv_set(mrb, (struct RObject*)sc, MRB_SYM(__attached__), mrb_obj_value(o));
387
+ sc->frozen = o->frozen;
388
+ }
389
+
390
+ /* Returns a string representation of a class name */
391
+ static mrb_value
392
+ class_name_str(mrb_state *mrb, struct RClass* c)
393
+ {
394
+ mrb_value path = mrb_class_path(mrb, c);
395
+ if (mrb_nil_p(path)) {
396
+ path = c->tt == MRB_TT_MODULE ? mrb_str_new_lit(mrb, "#<Module:") :
397
+ mrb_str_new_lit(mrb, "#<Class:");
398
+ mrb_str_cat_str(mrb, path, mrb_ptr_to_str(mrb, c));
399
+ mrb_str_cat_lit(mrb, path, ">");
400
+ }
401
+ return path;
402
+ }
403
+
404
+ /* Gets a class from a constant symbol, ensuring it's a class */
405
+ static struct RClass*
406
+ class_from_sym(mrb_state *mrb, struct RClass *klass, mrb_sym id)
407
+ {
408
+ mrb_value c = mrb_const_get(mrb, mrb_obj_value(klass), id);
409
+
410
+ mrb_check_type(mrb, c, MRB_TT_CLASS);
411
+ return mrb_class_ptr(c);
412
+ }
413
+
414
+ /* Gets a module from a constant symbol, ensuring it's a module */
415
+ static struct RClass*
416
+ module_from_sym(mrb_state *mrb, struct RClass *klass, mrb_sym id)
417
+ {
418
+ mrb_value c = mrb_const_get(mrb, mrb_obj_value(klass), id);
419
+
420
+ mrb_check_type(mrb, c, MRB_TT_MODULE);
421
+ return mrb_class_ptr(c);
422
+ }
423
+
424
+ /* Checks if an object is a class or module */
425
+ static mrb_bool
426
+ class_ptr_p(mrb_value obj)
427
+ {
428
+ switch (mrb_type(obj)) {
429
+ case MRB_TT_CLASS:
430
+ case MRB_TT_SCLASS:
431
+ case MRB_TT_MODULE:
432
+ return TRUE;
433
+ default:
434
+ return FALSE;
435
+ }
436
+ }
437
+
438
+ /* Checks if object is class/module and raises TypeError if not */
439
+ static void
440
+ check_if_class_or_module(mrb_state *mrb, mrb_value obj)
441
+ {
442
+ if (!class_ptr_p(obj)) {
443
+ mrb_raisef(mrb, E_TYPE_ERROR, "%!v is not a class/module", obj);
444
+ }
445
+ }
446
+
447
+ /* Defines a new module or returns existing one */
448
+ static struct RClass*
449
+ define_module(mrb_state *mrb, mrb_sym name, struct RClass *outer)
450
+ {
451
+ if (mrb_const_defined_at(mrb, mrb_obj_value(outer), name)) {
452
+ return module_from_sym(mrb, outer, name);
453
+ }
454
+ struct RClass *m = mrb_module_new(mrb);
455
+ setup_class(mrb, outer, m, name);
456
+
457
+ return m;
458
+ }
459
+
460
+ /*
461
+ * Defines a new module in the top-level scope (Object) using a symbol for the name.
462
+ *
463
+ * @param mrb The mruby state.
464
+ * @param name The symbol representing the name of the module to define.
465
+ * @return A pointer to the newly defined or existing RClass structure for the module.
466
+ * @sideeffect Creates a new module or returns an existing one if already defined.
467
+ * The module is set as a constant in Object.
468
+ */
469
+ MRB_API struct RClass*
470
+ mrb_define_module_id(mrb_state *mrb, mrb_sym name)
471
+ {
472
+ return define_module(mrb, name, mrb->object_class);
473
+ }
474
+
475
+ /*
476
+ * Defines a new module in the top-level scope (Object).
477
+ *
478
+ * @param mrb The mruby state.
479
+ * @param name The name of the module to define.
480
+ * @return A pointer to the newly defined or existing RClass structure for the module.
481
+ * @sideeffect Creates a new module or returns an existing one if already defined.
482
+ * The module is set as a constant in Object.
483
+ */
484
+ MRB_API struct RClass*
485
+ mrb_define_module(mrb_state *mrb, const char *name)
486
+ {
487
+ return define_module(mrb, mrb_intern_cstr(mrb, name), mrb->object_class);
488
+ }
489
+
490
+ struct RClass*
491
+ mrb_vm_define_module(mrb_state *mrb, mrb_value outer, mrb_sym id)
492
+ {
493
+ check_if_class_or_module(mrb, outer);
494
+ if (mrb_const_defined_at(mrb, outer, id)) {
495
+ mrb_value old = mrb_const_get(mrb, outer, id);
496
+
497
+ if (!mrb_module_p(old)) {
498
+ mrb_raisef(mrb, E_TYPE_ERROR, "%!v is not a module", old);
499
+ }
500
+ return mrb_class_ptr(old);
501
+ }
502
+ return define_module(mrb, id, mrb_class_ptr(outer));
503
+ }
504
+
505
+ /*
506
+ * Defines a new module under the given outer module/class using a symbol for the name.
507
+ *
508
+ * @param mrb The mruby state.
509
+ * @param outer A pointer to the RClass structure of the outer module/class.
510
+ * @param name The symbol representing the name of the module to define.
511
+ * @return A pointer to the newly defined or existing RClass structure for the module.
512
+ * @sideeffect Creates a new module or returns an existing one if already defined under `outer`.
513
+ * The module is set as a constant in `outer`.
514
+ */
515
+ MRB_API struct RClass*
516
+ mrb_define_module_under_id(mrb_state *mrb, struct RClass *outer, mrb_sym name)
517
+ {
518
+ struct RClass * c = define_module(mrb, name, outer);
519
+
520
+ setup_class(mrb, outer, c, name);
521
+ return c;
522
+ }
523
+
524
+ /*
525
+ * Defines a new module under the given outer module/class using a C string for the name.
526
+ *
527
+ * @param mrb The mruby state.
528
+ * @param outer A pointer to the RClass structure of the outer module/class.
529
+ * @param name The C string representing the name of the module to define.
530
+ * @return A pointer to the newly defined or existing RClass structure for the module.
531
+ * @sideeffect Creates a new module or returns an existing one if already defined under `outer`.
532
+ * The module is set as a constant in `outer`.
533
+ */
534
+ MRB_API struct RClass*
535
+ mrb_define_module_under(mrb_state *mrb, struct RClass *outer, const char *name)
536
+ {
537
+ mrb_sym id = mrb_intern_cstr(mrb, name);
538
+ struct RClass * c = define_module(mrb, id, outer);
539
+
540
+ setup_class(mrb, outer, c, id);
541
+ return c;
542
+ }
543
+
544
+ static struct RClass*
545
+ find_origin(struct RClass *c)
546
+ {
547
+ MRB_CLASS_ORIGIN(c);
548
+ return c;
549
+ }
550
+
551
+ static struct RClass*
552
+ define_class(mrb_state *mrb, mrb_sym name, struct RClass *super, struct RClass *outer)
553
+ {
554
+ struct RClass * c;
555
+
556
+ if (mrb_const_defined_at(mrb, mrb_obj_value(outer), name)) {
557
+ c = class_from_sym(mrb, outer, name);
558
+ MRB_CLASS_ORIGIN(c);
559
+ if (super && mrb_class_real(c->super) != super) {
560
+ mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for Class %n (%C not %C)",
561
+ name, c->super, super);
562
+ }
563
+ return c;
564
+ }
565
+
566
+ c = mrb_class_new(mrb, super);
567
+ setup_class(mrb, outer, c, name);
568
+
569
+ return c;
570
+ }
571
+
572
+ /*
573
+ * Defines a new class in the top-level scope (Object) using a symbol for the name.
574
+ *
575
+ * @param mrb The mruby state.
576
+ * @param name The symbol representing the name of the class to define.
577
+ * @param super A pointer to the RClass structure of the superclass.
578
+ * If NULL, Object is assumed as the superclass, and a warning is issued.
579
+ * @return A pointer to the newly defined or existing RClass structure for the class.
580
+ * @sideeffect Creates a new class or returns an existing one if already defined.
581
+ * The class is set as a constant in Object.
582
+ * Issues a warning if `super` is NULL.
583
+ */
584
+ MRB_API struct RClass*
585
+ mrb_define_class_id(mrb_state *mrb, mrb_sym name, struct RClass *super)
586
+ {
587
+ if (!super) {
588
+ mrb_warn(mrb, "no super class for '%n', Object assumed", name);
589
+ }
590
+ return define_class(mrb, name, super, mrb->object_class);
591
+ }
592
+
593
+ /*
594
+ * Defines a new class in the top-level scope (Object).
595
+ *
596
+ * @param mrb The mruby state.
597
+ * @param name The name of the class to define.
598
+ * @param super A pointer to the RClass structure of the superclass.
599
+ * If NULL, Object is assumed as the superclass.
600
+ * @return A pointer to the newly defined or existing RClass structure for the class.
601
+ * @sideeffect Creates a new class or returns an existing one if already defined.
602
+ * The class is set as a constant in Object.
603
+ */
604
+ MRB_API struct RClass*
605
+ mrb_define_class(mrb_state *mrb, const char *name, struct RClass *super)
606
+ {
607
+ return mrb_define_class_id(mrb, mrb_intern_cstr(mrb, name), super);
608
+ }
609
+
610
+ static mrb_value mrb_do_nothing(mrb_state *mrb, mrb_value);
611
+ #ifndef MRB_NO_METHOD_CACHE
612
+ static void mc_clear_by_id(mrb_state *mrb, mrb_sym mid);
613
+ #else
614
+ #define mc_clear(mrb)
615
+ #define mc_clear_by_id(mrb,mid)
616
+ #endif
617
+
618
+ static void
619
+ mrb_class_inherited(mrb_state *mrb, struct RClass *super, struct RClass *klass)
620
+ {
621
+
622
+ if (!super)
623
+ super = mrb->object_class;
624
+ super->flags |= MRB_FL_CLASS_IS_INHERITED;
625
+
626
+ mrb_value s = mrb_obj_value(super);
627
+ mrb_sym mid = MRB_SYM(inherited);
628
+
629
+ if (!mrb_func_basic_p(mrb, s, mid, mrb_do_nothing)) {
630
+ mrb_value c = mrb_obj_value(klass);
631
+ mrb_funcall_argv(mrb, s, mid, 1, &c);
632
+ }
633
+ }
634
+
635
+ struct RClass*
636
+ mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id)
637
+ {
638
+ struct RClass *s;
639
+ struct RClass *c;
640
+
641
+ if (!mrb_nil_p(super)) {
642
+ if (!mrb_class_p(super)) {
643
+ mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%!v given)", super);
644
+ }
645
+ s = mrb_class_ptr(super);
646
+ }
647
+ else {
648
+ s = NULL;
649
+ }
650
+ check_if_class_or_module(mrb, outer);
651
+ if (mrb_const_defined_at(mrb, outer, id)) {
652
+ mrb_value old = mrb_const_get(mrb, outer, id);
653
+
654
+ if (!mrb_class_p(old)) {
655
+ mrb_raisef(mrb, E_TYPE_ERROR, "%!v is not a class", old);
656
+ }
657
+ c = mrb_class_ptr(old);
658
+ if (s) {
659
+ /* check super class */
660
+ if (mrb_class_real(c->super) != s) {
661
+ mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for %v", old);
662
+ }
663
+ }
664
+ return c;
665
+ }
666
+ c = define_class(mrb, id, s, mrb_class_ptr(outer));
667
+ mrb_class_inherited(mrb, mrb_class_real(c->super), c);
668
+
669
+ return c;
670
+ }
671
+
672
+ /*
673
+ * Checks if a class is defined in the top-level scope (Object).
674
+ *
675
+ * @param mrb The mruby state.
676
+ * @param name The name of the class to check.
677
+ * @return TRUE if the class is defined, FALSE otherwise.
678
+ * Returns FALSE if the name is not a valid symbol.
679
+ */
680
+ MRB_API mrb_bool
681
+ mrb_class_defined(mrb_state *mrb, const char *name)
682
+ {
683
+ mrb_sym sym = mrb_intern_check_cstr(mrb, name);
684
+ if (!sym) return FALSE;
685
+ return mrb_const_defined(mrb, mrb_obj_value(mrb->object_class), sym);
686
+ }
687
+
688
+ /*
689
+ * Checks if a class is defined in the top-level scope (Object) using a symbol for the name.
690
+ *
691
+ * @param mrb The mruby state.
692
+ * @param name The symbol representing the name of the class to check.
693
+ * @return TRUE if the class is defined, FALSE otherwise.
694
+ */
695
+ MRB_API mrb_bool
696
+ mrb_class_defined_id(mrb_state *mrb, mrb_sym name)
697
+ {
698
+ return mrb_const_defined(mrb, mrb_obj_value(mrb->object_class), name);
699
+ }
700
+
701
+ /*
702
+ * Checks if a class is defined under the given outer module/class.
703
+ *
704
+ * @param mrb The mruby state.
705
+ * @param outer A pointer to the RClass structure of the outer module/class.
706
+ * @param name The name of the class to check.
707
+ * @return TRUE if the class is defined under `outer`, FALSE otherwise.
708
+ * Returns FALSE if the name is not a valid symbol.
709
+ */
710
+ MRB_API mrb_bool
711
+ mrb_class_defined_under(mrb_state *mrb, struct RClass *outer, const char *name)
712
+ {
713
+ mrb_sym sym = mrb_intern_check_cstr(mrb, name);
714
+ if (!sym) return FALSE;
715
+ return mrb_const_defined_at(mrb, mrb_obj_value(outer), sym);
716
+ }
717
+
718
+ /*
719
+ * Checks if a class is defined under the given outer module/class using a symbol for the name.
720
+ *
721
+ * @param mrb The mruby state.
722
+ * @param outer A pointer to the RClass structure of the outer module/class.
723
+ * @param name The symbol representing the name of the class to check.
724
+ * @return TRUE if the class is defined under `outer`, FALSE otherwise.
725
+ */
726
+ MRB_API mrb_bool
727
+ mrb_class_defined_under_id(mrb_state *mrb, struct RClass *outer, mrb_sym name)
728
+ {
729
+ return mrb_const_defined_at(mrb, mrb_obj_value(outer), name);
730
+ }
731
+
732
+ /*
733
+ * Retrieves a class defined under an outer module/class.
734
+ *
735
+ * @param mrb The mruby state.
736
+ * @param outer A pointer to the RClass structure of the outer module/class.
737
+ * If NULL, Object is assumed.
738
+ * @param name The name of the class to retrieve.
739
+ * @return A pointer to the RClass structure of the found class.
740
+ * @raise TypeError if the constant found is not a class.
741
+ * @raise NameError if the constant is not found.
742
+ */
743
+ MRB_API struct RClass*
744
+ mrb_class_get_under(mrb_state *mrb, struct RClass *outer, const char *name)
745
+ {
746
+ return class_from_sym(mrb, outer, mrb_intern_cstr(mrb, name));
747
+ }
748
+
749
+ /*
750
+ * Retrieves a class defined under an outer module/class using a symbol for the name.
751
+ *
752
+ * @param mrb The mruby state.
753
+ * @param outer A pointer to the RClass structure of the outer module/class.
754
+ * If NULL, Object is assumed.
755
+ * @param name The symbol representing the name of the class to retrieve.
756
+ * @return A pointer to the RClass structure of the found class.
757
+ * @raise TypeError if the constant found is not a class.
758
+ * @raise NameError if the constant is not found.
759
+ */
760
+ MRB_API struct RClass*
761
+ mrb_class_get_under_id(mrb_state *mrb, struct RClass *outer, mrb_sym name)
762
+ {
763
+ return class_from_sym(mrb, outer, name);
764
+ }
765
+
766
+ /*
767
+ * Retrieves a class defined in the top-level scope (Object).
768
+ *
769
+ * @param mrb The mruby state.
770
+ * @param name The name of the class to retrieve.
771
+ * @return A pointer to the RClass structure of the found class.
772
+ * @raise TypeError if the constant found is not a class.
773
+ * @raise NameError if the constant is not found.
774
+ */
775
+ MRB_API struct RClass*
776
+ mrb_class_get(mrb_state *mrb, const char *name)
777
+ {
778
+ return mrb_class_get_under(mrb, mrb->object_class, name);
779
+ }
780
+
781
+ /*
782
+ * Retrieves a class defined in the top-level scope (Object) using a symbol for the name.
783
+ *
784
+ * @param mrb The mruby state.
785
+ * @param name The symbol representing the name of the class to retrieve.
786
+ * @return A pointer to the RClass structure of the found class.
787
+ * @raise TypeError if the constant found is not a class.
788
+ * @raise NameError if the constant is not found.
789
+ */
790
+ MRB_API struct RClass*
791
+ mrb_class_get_id(mrb_state *mrb, mrb_sym name)
792
+ {
793
+ return mrb_class_get_under_id(mrb, mrb->object_class, name);
794
+ }
795
+
796
+ /*
797
+ * Retrieves an exception class by its symbol name.
798
+ * This function specifically searches for exception classes.
799
+ *
800
+ * @param mrb The mruby state.
801
+ * @param name The symbol representing the name of the exception class.
802
+ * @return A pointer to the RClass structure of the found exception class.
803
+ * @raise TypeError if the constant found is not a class.
804
+ * @raise NameError if the constant is not found.
805
+ * @raise Exception if the found class is not an exception (does not inherit from E_EXCEPTION).
806
+ * @raise Exception if the exception system is corrupted.
807
+ */
808
+ MRB_API struct RClass*
809
+ mrb_exc_get_id(mrb_state *mrb, mrb_sym name)
810
+ {
811
+ mrb_value c = mrb_exc_const_get(mrb, name);
812
+
813
+ if (!mrb_class_p(c)) {
814
+ mrb_raise(mrb, E_EXCEPTION, "exception corrupted");
815
+ }
816
+
817
+ struct RClass *exc = mrb_class_ptr(c);
818
+ for (struct RClass *e = exc; e; e = e->super) {
819
+ if (e == E_EXCEPTION)
820
+ return exc;
821
+ }
822
+ mrb_raise(mrb, E_EXCEPTION, "non-exception raised");
823
+ /* not reached */
824
+ return NULL;
825
+ }
826
+
827
+ /*
828
+ * Retrieves a module defined under an outer module/class.
829
+ *
830
+ * @param mrb The mruby state.
831
+ * @param outer A pointer to the RClass structure of the outer module/class.
832
+ * @param name The name of the module to retrieve.
833
+ * @return A pointer to the RClass structure of the found module.
834
+ * @raise TypeError if the constant found is not a module.
835
+ * @raise NameError if the constant is not found.
836
+ */
837
+ MRB_API struct RClass*
838
+ mrb_module_get_under(mrb_state *mrb, struct RClass *outer, const char *name)
839
+ {
840
+ return module_from_sym(mrb, outer, mrb_intern_cstr(mrb, name));
841
+ }
842
+
843
+ /*
844
+ * Retrieves a module defined under an outer module/class using a symbol for the name.
845
+ *
846
+ * @param mrb The mruby state.
847
+ * @param outer A pointer to the RClass structure of the outer module/class.
848
+ * @param name The symbol representing the name of the module to retrieve.
849
+ * @return A pointer to the RClass structure of the found module.
850
+ * @raise TypeError if the constant found is not a module.
851
+ * @raise NameError if the constant is not found.
852
+ */
853
+ MRB_API struct RClass*
854
+ mrb_module_get_under_id(mrb_state *mrb, struct RClass *outer, mrb_sym name)
855
+ {
856
+ return module_from_sym(mrb, outer, name);
857
+ }
858
+
859
+ /*
860
+ * Retrieves a module defined in the top-level scope (Object).
861
+ *
862
+ * @param mrb The mruby state.
863
+ * @param name The name of the module to retrieve.
864
+ * @return A pointer to the RClass structure of the found module.
865
+ * @raise TypeError if the constant found is not a module.
866
+ * @raise NameError if the constant is not found.
867
+ */
868
+ MRB_API struct RClass*
869
+ mrb_module_get(mrb_state *mrb, const char *name)
870
+ {
871
+ return mrb_module_get_under(mrb, mrb->object_class, name);
872
+ }
873
+
874
+ /*
875
+ * Retrieves a module defined in the top-level scope (Object) using a symbol for the name.
876
+ *
877
+ * @param mrb The mruby state.
878
+ * @param name The symbol representing the name of the module to retrieve.
879
+ * @return A pointer to the RClass structure of the found module.
880
+ * @raise TypeError if the constant found is not a module.
881
+ * @raise NameError if the constant is not found.
882
+ */
883
+ MRB_API struct RClass*
884
+ mrb_module_get_id(mrb_state *mrb, mrb_sym name)
885
+ {
886
+ return mrb_module_get_under_id(mrb, mrb->object_class, name);
887
+ }
888
+
889
+ /*
890
+ * Defines a class under the namespace of outer.
891
+ *
892
+ * @param mrb The mruby state.
893
+ * @param outer A pointer to the RClass structure of the outer module/class.
894
+ * @param name The symbol representing the name of the class to define.
895
+ * @param super A pointer to the RClass structure of the superclass.
896
+ * If NULL, Object is assumed as the superclass.
897
+ * @return A pointer to the newly defined or existing RClass structure for the class.
898
+ * @raise TypeError if a constant with the same name exists but is not a class.
899
+ * @raise NameError if the class is already defined but with a different superclass.
900
+ * @sideeffect Creates a new class or returns an existing one if compatible.
901
+ * The class is set as a constant in `outer`.
902
+ * If a class with the same name is already defined and its superclass
903
+ * matches `super`, the existing class is returned.
904
+ */
905
+ MRB_API struct RClass*
906
+ mrb_define_class_under_id(mrb_state *mrb, struct RClass *outer, mrb_sym name, struct RClass *super)
907
+ {
908
+ struct RClass * c;
909
+
910
+ #if 0 /* Warning is disabled by default, but can be enabled for debugging. */
911
+ if (!super) {
912
+ /* Emits a warning if no superclass is provided, assuming Object. */
913
+ mrb_warn(mrb, "no super class for '%C::%n', Object assumed", outer, name);
914
+ }
915
+ #endif
916
+ c = define_class(mrb, name, super, outer);
917
+ setup_class(mrb, outer, c, name); /* This sets the constant in outer */
918
+ return c;
919
+ }
920
+
921
+ /*
922
+ * Defines a class under the namespace of outer using a C string for the name.
923
+ *
924
+ * @param mrb The mruby state.
925
+ * @param outer A pointer to the RClass structure of the outer module/class.
926
+ * @param name The C string representing the name of the class to define.
927
+ * @param super A pointer to the RClass structure of the superclass.
928
+ * If NULL, Object is assumed as the superclass.
929
+ * @return A pointer to the newly defined or existing RClass structure for the class.
930
+ * @raise TypeError if a constant with the same name exists but is not a class.
931
+ * @raise NameError if the class is already defined but with a different superclass.
932
+ * @sideeffect Creates a new class or returns an existing one if compatible.
933
+ * The class is set as a constant in `outer`.
934
+ */
935
+ MRB_API struct RClass*
936
+ mrb_define_class_under(mrb_state *mrb, struct RClass *outer, const char *name, struct RClass *super)
937
+ {
938
+ return mrb_define_class_under_id(mrb, outer, mrb_intern_cstr(mrb, name), super);
939
+ }
940
+
941
+ static mrb_bool
942
+ check_visibility_break(const struct RProc *p, const struct RClass *c, mrb_callinfo *ci, struct REnv *env)
943
+ {
944
+ if (!p || p->upper == NULL || MRB_PROC_SCOPE_P(p) || p->e.env == NULL || !MRB_PROC_ENV_P(p)) {
945
+ return TRUE;
946
+ }
947
+ if (env) {
948
+ return p->e.env->c != c || MRB_ENV_VISIBILITY_BREAK_P(env);
949
+ }
950
+ return mrb_vm_ci_target_class(ci) != c || MRB_CI_VISIBILITY_BREAK_P(ci);
951
+ }
952
+
953
+ static void
954
+ find_visibility_scope(mrb_state *mrb, const struct RClass *c, int n, mrb_callinfo **cp, struct REnv **ep)
955
+ {
956
+ const struct mrb_context *ec = mrb->c;
957
+ mrb_callinfo *ci = ec->ci - n;
958
+ const struct RProc *p = ci->proc;
959
+
960
+ if (c == NULL) c = mrb_vm_ci_target_class(ci);
961
+
962
+ if (check_visibility_break(p, c, ci, NULL)) {
963
+ *ep = (ci->u.env && ci->u.env->tt == MRB_TT_ENV) ? ci->u.env : NULL;
964
+ *cp = ci;
965
+ return;
966
+ }
967
+
968
+ for (;;) {
969
+ struct REnv *env = p->e.env;
970
+ p = p->upper;
971
+ if (check_visibility_break(p, c, ci, env)) {
972
+ *ep = env;
973
+ *cp = NULL;
974
+ return;
975
+ }
976
+ }
977
+ }
978
+
979
+ /*
980
+ * Defines a method with raw mrb_method_t structure.
981
+ * This is a low-level function for method definition.
982
+ *
983
+ * @param mrb The mruby state.
984
+ * @param c The class/module in which to define the method.
985
+ * @param mid The symbol ID of the method name.
986
+ * @param m The mrb_method_t structure representing the method.
987
+ * @sideeffect Modifies the method table of the class/module `c`.
988
+ * Clears the method cache for `mid`.
989
+ * If `mid` is `initialize`, the method is automatically set to private.
990
+ * If the method visibility is default, it's determined by the current scope.
991
+ * @raise TypeError if the class/module or its attached object (for singleton classes) is frozen.
992
+ */
993
+ MRB_API void
994
+ mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_method_t m)
995
+ {
996
+ union mrb_mt_ptr ptr;
997
+
998
+ MRB_CLASS_ORIGIN(c);
999
+
1000
+ mrb_mt_tbl *h = c->mt;
1001
+ if (c->tt == MRB_TT_SCLASS && mrb_frozen_p(c)) {
1002
+ mrb_value v = mrb_iv_get(mrb, mrb_obj_value(c), MRB_SYM(__attached__));
1003
+ mrb_check_frozen_value(mrb, v);
1004
+ }
1005
+ else {
1006
+ mrb_check_frozen(mrb, c);
1007
+ }
1008
+ if (!h) {
1009
+ h = c->mt = mt_new(mrb);
1010
+ }
1011
+ else if (mt_frozen_p(h)) {
1012
+ /* unfreeze heap-allocated frozen layer to preserve c->mt pointer
1013
+ * (iclasses hold a copy of the mt pointer for included modules) */
1014
+ h->alloc &= ~MRB_MT_FROZEN_BIT;
1015
+ }
1016
+ else if (mt_readonly_p(h)) {
1017
+ /* COW: create mutable top layer, chain to ROM */
1018
+ mrb_mt_tbl *top = mt_new(mrb);
1019
+ top->next = h;
1020
+ h = c->mt = top;
1021
+ }
1022
+ if (MRB_METHOD_PROC_P(m)) {
1023
+ struct RProc *p = (struct RProc*)MRB_METHOD_PROC(m);
1024
+
1025
+ ptr.proc = p;
1026
+ if (p) {
1027
+ if (p->gc_color != MRB_GC_RED) {
1028
+ p->flags |= MRB_PROC_SCOPE;
1029
+ p->c = NULL;
1030
+ mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)p);
1031
+ if (!MRB_PROC_ENV_P(p)) {
1032
+ MRB_PROC_SET_TARGET_CLASS(p, c);
1033
+ }
1034
+ }
1035
+ else {
1036
+ mrb_assert(mrb_frozen_p(p) && MRB_PROC_SCOPE_P(p));
1037
+ mrb_assert(p->c == NULL && p->upper == NULL && p->e.target_class == NULL);
1038
+ }
1039
+ }
1040
+ }
1041
+ else {
1042
+ ptr.func = MRB_METHOD_FUNC(m);
1043
+ }
1044
+
1045
+ int flags = m.flags;
1046
+ if (mid == MRB_SYM(initialize) ||
1047
+ mid == MRB_SYM(initialize_copy) ||
1048
+ mid == MRB_SYM_Q(respond_to_missing)) {
1049
+ MRB_SET_VISIBILITY_FLAGS(flags, MRB_METHOD_PRIVATE_FL);
1050
+ }
1051
+ else if ((flags & MT_VMASK) == MT_VDEFAULT) {
1052
+ /* singleton methods are always public */
1053
+ if (c->tt == MRB_TT_SCLASS) {
1054
+ MRB_SET_VISIBILITY_FLAGS(flags, MRB_METHOD_PUBLIC_FL);
1055
+ }
1056
+ else {
1057
+ mrb_callinfo *ci;
1058
+ struct REnv *e;
1059
+ find_visibility_scope(mrb, c, 0, &ci, &e);
1060
+ mrb_assert(ci || e);
1061
+ MRB_SET_VISIBILITY_FLAGS(flags, (uint32_t)(e ? MRB_ENV_VISIBILITY(e) : MRB_CI_VISIBILITY(ci)) << 25);
1062
+ }
1063
+ }
1064
+ mt_put(mrb, h, mid, flags, ptr);
1065
+ if (!mrb->bootstrapping) mc_clear_by_id(mrb, mid);
1066
+ }
1067
+
1068
+ static void
1069
+ define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, mrb_aspec aspec, int vis)
1070
+ {
1071
+ mrb_method_t m;
1072
+ int ai = mrb_gc_arena_save(mrb);
1073
+
1074
+ MRB_METHOD_FROM_FUNC(m, func);
1075
+ m.flags |= aspec;
1076
+ MRB_METHOD_SET_VISIBILITY(m, vis);
1077
+ mrb_define_method_raw(mrb, c, mid, m);
1078
+ mrb_gc_arena_restore(mrb, ai);
1079
+ }
1080
+
1081
+ /*
1082
+ * Defines a public C function as a method for a class/module using a symbol for the name.
1083
+ *
1084
+ * @param mrb The mruby state.
1085
+ * @param c The class/module in which to define the method.
1086
+ * @param mid The symbol ID of the method name.
1087
+ * @param func The C function pointer (mrb_func_t) for the method body.
1088
+ * @param aspec The argument specification for the method (e.g., MRB_ARGS_REQ(1)).
1089
+ * @sideeffect Modifies the method table of the class/module `c`.
1090
+ * Clears the method cache for `mid`.
1091
+ */
1092
+ MRB_API void
1093
+ mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, mrb_aspec aspec)
1094
+ {
1095
+ define_method_id(mrb, c, mid, func, aspec, MRB_METHOD_PUBLIC_FL);
1096
+ }
1097
+
1098
+ /*
1099
+ * Defines a public C function as a method for a class/module.
1100
+ *
1101
+ * @param mrb The mruby state.
1102
+ * @param c The class/module in which to define the method.
1103
+ * @param name The C string name of the method.
1104
+ * @param func The C function pointer (mrb_func_t) for the method body.
1105
+ * @param aspec The argument specification for the method (e.g., MRB_ARGS_REQ(1)).
1106
+ * @sideeffect Modifies the method table of the class/module `c`.
1107
+ * Interns the method name string.
1108
+ * Clears the method cache for the interned method name.
1109
+ */
1110
+ MRB_API void
1111
+ mrb_define_method(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec)
1112
+ {
1113
+ mrb_define_method_id(mrb, c, mrb_intern_cstr(mrb, name), func, aspec);
1114
+ }
1115
+
1116
+ /*
1117
+ * Defines a private C function as a method for a class/module using a symbol for the name.
1118
+ *
1119
+ * @param mrb The mruby state.
1120
+ * @param c The class/module in which to define the method.
1121
+ * @param mid The symbol ID of the method name.
1122
+ * @param func The C function pointer (mrb_func_t) for the method body.
1123
+ * @param aspec The argument specification for the method (e.g., MRB_ARGS_REQ(1)).
1124
+ * @sideeffect Modifies the method table of the class/module `c`.
1125
+ * Clears the method cache for `mid`.
1126
+ */
1127
+ MRB_API void
1128
+ mrb_define_private_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, mrb_aspec aspec)
1129
+ {
1130
+ define_method_id(mrb, c, mid, func, aspec, MRB_METHOD_PRIVATE_FL);
1131
+ }
1132
+
1133
+ /*
1134
+ * Defines a private C function as a method for a class/module.
1135
+ *
1136
+ * @param mrb The mruby state.
1137
+ * @param c The class/module in which to define the method.
1138
+ * @param name The C string name of the method.
1139
+ * @param func The C function pointer (mrb_func_t) for the method body.
1140
+ * @param aspec The argument specification for the method (e.g., MRB_ARGS_REQ(1)).
1141
+ * @sideeffect Modifies the method table of the class/module `c`.
1142
+ * Interns the method name string.
1143
+ * Clears the method cache for the interned method name.
1144
+ */
1145
+ MRB_API void
1146
+ mrb_define_private_method(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec)
1147
+ {
1148
+ mrb_define_private_method_id(mrb, c, mrb_intern_cstr(mrb, name), func, aspec);
1149
+ }
1150
+
1151
+ /*
1152
+ * Raises a NotImplementedError, typically indicating that the C function
1153
+ * called by Ruby is not implemented for the current platform or build.
1154
+ * The error message will include the name of the Ruby method that called this C function.
1155
+ *
1156
+ * @param mrb The mruby state.
1157
+ * @sideeffect Raises a NotImplementedError exception. This function does not return.
1158
+ * If a method name is available from the callinfo, it's included
1159
+ * in the error message (e.g., "foo() function is unimplemented on this machine").
1160
+ */
1161
+ MRB_API void
1162
+ mrb_notimplement(mrb_state *mrb)
1163
+ {
1164
+ mrb_callinfo *ci = mrb->c->ci;
1165
+
1166
+ if (ci->mid) {
1167
+ mrb_raisef(mrb, E_NOTIMP_ERROR, "%n() function is unimplemented on this machine", ci->mid);
1168
+ }
1169
+ }
1170
+
1171
+ /*
1172
+ * A C function suitable for use as a method body (mrb_func_t)
1173
+ * that raises a NotImplementedError.
1174
+ *
1175
+ * @param mrb The mruby state.
1176
+ * @param self The receiver of the method call (unused).
1177
+ * @return This function does not return, as it raises an exception.
1178
+ * @sideeffect Raises a NotImplementedError exception via `mrb_notimplement`.
1179
+ */
1180
+ MRB_API mrb_value
1181
+ mrb_notimplement_m(mrb_state *mrb, mrb_value self)
1182
+ {
1183
+ mrb_notimplement(mrb);
1184
+ /* not reached */
1185
+ return mrb_nil_value();
1186
+ }
1187
+
1188
+ static void
1189
+ ensure_class_type(mrb_state *mrb, mrb_value val)
1190
+ {
1191
+ if (!class_ptr_p(val)) {
1192
+ mrb_raisef(mrb, E_TYPE_ERROR, "%v is not class/module", val);
1193
+ }
1194
+ }
1195
+
1196
+ #define to_sym(mrb, ss) mrb_obj_to_sym(mrb, ss)
1197
+
1198
+ /*
1199
+ * Gets the number of arguments passed to the current C function call.
1200
+ *
1201
+ * This function retrieves the argument count from the current callinfo (`ci`)
1202
+ * in the mruby state. It correctly handles the case where arguments might be
1203
+ * packed into an array by the caller (indicated by `ci->n == 15`), in which
1204
+ * case it gets the length of that array.
1205
+ *
1206
+ * @param mrb The mruby state.
1207
+ * @return The number of arguments passed to the C function.
1208
+ */
1209
+ MRB_API mrb_int
1210
+ mrb_get_argc(mrb_state *mrb)
1211
+ {
1212
+ mrb_int argc = mrb->c->ci->n;
1213
+
1214
+ if (argc == 15) {
1215
+ struct RArray *a = mrb_ary_ptr(mrb->c->ci->stack[1]);
1216
+
1217
+ a->c = NULL; /* hide from ObjectSpace.each_object */
1218
+ argc = ARY_LEN(a);
1219
+ }
1220
+ return argc;
1221
+ }
1222
+
1223
+ /*
1224
+ * Gets a pointer to the array of arguments passed to the current C function call.
1225
+ *
1226
+ * This function retrieves the arguments from the current callinfo stack.
1227
+ * It handles the case where arguments might be packed into an array
1228
+ * (when `ci->n == 15`), returning a pointer to the elements of that array.
1229
+ * Otherwise, it returns a pointer to the arguments on the stack.
1230
+ *
1231
+ * @param mrb The mruby state.
1232
+ * @return A const pointer to the array of mrb_value arguments.
1233
+ * The caller should not modify the contents of this array.
1234
+ * @note If arguments were packed, the RArray object on stack has its class pointer
1235
+ * temporarily set to NULL to hide it from `ObjectSpace.each_object`.
1236
+ */
1237
+ MRB_API const mrb_value*
1238
+ mrb_get_argv(mrb_state *mrb)
1239
+ {
1240
+ mrb_int argc = mrb->c->ci->n;
1241
+ mrb_value *array_argv = mrb->c->ci->stack + 1;
1242
+ if (argc == 15) {
1243
+ struct RArray *a = mrb_ary_ptr(*array_argv);
1244
+
1245
+ a->c = NULL; /* hide from ObjectSpace.each_object */
1246
+ array_argv = ARY_PTR(a);
1247
+ }
1248
+ return array_argv;
1249
+ }
1250
+
1251
+ /*
1252
+ * Gets the first argument passed to the current C function call.
1253
+ *
1254
+ * This is a convenience function for directly accessing the first argument.
1255
+ * It handles cases where arguments might be packed into an array or
1256
+ * if the first argument is a keyword hash.
1257
+ *
1258
+ * @param mrb The mruby state.
1259
+ * @return The first mrb_value argument.
1260
+ * @raise ArgumentError if the number of positional arguments is not 1,
1261
+ * unless there are no positional arguments but a keyword hash is present,
1262
+ * in which case the keyword hash is returned.
1263
+ */
1264
+ MRB_API mrb_value
1265
+ mrb_get_arg1(mrb_state *mrb)
1266
+ {
1267
+ mrb_callinfo *ci = mrb->c->ci;
1268
+ mrb_int argc = ci->n;
1269
+ mrb_value *array_argv = ci->stack + 1;
1270
+ if (argc == 15) {
1271
+ struct RArray *a = mrb_ary_ptr(*array_argv);
1272
+
1273
+ argc = ARY_LEN(a);
1274
+ array_argv = ARY_PTR(a);
1275
+ }
1276
+ if (argc == 0 && ci->nk == 15) {
1277
+ mrb_int n = ci->n;
1278
+ if (n == 15) n = 1;
1279
+ return ci->stack[n+1]; /* kwhash next to positional arguments */
1280
+ }
1281
+ if (argc != 1) {
1282
+ mrb_argnum_error(mrb, argc, 1, 1);
1283
+ }
1284
+ return array_argv[0];
1285
+ }
1286
+
1287
+ /*
1288
+ * Checks if a block was passed to the current C function call.
1289
+ *
1290
+ * It inspects the current callinfo stack for a block argument.
1291
+ *
1292
+ * @param mrb The mruby state.
1293
+ * @return TRUE if a block is present (i.e., not nil), FALSE otherwise.
1294
+ */
1295
+ MRB_API mrb_bool
1296
+ mrb_block_given_p(mrb_state *mrb)
1297
+ {
1298
+ mrb_callinfo *ci = mrb->c->ci;
1299
+ mrb_value b = ci->stack[mrb_ci_bidx(ci)];
1300
+
1301
+ return !mrb_nil_p(b);
1302
+ }
1303
+
1304
+ #define GET_ARG(_type) (ptr ? ((_type)(*ptr++)) : va_arg((*ap), _type))
1305
+
1306
+ static mrb_int
1307
+ get_args_v(mrb_state *mrb, mrb_args_format format, void** ptr, va_list *ap)
1308
+ {
1309
+ const char *fmt = format;
1310
+ char c;
1311
+ mrb_int i = 0;
1312
+ mrb_callinfo *ci = mrb->c->ci;
1313
+ mrb_int argc = ci->n;
1314
+ const mrb_value *argv = ci->stack+1;
1315
+ mrb_bool argv_on_stack;
1316
+ mrb_bool opt = FALSE;
1317
+ mrb_bool opt_skip = TRUE;
1318
+ const mrb_value *pickarg = NULL; /* arguments currently being processed */
1319
+ mrb_value kdict = mrb_nil_value();
1320
+ mrb_bool reqkarg = FALSE;
1321
+ int argc_min = 0, argc_max = 0;
1322
+
1323
+ while ((c = *fmt++)) {
1324
+ switch (c) {
1325
+ case '|':
1326
+ opt = TRUE;
1327
+ break;
1328
+ case '*':
1329
+ opt_skip = FALSE;
1330
+ argc_max = -1;
1331
+ if (!reqkarg) reqkarg = strchr(fmt, ':') ? TRUE : FALSE;
1332
+ goto check_exit;
1333
+ case '!':
1334
+ case '+':
1335
+ break;
1336
+ case ':':
1337
+ reqkarg = TRUE;
1338
+ /* fall through */
1339
+ case '&': case '?':
1340
+ if (opt) opt_skip = FALSE;
1341
+ break;
1342
+ default:
1343
+ if (!opt) argc_min++;
1344
+ argc_max++;
1345
+ break;
1346
+ }
1347
+ }
1348
+
1349
+ check_exit:
1350
+ if (!reqkarg && ci->nk > 0) {
1351
+ mrb_assert(ci->nk == 15);
1352
+ kdict = ci->stack[mrb_ci_bidx(ci)-1];
1353
+ if (mrb_hash_p(kdict) && mrb_hash_size(mrb, kdict) > 0) {
1354
+ if (argc < 14) {
1355
+ ci->n++;
1356
+ argc++; /* include kdict in normal arguments */
1357
+ }
1358
+ else {
1359
+ /* 14+1 == 15 so pack first */
1360
+ if (argc == 14) {
1361
+ /* pack arguments and kdict */
1362
+ ci->stack[1] = mrb_ary_new_from_values(mrb, argc+1, &ci->stack[1]);
1363
+ argc = ci->n = 15;
1364
+ }
1365
+ else {
1366
+ /* push kdict to packed arguments */
1367
+ mrb_ary_push(mrb, ci->stack[1], kdict);
1368
+ }
1369
+ ci->stack[2] = ci->stack[mrb_ci_bidx(ci)];
1370
+ }
1371
+ ci->nk = 0;
1372
+ }
1373
+ }
1374
+ if (reqkarg && ci->nk > 0) {
1375
+ kdict = ci->stack[mrb_ci_bidx(ci)-1];
1376
+ mrb_assert(ci->nk == 15);
1377
+ mrb_assert(mrb_hash_p(kdict));
1378
+ }
1379
+
1380
+ argv_on_stack = argc < 15;
1381
+ if (!argv_on_stack) {
1382
+ struct RArray *a = mrb_ary_ptr(*argv);
1383
+ argv = ARY_PTR(a);
1384
+ argc = ARY_LEN(a);
1385
+ a->c = NULL; /* hide from ObjectSpace.each_object */
1386
+ }
1387
+
1388
+ opt = FALSE;
1389
+ i = 0;
1390
+ while ((c = *format++)) {
1391
+ mrb_bool altmode = FALSE;
1392
+ mrb_bool needmodify = FALSE;
1393
+
1394
+ for (; *format; format++) {
1395
+ switch (*format) {
1396
+ case '!':
1397
+ if (altmode) goto modifier_exit; /* not accept for multiple '!' */
1398
+ altmode = TRUE;
1399
+ break;
1400
+ case '+':
1401
+ if (needmodify) goto modifier_exit; /* not accept for multiple '+' */
1402
+ needmodify = TRUE;
1403
+ break;
1404
+ default:
1405
+ goto modifier_exit;
1406
+ }
1407
+ }
1408
+
1409
+ modifier_exit:
1410
+ switch (c) {
1411
+ case '|': case '*': case '&': case '?': case ':':
1412
+ if (needmodify) {
1413
+ bad_needmodify:
1414
+ mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong `%c+` modified specifier`", c);
1415
+ }
1416
+ break;
1417
+ default:
1418
+ if (i < argc) {
1419
+ pickarg = &argv[i++];
1420
+ if (needmodify && !mrb_nil_p(*pickarg)) {
1421
+ mrb_check_frozen_value(mrb, *pickarg);
1422
+ }
1423
+ }
1424
+ else {
1425
+ if (opt) {
1426
+ pickarg = NULL;
1427
+ }
1428
+ else {
1429
+ mrb_argnum_error(mrb, argc, argc_min, argc_max);
1430
+ }
1431
+ }
1432
+ break;
1433
+ }
1434
+
1435
+ switch (c) {
1436
+ case 'o':
1437
+ case 'C':
1438
+ case 'S':
1439
+ case 'A':
1440
+ case 'H':
1441
+ {
1442
+ mrb_value *p;
1443
+
1444
+ p = GET_ARG(mrb_value*);
1445
+ if (pickarg) {
1446
+ if (!(altmode && mrb_nil_p(*pickarg))) {
1447
+ switch (c) {
1448
+ case 'C': ensure_class_type(mrb, *pickarg); break;
1449
+ case 'S': mrb_ensure_string_type(mrb, *pickarg); break;
1450
+ case 'A': mrb_ensure_array_type(mrb, *pickarg); break;
1451
+ case 'H': mrb_ensure_hash_type(mrb, *pickarg); break;
1452
+ }
1453
+ }
1454
+ *p = *pickarg;
1455
+ }
1456
+ }
1457
+ break;
1458
+ case 'c':
1459
+ {
1460
+ struct RClass **p;
1461
+
1462
+ p = GET_ARG(struct RClass**);
1463
+ if (pickarg) {
1464
+ if (altmode && mrb_nil_p(*pickarg)) {
1465
+ *p = NULL;
1466
+ }
1467
+ else {
1468
+ ensure_class_type(mrb, *pickarg);
1469
+ *p = mrb_class_ptr(*pickarg);
1470
+ }
1471
+ }
1472
+ }
1473
+ break;
1474
+ case 's':
1475
+ {
1476
+ const char **ps = NULL;
1477
+ mrb_int *pl = NULL;
1478
+
1479
+ ps = GET_ARG(const char**);
1480
+ pl = GET_ARG(mrb_int*);
1481
+ if (needmodify) goto bad_needmodify;
1482
+ if (pickarg) {
1483
+ if (altmode && mrb_nil_p(*pickarg)) {
1484
+ *ps = NULL;
1485
+ *pl = 0;
1486
+ }
1487
+ else {
1488
+ mrb_ensure_string_type(mrb, *pickarg);
1489
+ *ps = RSTRING_PTR(*pickarg);
1490
+ *pl = RSTRING_LEN(*pickarg);
1491
+ }
1492
+ }
1493
+ }
1494
+ break;
1495
+ case 'z':
1496
+ {
1497
+ const char **ps;
1498
+
1499
+ ps = GET_ARG(const char**);
1500
+ if (needmodify) goto bad_needmodify;
1501
+ if (pickarg) {
1502
+ if (altmode && mrb_nil_p(*pickarg)) {
1503
+ *ps = NULL;
1504
+ }
1505
+ else {
1506
+ mrb_ensure_string_type(mrb, *pickarg);
1507
+ *ps = RSTRING_CSTR(mrb, *pickarg);
1508
+ }
1509
+ }
1510
+ }
1511
+ break;
1512
+ case 'a':
1513
+ {
1514
+ struct RArray *a;
1515
+ const mrb_value **pb;
1516
+ mrb_int *pl;
1517
+
1518
+ pb = GET_ARG(const mrb_value**);
1519
+ pl = GET_ARG(mrb_int*);
1520
+ if (needmodify) goto bad_needmodify;
1521
+ if (pickarg) {
1522
+ if (altmode && mrb_nil_p(*pickarg)) {
1523
+ *pb = NULL;
1524
+ *pl = 0;
1525
+ }
1526
+ else {
1527
+ mrb_ensure_array_type(mrb, *pickarg);
1528
+ a = mrb_ary_ptr(*pickarg);
1529
+ *pb = ARY_PTR(a);
1530
+ *pl = ARY_LEN(a);
1531
+ }
1532
+ }
1533
+ }
1534
+ break;
1535
+ #ifndef MRB_NO_FLOAT
1536
+ case 'f':
1537
+ {
1538
+ mrb_float *p;
1539
+
1540
+ p = GET_ARG(mrb_float*);
1541
+ if (pickarg) {
1542
+ *p = mrb_as_float(mrb, *pickarg);
1543
+ }
1544
+ }
1545
+ break;
1546
+ #endif
1547
+ case 'i':
1548
+ {
1549
+ mrb_int *p;
1550
+
1551
+ p = GET_ARG(mrb_int*);
1552
+ if (pickarg) {
1553
+ *p = mrb_as_int(mrb, *pickarg);
1554
+ }
1555
+ }
1556
+ break;
1557
+ case 'b':
1558
+ {
1559
+ mrb_bool *boolp = GET_ARG(mrb_bool*);
1560
+
1561
+ if (pickarg) {
1562
+ *boolp = mrb_test(*pickarg);
1563
+ }
1564
+ }
1565
+ break;
1566
+ case 'n':
1567
+ {
1568
+ mrb_sym *symp;
1569
+
1570
+ symp = GET_ARG(mrb_sym*);
1571
+ if (pickarg) {
1572
+ *symp = to_sym(mrb, *pickarg);
1573
+ }
1574
+ }
1575
+ break;
1576
+ case 'd':
1577
+ {
1578
+ void** datap;
1579
+ struct mrb_data_type const* type;
1580
+
1581
+ datap = GET_ARG(void**);
1582
+ type = GET_ARG(struct mrb_data_type const*);
1583
+ if (pickarg) {
1584
+ if (altmode && mrb_nil_p(*pickarg)) {
1585
+ *datap = NULL;
1586
+ }
1587
+ else {
1588
+ *datap = mrb_data_get_ptr(mrb, *pickarg, type);
1589
+ }
1590
+ }
1591
+ }
1592
+ break;
1593
+
1594
+ case '&':
1595
+ {
1596
+ mrb_value *p, *bp;
1597
+
1598
+ p = GET_ARG(mrb_value*);
1599
+ bp = ci->stack + mrb_ci_bidx(ci);
1600
+ if (altmode && mrb_nil_p(*bp)) {
1601
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
1602
+ }
1603
+ *p = *bp;
1604
+ }
1605
+ break;
1606
+ case '|':
1607
+ if (opt_skip && i == argc) goto finish;
1608
+ opt = TRUE;
1609
+ break;
1610
+ case '?':
1611
+ {
1612
+ mrb_bool *p;
1613
+
1614
+ p = GET_ARG(mrb_bool*);
1615
+ *p = pickarg ? TRUE : FALSE;
1616
+ }
1617
+ break;
1618
+
1619
+ case '*':
1620
+ {
1621
+ const mrb_value **var;
1622
+ mrb_int *pl;
1623
+ mrb_bool nocopy = (altmode || !argv_on_stack) ? TRUE : FALSE;
1624
+
1625
+ var = GET_ARG(const mrb_value**);
1626
+ pl = GET_ARG(mrb_int*);
1627
+ if (argc > i) {
1628
+ *pl = argc-i;
1629
+ if (*pl > 0) {
1630
+ if (nocopy) {
1631
+ *var = argv+i;
1632
+ }
1633
+ else {
1634
+ mrb_value args = mrb_ary_new_from_values(mrb, *pl, argv+i);
1635
+ RARRAY(args)->c = NULL;
1636
+ *var = RARRAY_PTR(args);
1637
+ }
1638
+ }
1639
+ i = argc;
1640
+ }
1641
+ else {
1642
+ *pl = 0;
1643
+ *var = NULL;
1644
+ }
1645
+ }
1646
+ break;
1647
+
1648
+ case ':':
1649
+ {
1650
+ mrb_value ksrc = mrb_hash_p(kdict) ? kdict : mrb_hash_new(mrb);
1651
+ const mrb_kwargs *kwargs = GET_ARG(const mrb_kwargs*);
1652
+ mrb_value *rest;
1653
+
1654
+ if (kwargs == NULL) {
1655
+ rest = NULL;
1656
+ }
1657
+ else {
1658
+ mrb_int kwnum = kwargs->num;
1659
+ mrb_int required = kwargs->required;
1660
+ const mrb_sym *kname = kwargs->table;
1661
+ mrb_value *values = kwargs->values;
1662
+ const mrb_int keyword_max = 40;
1663
+
1664
+ mrb_assert(kwnum >= 0);
1665
+ mrb_assert(required >= 0);
1666
+ if (kwnum > keyword_max || required > kwnum) {
1667
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "keyword number is too large");
1668
+ }
1669
+
1670
+ for (mrb_int j = required; j > 0; j--, kname++, values++) {
1671
+ mrb_value k = mrb_symbol_value(*kname);
1672
+ if (!mrb_hash_key_p(mrb, ksrc, k)) {
1673
+ mrb_raisef(mrb, E_ARGUMENT_ERROR, "missing keyword: %n", *kname);
1674
+ }
1675
+ *values = mrb_hash_delete_key(mrb, ksrc, k);
1676
+ mrb_gc_protect(mrb, *values);
1677
+ }
1678
+
1679
+ for (mrb_int j = kwnum - required; j > 0; j--, kname++, values++) {
1680
+ mrb_value k = mrb_symbol_value(*kname);
1681
+ if (mrb_hash_key_p(mrb, ksrc, k)) {
1682
+ *values = mrb_hash_delete_key(mrb, ksrc, k);
1683
+ mrb_gc_protect(mrb, *values);
1684
+ }
1685
+ else {
1686
+ *values = mrb_undef_value();
1687
+ }
1688
+ }
1689
+
1690
+ rest = kwargs->rest;
1691
+ }
1692
+
1693
+ if (rest) {
1694
+ *rest = ksrc;
1695
+ }
1696
+ else if (!mrb_hash_empty_p(mrb, ksrc)) {
1697
+ ksrc = mrb_hash_first_key(mrb, ksrc);
1698
+ mrb_raisef(mrb, E_ARGUMENT_ERROR, "unknown keyword: %v", ksrc);
1699
+ }
1700
+ }
1701
+ break;
1702
+
1703
+ default:
1704
+ mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid argument specifier %c", c);
1705
+ break;
1706
+ }
1707
+ }
1708
+
1709
+ if (!c && argc > i) {
1710
+ mrb_argnum_error(mrb, argc, argc_min, argc_max);
1711
+ }
1712
+
1713
+ finish:
1714
+ return i;
1715
+ }
1716
+
1717
+ /*
1718
+ retrieve arguments from mrb_state.
1719
+
1720
+ mrb_get_args(mrb, format, ...)
1721
+
1722
+ returns number of arguments parsed.
1723
+
1724
+ format specifiers:
1725
+
1726
+ string mruby type C type note
1727
+ ----------------------------------------------------------------------------------------------
1728
+ o: Object [mrb_value]
1729
+ C: Class/Module [mrb_value] when ! follows, the value may be nil
1730
+ S: String [mrb_value] when ! follows, the value may be nil
1731
+ A: Array [mrb_value] when ! follows, the value may be nil
1732
+ H: Hash [mrb_value] when ! follows, the value may be nil
1733
+ s: String [const char*,mrb_int] Receive two arguments; s! gives (NULL,0) for nil
1734
+ z: String [const char*] NUL terminated string; z! gives NULL for nil
1735
+ a: Array [const mrb_value*,mrb_int] Receive two arguments; a! gives (NULL,0) for nil
1736
+ c: Class/Module [struct RClass*] c! gives NULL for nil
1737
+ f: Integer/Float [mrb_float]
1738
+ i: Integer/Float [mrb_int]
1739
+ b: boolean [mrb_bool]
1740
+ n: String/Symbol [mrb_sym]
1741
+ d: data [void*,mrb_data_type const] 2nd argument will be used to check data type so it won't be modified; when ! follows, the value may be nil
1742
+ &: block [mrb_value] &! raises exception if no block given
1743
+ *: rest argument [const mrb_value*,mrb_int] The rest of the arguments as an array; *! avoid copy of the stack
1744
+ |: optional Following arguments are optional
1745
+ ?: optional given [mrb_bool] true if preceding argument (optional) is given
1746
+ ':': keyword args [mrb_kwargs const] Get keyword arguments
1747
+
1748
+ format modifiers:
1749
+
1750
+ string note
1751
+ ----------------------------------------------------------------------------------------------
1752
+ !: Switch to the alternate mode; The behaviour changes depending on the specifier
1753
+ +: Request a not frozen object; However, except nil value
1754
+ */
1755
+ /*
1756
+ * Retrieves and parses arguments passed to a C function based on a given format string.
1757
+ * This is the primary and most flexible way for C extensions to handle arguments
1758
+ * passed from Ruby method calls.
1759
+ *
1760
+ * @param mrb The mruby state.
1761
+ * @param format A C string that specifies the expected arguments and their types.
1762
+ * See below for detailed format specifiers and modifiers.
1763
+ * @param ... A variable number of pointer arguments, corresponding to the types
1764
+ * specified in the format string, where the parsed values will be stored.
1765
+ * @return The number of arguments successfully parsed and assigned from the Ruby stack
1766
+ * to the C variables.
1767
+ * @raise ArgumentError if the passed arguments do not match the format string,
1768
+ * if there are type mismatches, or if required arguments are missing.
1769
+ * @sideeffect Arguments from the mruby stack are converted and stored in the C variables
1770
+ * provided via `...`. The mruby garbage collector arena might be saved
1771
+ * and restored during this process. Keyword argument processing might
1772
+ * involve hash duplication or key deletion.
1773
+ *
1774
+ * Format Specifiers (within the `format` string):
1775
+ * 'o': Object (expects mrb_value*)
1776
+ * 'C': Class/Module (expects mrb_value*). Use 'c' for `struct RClass*`.
1777
+ * 'S': String (expects mrb_value*)
1778
+ * 'A': Array (expects mrb_value*)
1779
+ * 'H': Hash (expects mrb_value*)
1780
+ * 's': String (expects const char**, mrb_int* for pointer and length)
1781
+ * 'z': String (expects const char** for a NUL-terminated string)
1782
+ * 'a': Array (expects const mrb_value**, mrb_int* for pointer and length)
1783
+ * 'c': Class/Module (expects struct RClass**)
1784
+ * 'f': Float (expects mrb_float*) - available if MRB_NO_FLOAT is not defined.
1785
+ * 'i': Integer (expects mrb_int*)
1786
+ * 'b': Boolean (expects mrb_bool*)
1787
+ * 'n': Symbol (expects mrb_sym*) - converts from String or Symbol argument.
1788
+ * 'd': Data (expects void**, const struct mrb_data_type*). The second argument is used
1789
+ * for type checking and is not modified.
1790
+ * '&': Block (expects mrb_value*) - retrieves the block passed to the method.
1791
+ * '*': Rest arguments (expects const mrb_value**, mrb_int*) - captures all remaining
1792
+ * positional arguments into an array.
1793
+ * '|': Optional arguments separator. Arguments following this are optional.
1794
+ * '?': Optional given (expects mrb_bool*) - sets to TRUE if the preceding optional
1795
+ * argument was provided, FALSE otherwise.
1796
+ * ':': Keyword arguments (expects const mrb_kwargs*). Used to retrieve keyword arguments.
1797
+ * See mrb_kwargs structure for details.
1798
+ *
1799
+ * Format Modifiers (prefix the specifier, e.g., "!s" or "c!"):
1800
+ * '!': Alternate mode. Behavior changes depending on the specifier.
1801
+ * For example, 's!' gives (NULL, 0) for a nil string. 'c!' gives NULL for nil.
1802
+ * '&!' raises an ArgumentError if no block is given.
1803
+ * '*!' avoids copying the rest arguments from the stack if possible.
1804
+ * '+': Request a modifiable (not frozen) object. Raises a FrozenError if the
1805
+ * retrieved object is frozen (this check does not apply to nil values).
1806
+ */
1807
+ MRB_API mrb_int
1808
+ mrb_get_args(mrb_state *mrb, mrb_args_format format, ...)
1809
+ {
1810
+ va_list ap;
1811
+ va_start(ap, format);
1812
+ mrb_int rc = get_args_v(mrb, format, NULL, &ap);
1813
+ va_end(ap);
1814
+ return rc;
1815
+ }
1816
+
1817
+ /*
1818
+ * Retrieves and parses arguments passed to a C function according to a format string,
1819
+ * taking a `void**` array for the output variables instead of `va_list`.
1820
+ * This version is useful when the argument parsing needs to be done in a more
1821
+ * programmatic way, or when wrapping `mrb_get_args`.
1822
+ *
1823
+ * @param mrb The mruby state.
1824
+ * @param format A C string specifying the expected arguments. See `mrb_get_args`
1825
+ * documentation for format specifiers and modifiers.
1826
+ * @param args An array of `void*` pointers to variables where the parsed arguments
1827
+ * will be stored. The types of these variables must correspond to the
1828
+ * specifiers in the `format` string.
1829
+ * @return The number of arguments successfully parsed and assigned.
1830
+ * @raise ArgumentError if arguments do not match the format string, or if there are
1831
+ * type mismatches.
1832
+ * @sideeffect Arguments from the mruby stack are converted and stored in the C variables
1833
+ * pointed to by the elements of the `args` array.
1834
+ * (See `mrb_get_args` for more details on side effects like GC arena handling
1835
+ * and keyword argument processing).
1836
+ */
1837
+ MRB_API mrb_int
1838
+ mrb_get_args_a(mrb_state *mrb, mrb_args_format format, void **args)
1839
+ {
1840
+ return get_args_v(mrb, format, args, NULL);
1841
+ }
1842
+
1843
+ static struct RClass*
1844
+ boot_defclass(mrb_state *mrb, struct RClass *super, enum mrb_vtype tt)
1845
+ {
1846
+ struct RClass *c = MRB_OBJ_ALLOC(mrb, MRB_TT_CLASS, mrb->class_class);
1847
+ MRB_SET_INSTANCE_TT(c, tt);
1848
+
1849
+ if (super) {
1850
+ c->super = super;
1851
+ mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)super);
1852
+ c->flags |= MRB_FL_CLASS_IS_INHERITED;
1853
+ }
1854
+ else {
1855
+ // limited to cases where BasicObject class is defined during mruby initialization
1856
+ mrb_assert(mrb->object_class == NULL);
1857
+ }
1858
+ c->mt = mt_new(mrb);
1859
+ return c;
1860
+ }
1861
+
1862
+ static void
1863
+ boot_initmod(mrb_state *mrb, struct RClass *mod)
1864
+ {
1865
+ if (!mod->mt) {
1866
+ mod->mt = mt_new(mrb);
1867
+ }
1868
+ }
1869
+
1870
+ static struct RClass*
1871
+ include_class_new(mrb_state *mrb, struct RClass *m, struct RClass *super)
1872
+ {
1873
+ struct RClass *ic = MRB_OBJ_ALLOC(mrb, MRB_TT_ICLASS, mrb->class_class);
1874
+ if (m->tt == MRB_TT_ICLASS) {
1875
+ m = m->c;
1876
+ }
1877
+ MRB_CLASS_ORIGIN(m);
1878
+ ic->mt = m->mt;
1879
+ ic->super = super;
1880
+ if (m->tt == MRB_TT_ICLASS) {
1881
+ ic->c = m->c;
1882
+ }
1883
+ else {
1884
+ ic->c = m;
1885
+ }
1886
+ return ic;
1887
+ }
1888
+
1889
+ static int
1890
+ include_module_at(mrb_state *mrb, struct RClass *c, struct RClass *ins_pos, struct RClass *m, int search_super)
1891
+ {
1892
+ struct RClass *ic;
1893
+ void *klass_mt = find_origin(c)->mt;
1894
+
1895
+ while (m) {
1896
+ struct RClass *p = c->super;
1897
+ int original_seen = FALSE;
1898
+ int superclass_seen = FALSE;
1899
+
1900
+ if (c == ins_pos) original_seen = TRUE;
1901
+ if (m->flags & MRB_FL_CLASS_IS_PREPENDED)
1902
+ goto skip;
1903
+ if (klass_mt && klass_mt == m->mt)
1904
+ return -1;
1905
+
1906
+ while (p) {
1907
+ if (c == p) original_seen = TRUE;
1908
+ if (p->tt == MRB_TT_ICLASS) {
1909
+ if (p->mt == m->mt) {
1910
+ if (!superclass_seen && original_seen) {
1911
+ ins_pos = p; /* move insert point */
1912
+ }
1913
+ goto skip;
1914
+ }
1915
+ }
1916
+ else if (p->tt == MRB_TT_CLASS) {
1917
+ if (!search_super) break;
1918
+ superclass_seen = TRUE;
1919
+ }
1920
+ p = p->super;
1921
+ }
1922
+
1923
+ ic = include_class_new(mrb, m, ins_pos->super);
1924
+ m->flags |= MRB_FL_CLASS_IS_INHERITED;
1925
+ ins_pos->super = ic;
1926
+ mrb_field_write_barrier(mrb, (struct RBasic*)ins_pos, (struct RBasic*)ic);
1927
+ ins_pos = ic;
1928
+ skip:
1929
+ m = m->super;
1930
+ }
1931
+ if (!mrb->bootstrapping) mrb_method_cache_clear(mrb);
1932
+ return 0;
1933
+ }
1934
+
1935
+ static int
1936
+ fix_include_module(mrb_state *mrb, struct RBasic *obj, void *data)
1937
+ {
1938
+ struct RClass **m = (struct RClass**)data;
1939
+
1940
+ if (obj->tt == MRB_TT_ICLASS && obj->c == m[0] && !MRB_FLAG_TEST(obj, MRB_FL_CLASS_IS_ORIGIN)) {
1941
+ struct RClass *ic = (struct RClass*)obj;
1942
+ include_module_at(mrb, ic, ic, m[1], 1);
1943
+ }
1944
+ return MRB_EACH_OBJ_OK;
1945
+ }
1946
+
1947
+ /*
1948
+ * Includes a module into a class or another module.
1949
+ * This adds the methods and constants of module `m` to class `c` (or module `c`).
1950
+ * The included module's instance methods become instance methods of `c`.
1951
+ *
1952
+ * @param mrb The mruby state.
1953
+ * @param c The target class or module into which module `m` will be included.
1954
+ * @param m The module to include. Must be a module (MRB_TT_MODULE).
1955
+ * @raise ArgumentError if `m` is not a module or if a cyclic include is detected.
1956
+ * @raise FrozenError if class/module `c` is frozen.
1957
+ * @sideeffect Modifies the ancestor chain of `c` by inserting an ICLASS (inclusion class)
1958
+ * that references `m`'s method table.
1959
+ * Clears the method cache.
1960
+ * If `m` defines an `included` hook, it will be called with `c` as an argument.
1961
+ * If `c` is a module that has itself been included in other classes/modules,
1962
+ * this operation will also propagate the inclusion of `m` to those descendants.
1963
+ */
1964
+ MRB_API void
1965
+ mrb_include_module(mrb_state *mrb, struct RClass *c, struct RClass *m)
1966
+ {
1967
+ mrb_check_frozen(mrb, c);
1968
+ if (include_module_at(mrb, c, find_origin(c), m, 1) < 0) {
1969
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "cyclic include detected");
1970
+ }
1971
+ if (c->tt == MRB_TT_MODULE && (c->flags & MRB_FL_CLASS_IS_INHERITED)) {
1972
+ struct RClass *data[2];
1973
+ data[0] = c;
1974
+ data[1] = m;
1975
+ mrb_objspace_each_objects(mrb, fix_include_module, data);
1976
+ }
1977
+ }
1978
+
1979
+ static int
1980
+ fix_prepend_module(mrb_state *mrb, struct RBasic *obj, void *data)
1981
+ {
1982
+ struct RClass **m = (struct RClass**)data;
1983
+ struct RClass *c = (struct RClass*)obj;
1984
+
1985
+ if (c->tt == MRB_TT_CLASS || c->tt == MRB_TT_MODULE) {
1986
+ struct RClass *p = c->super;
1987
+ struct RClass *ins_pos = c;
1988
+ while (p) {
1989
+ if (c == m[0]) break;
1990
+ if (p == m[0]->super->c) {
1991
+ ins_pos = c;
1992
+ }
1993
+ if (p->tt == MRB_TT_CLASS) break;
1994
+ if (p->c == m[0]) {
1995
+ include_module_at(mrb, ins_pos, ins_pos, m[1], 0);
1996
+ break;
1997
+ }
1998
+ c = p;
1999
+ p = p->super;
2000
+ }
2001
+ }
2002
+ return MRB_EACH_OBJ_OK;
2003
+ }
2004
+
2005
+ /*
2006
+ * Prepends a module to a class or another module.
2007
+ * Methods in the prepended module `m` will override methods of the same name in `c`.
2008
+ * In the ancestor chain, the prepended module appears before the class/module itself.
2009
+ *
2010
+ * @param mrb The mruby state.
2011
+ * @param c The target class or module to which module `m` will be prepended.
2012
+ * @param m The module to prepend. Must be a module (MRB_TT_MODULE).
2013
+ * @raise ArgumentError if `m` is not a module or if a cyclic prepend is detected.
2014
+ * @raise FrozenError if class/module `c` is frozen.
2015
+ * @sideeffect Modifies the ancestor chain of `c`. If `c` hasn't been prepended before,
2016
+ * an "origin" ICLASS is created to hold `c`'s original methods, and `c`'s
2017
+ * method table is cleared. Then, an ICLASS for `m` is inserted above `c`.
2018
+ * Clears the method cache.
2019
+ * If `m` defines a `prepended` hook, it will be called with `c` as an argument.
2020
+ * If `c` is a module that has been included/prepended elsewhere, this
2021
+ * operation propagates the prepending of `m` to those descendants.
2022
+ */
2023
+ MRB_API void
2024
+ mrb_prepend_module(mrb_state *mrb, struct RClass *c, struct RClass *m)
2025
+ {
2026
+ mrb_check_frozen(mrb, c);
2027
+ if (!(c->flags & MRB_FL_CLASS_IS_PREPENDED)) {
2028
+ struct RClass *origin = MRB_OBJ_ALLOC(mrb, MRB_TT_ICLASS, c);
2029
+ origin->flags |= MRB_FL_CLASS_IS_ORIGIN | MRB_FL_CLASS_IS_INHERITED;
2030
+ origin->super = c->super;
2031
+ c->super = origin;
2032
+ origin->mt = c->mt;
2033
+ c->mt = NULL;
2034
+ mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)origin);
2035
+ c->flags |= MRB_FL_CLASS_IS_PREPENDED;
2036
+ }
2037
+ if (include_module_at(mrb, c, c, m, 0) < 0) {
2038
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "cyclic prepend detected");
2039
+ }
2040
+ if (c->tt == MRB_TT_MODULE &&
2041
+ (c->flags & (MRB_FL_CLASS_IS_INHERITED|MRB_FL_CLASS_IS_PREPENDED))) {
2042
+ struct RClass *data[2];
2043
+ data[0] = c;
2044
+ data[1] = m;
2045
+ mrb_objspace_each_objects(mrb, fix_prepend_module, data);
2046
+ }
2047
+ }
2048
+
2049
+ /*
2050
+ * call-seq:
2051
+ * mod.prepend(module, ...) -> self
2052
+ *
2053
+ * Invokes Module.prepend_features on each parameter in reverse order.
2054
+ *
2055
+ * module Mod
2056
+ * def hello
2057
+ * "Hello from Mod.\n"
2058
+ * end
2059
+ * end
2060
+ *
2061
+ * class Klass
2062
+ * def hello
2063
+ * "Hello from Klass.\n"
2064
+ * end
2065
+ * prepend Mod
2066
+ * end
2067
+ * Klass.new.hello #=> "Hello from Mod.\n"
2068
+ */
2069
+ static mrb_value
2070
+ mrb_mod_prepend(mrb_state *mrb, mrb_value mod)
2071
+ {
2072
+ struct RClass *c = mrb_class_ptr(mod);
2073
+ mrb_int argc;
2074
+ mrb_value *argv;
2075
+ mrb_sym prepended = MRB_SYM(prepended);
2076
+
2077
+ mrb_get_args(mrb, "*", &argv, &argc);
2078
+ while (argc--) {
2079
+ mrb_value m = argv[argc];
2080
+ mrb_check_type(mrb, m, MRB_TT_MODULE);
2081
+ mrb_prepend_module(mrb, c, mrb_class_ptr(m));
2082
+ if (!mrb_func_basic_p(mrb, m, prepended, mrb_do_nothing)) {
2083
+ mrb_funcall_argv(mrb, m, prepended, 1, &mod);
2084
+ }
2085
+ }
2086
+ return mod;
2087
+ }
2088
+
2089
+ /*
2090
+ * call-seq:
2091
+ * mod.include(module, ...) -> self
2092
+ *
2093
+ * Invokes Module.append_features on each parameter in reverse order.
2094
+ *
2095
+ * module Mod
2096
+ * def hello
2097
+ * "Hello from Mod.\n"
2098
+ * end
2099
+ * end
2100
+ *
2101
+ * class Klass
2102
+ * include Mod
2103
+ * end
2104
+ * Klass.new.hello #=> "Hello from Mod.\n"
2105
+ */
2106
+ static mrb_value
2107
+ mrb_mod_include(mrb_state *mrb, mrb_value mod)
2108
+ {
2109
+ struct RClass *c = mrb_class_ptr(mod);
2110
+ mrb_int argc;
2111
+ mrb_value *argv;
2112
+ mrb_sym included = MRB_SYM(included);
2113
+
2114
+ mrb_get_args(mrb, "*", &argv, &argc);
2115
+ while (argc--) {
2116
+ mrb_value m = argv[argc];
2117
+ mrb_check_type(mrb, m, MRB_TT_MODULE);
2118
+ mrb_include_module(mrb, c, mrb_class_ptr(m));
2119
+ if (!mrb_func_basic_p(mrb, m, included, mrb_do_nothing)) {
2120
+ mrb_funcall_argv(mrb, m, included, 1, &mod);
2121
+ }
2122
+ }
2123
+ return mod;
2124
+ }
2125
+
2126
+ /* 15.3.1.3.13 */
2127
+ /*
2128
+ * call-seq:
2129
+ * obj.extend(module, ...) -> obj
2130
+ *
2131
+ * Adds to _obj_ the instance methods from each module given as a
2132
+ * parameter.
2133
+ *
2134
+ * module Mod
2135
+ * def hello
2136
+ * "Hello from Mod.\n"
2137
+ * end
2138
+ * end
2139
+ *
2140
+ * class Klass
2141
+ * def hello
2142
+ * "Hello from Klass.\n"
2143
+ * end
2144
+ * end
2145
+ *
2146
+ * k = Klass.new
2147
+ * k.hello #=> "Hello from Klass.\n"
2148
+ * k.extend(Mod) #=> #<Klass:0x401b3bc8>
2149
+ * k.hello #=> "Hello from Mod.\n"
2150
+ *
2151
+ */
2152
+ /*
2153
+ * Adds the instance methods from one or more modules to the given object `obj`.
2154
+ * This is achieved by including the specified modules into `obj`'s singleton class.
2155
+ *
2156
+ * @param mrb The mruby state.
2157
+ * @param obj The object to extend.
2158
+ * @return The extended object `obj`.
2159
+ * @raise TypeError if any of the arguments passed for extension are not modules.
2160
+ * @sideeffect Modifies the singleton class of `obj`. If the singleton class doesn't exist,
2161
+ * it is created. The given modules are included into this singleton class.
2162
+ * If any of the included modules define an `extended` hook, it is called
2163
+ * with `obj` as an argument.
2164
+ */
2165
+ mrb_value
2166
+ mrb_obj_extend(mrb_state *mrb, mrb_value obj)
2167
+ {
2168
+ mrb_int argc;
2169
+ mrb_value *argv;
2170
+ mrb_sym extended = MRB_SYM(extended);
2171
+
2172
+ mrb_get_args(mrb, "*", &argv, &argc);
2173
+
2174
+ mrb_value cc = mrb_singleton_class(mrb, obj);
2175
+ while (argc--) {
2176
+ mrb_value mod = argv[argc];
2177
+ mrb_check_type(mrb, mod, MRB_TT_MODULE);
2178
+ mrb_include_module(mrb, mrb_class_ptr(cc), mrb_class_ptr(mod));
2179
+ if (!mrb_func_basic_p(mrb, mod, extended, mrb_do_nothing)) {
2180
+ mrb_funcall_argv(mrb, mod, extended, 1, &obj);
2181
+ }
2182
+ }
2183
+ return obj;
2184
+ }
2185
+
2186
+ /* 15.2.2.4.28 */
2187
+ /*
2188
+ * call-seq:
2189
+ * mod.include?(module) -> true or false
2190
+ *
2191
+ * Returns `true` if *module* is included in
2192
+ * *mod* or one of *mod*'s ancestors.
2193
+ *
2194
+ * module A
2195
+ * end
2196
+ * class B
2197
+ * include A
2198
+ * end
2199
+ * class C < B
2200
+ * end
2201
+ * B.include?(A) #=> true
2202
+ * C.include?(A) #=> true
2203
+ * A.include?(A) #=> false
2204
+ */
2205
+ static mrb_value
2206
+ mrb_mod_include_p(mrb_state *mrb, mrb_value mod)
2207
+ {
2208
+ mrb_value mod2;
2209
+ struct RClass *c = mrb_class_ptr(mod);
2210
+
2211
+ mrb_get_args(mrb, "C", &mod2);
2212
+ mrb_check_type(mrb, mod2, MRB_TT_MODULE);
2213
+
2214
+ while (c) {
2215
+ if (c->tt == MRB_TT_ICLASS) {
2216
+ if (c->c == mrb_class_ptr(mod2)) return mrb_true_value();
2217
+ }
2218
+ c = c->super;
2219
+ }
2220
+ return mrb_false_value();
2221
+ }
2222
+
2223
+ /*
2224
+ * call-seq:
2225
+ * mod.ancestors -> array
2226
+ *
2227
+ * Returns a list of modules included/prepended in mod (including mod itself).
2228
+ *
2229
+ * module Mod
2230
+ * include Math
2231
+ * include Comparable
2232
+ * prepend Enumerable
2233
+ * end
2234
+ *
2235
+ * Mod.ancestors #=> [Enumerable, Mod, Comparable, Math]
2236
+ * Math.ancestors #=> [Math]
2237
+ * Numeric.ancestors #=> [Numeric, Comparable]
2238
+ */
2239
+ static mrb_value
2240
+ mrb_mod_ancestors(mrb_state *mrb, mrb_value self)
2241
+ {
2242
+ struct RClass *c = mrb_class_ptr(self);
2243
+ mrb_value result = mrb_ary_new(mrb);
2244
+
2245
+ while (c) {
2246
+ if (c->tt == MRB_TT_ICLASS) {
2247
+ mrb_ary_push(mrb, result, mrb_obj_value(c->c));
2248
+ }
2249
+ else if (!(c->flags & MRB_FL_CLASS_IS_PREPENDED)) {
2250
+ mrb_ary_push(mrb, result, mrb_obj_value(c));
2251
+ }
2252
+ c = c->super;
2253
+ }
2254
+
2255
+ return result;
2256
+ }
2257
+
2258
+ static mrb_value
2259
+ mrb_mod_initialize(mrb_state *mrb, mrb_value mod)
2260
+ {
2261
+ mrb_value b;
2262
+ struct RClass *m = mrb_class_ptr(mod);
2263
+ boot_initmod(mrb, m); /* bootstrap a newly initialized module */
2264
+ mrb_get_args(mrb, "|&", &b);
2265
+ if (!mrb_nil_p(b)) {
2266
+ mrb_yield_with_class(mrb, b, 1, &mod, mod, m);
2267
+ }
2268
+ return mod;
2269
+ }
2270
+
2271
+ static void
2272
+ mrb_mod_visibility(mrb_state *mrb, mrb_value mod, int vis)
2273
+ {
2274
+ mrb_assert((vis&MT_VMASK)==vis);
2275
+ mrb_int argc;
2276
+ mrb_value *argv;
2277
+ struct RClass *c = mrb_class_ptr(mod);
2278
+
2279
+ mrb_get_args(mrb, "*!", &argv, &argc);
2280
+ if (argc == 0) {
2281
+ mrb_callinfo *ci;
2282
+ struct REnv *e;
2283
+ find_visibility_scope(mrb, NULL, 1, &ci, &e);
2284
+ if (e) {
2285
+ MRB_ENV_SET_VISIBILITY(e, vis >> 25);
2286
+ }
2287
+ else {
2288
+ MRB_CI_SET_VISIBILITY(ci, vis >> 25);
2289
+ }
2290
+ }
2291
+ else {
2292
+ mrb_mt_tbl *h = c->mt;
2293
+ for (int i=0; i<argc; i++) {
2294
+ mrb_check_type(mrb, argv[i], MRB_TT_SYMBOL);
2295
+ mrb_sym mid = mrb_symbol(argv[i]);
2296
+ mrb_method_t m = mrb_method_search(mrb, c, mid);
2297
+ MRB_METHOD_SET_VISIBILITY(m, vis);
2298
+ union mrb_mt_ptr ptr;
2299
+ if (MRB_METHOD_PROC_P(m)) {
2300
+ ptr.proc = MRB_METHOD_PROC(m);
2301
+ }
2302
+ else {
2303
+ ptr.func = MRB_METHOD_FUNC(m);
2304
+ }
2305
+ mt_put(mrb, h, mid, m.flags, ptr);
2306
+ mc_clear_by_id(mrb, mid);
2307
+ }
2308
+ }
2309
+ }
2310
+
2311
+ static mrb_value
2312
+ mrb_mod_public(mrb_state *mrb, mrb_value mod)
2313
+ {
2314
+ mrb_mod_visibility(mrb, mod, MRB_METHOD_PUBLIC_FL);
2315
+ return mod;
2316
+ }
2317
+
2318
+ static mrb_value
2319
+ mrb_mod_private(mrb_state *mrb, mrb_value mod)
2320
+ {
2321
+ mrb_mod_visibility(mrb, mod, MRB_METHOD_PRIVATE_FL);
2322
+ return mod;
2323
+ }
2324
+
2325
+ static mrb_value
2326
+ mrb_mod_protected(mrb_state *mrb, mrb_value mod)
2327
+ {
2328
+ mrb_mod_visibility(mrb, mod, MT_PROTECTED);
2329
+ return mod;
2330
+ }
2331
+
2332
+ static mrb_value
2333
+ top_public(mrb_state *mrb, mrb_value self)
2334
+ {
2335
+ self = mrb_obj_value(mrb->object_class);
2336
+ mrb_mod_visibility(mrb, self, MRB_METHOD_PUBLIC_FL);
2337
+ return self;
2338
+ }
2339
+
2340
+ static mrb_value
2341
+ top_private(mrb_state *mrb, mrb_value self)
2342
+ {
2343
+ self = mrb_obj_value(mrb->object_class);
2344
+ mrb_mod_visibility(mrb, self, MRB_METHOD_PRIVATE_FL);
2345
+ return self;
2346
+ }
2347
+
2348
+ static mrb_value
2349
+ top_protected(mrb_state *mrb, mrb_value self)
2350
+ {
2351
+ self = mrb_obj_value(mrb->object_class);
2352
+ mrb_mod_visibility(mrb, self, MT_PROTECTED);
2353
+ return self;
2354
+ }
2355
+
2356
+ /*
2357
+ * Retrieves a pointer to the singleton class (also known as metaclass or eigenclass)
2358
+ * of a given object `v`. If the singleton class does not yet exist, it is created.
2359
+ *
2360
+ * Singleton classes are anonymous classes associated with a specific object,
2361
+ * allowing that object to have its own unique methods.
2362
+ *
2363
+ * @param mrb The mruby state.
2364
+ * @param v The `mrb_value` for which to get the singleton class.
2365
+ * @return A pointer to the `RClass` structure of the singleton class.
2366
+ * Returns `NULL` for immediate values (e.g., Symbols, Integers,
2367
+ * Floats if not word-boxed, C pointers) as they cannot have singleton classes.
2368
+ * For `nil`, `true`, and `false`, it returns their respective predefined
2369
+ * classes (`mrb->nil_class`, `mrb->true_class`, `mrb->false_class`),
2370
+ * which effectively act as their singleton classes.
2371
+ * @sideeffect If the singleton class doesn't exist for `v` (and `v` can have one,
2372
+ * i.e., it's not an immediate value or one of the special singletons),
2373
+ * this function will:
2374
+ * 1. Allocate a new `RClass` of type `MRB_TT_SCLASS`.
2375
+ * 2. Set its superclass appropriately (e.g., the object's original class,
2376
+ * or the class of the superclass for class singletons).
2377
+ * 3. Link this new singleton class to the object `v`.
2378
+ * 4. Set an internal `__attached__` instance variable on the singleton
2379
+ * class to point back to `v`.
2380
+ * 5. The `MRB_FL_CLASS_IS_INHERITED` flag is set on the new singleton class.
2381
+ */
2382
+ MRB_API struct RClass*
2383
+ mrb_singleton_class_ptr(mrb_state *mrb, mrb_value v)
2384
+ {
2385
+ struct RBasic *obj;
2386
+
2387
+ switch (mrb_type(v)) {
2388
+ case MRB_TT_FALSE:
2389
+ if (mrb_nil_p(v))
2390
+ return mrb->nil_class;
2391
+ return mrb->false_class;
2392
+ case MRB_TT_TRUE:
2393
+ return mrb->true_class;
2394
+ case MRB_TT_CPTR:
2395
+ case MRB_TT_SYMBOL:
2396
+ case MRB_TT_INTEGER:
2397
+ #ifndef MRB_NO_FLOAT
2398
+ case MRB_TT_FLOAT:
2399
+ #endif
2400
+ return NULL;
2401
+ default:
2402
+ break;
2403
+ }
2404
+ obj = mrb_basic_ptr(v);
2405
+ if (obj->c == NULL) return NULL;
2406
+ prepare_singleton_class(mrb, obj);
2407
+ return obj->c;
2408
+ }
2409
+
2410
+ /*
2411
+ * Retrieves the singleton class (also known as metaclass or eigenclass) of a given object
2412
+ * as an mrb_value. If the singleton class does not exist, it is created.
2413
+ *
2414
+ * This function is a wrapper around `mrb_singleton_class_ptr` that returns the
2415
+ * singleton class as an `mrb_value`.
2416
+ *
2417
+ * @param mrb The mruby state.
2418
+ * @param v The `mrb_value` for which to get the singleton class.
2419
+ * @return An `mrb_value` representing the singleton class.
2420
+ * @raise TypeError if `v` is an object that cannot have a singleton class
2421
+ * (e.g., immediate values like Symbols or Integers under certain configurations,
2422
+ * or C pointers). This exception is raised by the underlying
2423
+ * `mrb_singleton_class_ptr` if it returns NULL.
2424
+ * @sideeffect If the singleton class doesn't exist for `v` (and `v` can have one),
2425
+ * it will be created via `mrb_singleton_class_ptr`, which involves
2426
+ * memory allocation and modification of the object's class pointer.
2427
+ */
2428
+ MRB_API mrb_value
2429
+ mrb_singleton_class(mrb_state *mrb, mrb_value v)
2430
+ {
2431
+ struct RClass *c = mrb_singleton_class_ptr(mrb, v);
2432
+
2433
+ if (c == NULL) {
2434
+ mrb_raise(mrb, E_TYPE_ERROR, "can't define singleton");
2435
+ }
2436
+ return mrb_obj_value(c);
2437
+ }
2438
+
2439
+ /*
2440
+ * Defines a singleton method for a specific object `o`.
2441
+ * A singleton method is a method that belongs only to a single object,
2442
+ * not to all instances of its class. It's defined in the object's singleton class.
2443
+ *
2444
+ * @param mrb The mruby state.
2445
+ * @param o A pointer to the RObject for which the singleton method is being defined.
2446
+ * @param name The C string name of the method.
2447
+ * @param func The C function (mrb_func_t) that implements the method.
2448
+ * @param aspec The argument specification for the method (e.g., MRB_ARGS_REQ(1)).
2449
+ * @sideeffect
2450
+ * 1. Ensures that the singleton class for object `o` exists, creating it if necessary.
2451
+ * This might involve memory allocation.
2452
+ * 2. Defines the method specified by `name`, `func`, and `aspec` into this
2453
+ * singleton class.
2454
+ * 3. The method name `name` is interned into a symbol.
2455
+ * 4. The method cache for the newly defined method is cleared.
2456
+ * @raise TypeError if `o` is an object that cannot have a singleton class (e.g., immediate values).
2457
+ */
2458
+ MRB_API void
2459
+ mrb_define_singleton_method(mrb_state *mrb, struct RObject *o, const char *name, mrb_func_t func, mrb_aspec aspec)
2460
+ {
2461
+ prepare_singleton_class(mrb, (struct RBasic*)o);
2462
+ mrb_define_method_id(mrb, o->c, mrb_intern_cstr(mrb, name), func, aspec);
2463
+ }
2464
+
2465
+ /*
2466
+ * Defines a singleton method for a specific object `o` using a symbol for the method name.
2467
+ * A singleton method is a method that belongs only to a single object,
2468
+ * not to all instances of its class. It's defined in the object's singleton class.
2469
+ *
2470
+ * @param mrb The mruby state.
2471
+ * @param o A pointer to the RObject for which the singleton method is being defined.
2472
+ * @param name The symbol ID (`mrb_sym`) of the method name.
2473
+ * @param func The C function (mrb_func_t) that implements the method.
2474
+ * @param aspec The argument specification for the method (e.g., MRB_ARGS_REQ(1)).
2475
+ * @sideeffect
2476
+ * 1. Ensures that the singleton class for object `o` exists, creating it if necessary.
2477
+ * This might involve memory allocation.
2478
+ * 2. Defines the method specified by `name`, `func`, and `aspec` into this
2479
+ * singleton class.
2480
+ * 3. The method cache for the method `name` is cleared.
2481
+ * @raise TypeError if `o` is an object that cannot have a singleton class (e.g., immediate values).
2482
+ */
2483
+ MRB_API void
2484
+ mrb_define_singleton_method_id(mrb_state *mrb, struct RObject *o, mrb_sym name, mrb_func_t func, mrb_aspec aspec)
2485
+ {
2486
+ prepare_singleton_class(mrb, (struct RBasic*)o);
2487
+ mrb_define_method_id(mrb, o->c, name, func, aspec);
2488
+ }
2489
+
2490
+ /*
2491
+ * Defines a class method for a class/module `c`.
2492
+ * Class methods are effectively singleton methods defined on the class object itself.
2493
+ *
2494
+ * @param mrb The mruby state.
2495
+ * @param c The class/module (`RClass*`) for which to define the class method.
2496
+ * @param name The C string name of the class method.
2497
+ * @param func The C function (mrb_func_t) that implements the method.
2498
+ * @param aspec The argument specification for the method.
2499
+ * @sideeffect This function internally calls `mrb_define_singleton_method` on the
2500
+ * class object `c`. This involves:
2501
+ * 1. Ensuring `c`'s singleton class exists (creating it if needed).
2502
+ * 2. Defining the method in `c`'s singleton class.
2503
+ * 3. Interning the `name` string.
2504
+ * 4. Clearing the relevant method cache.
2505
+ * @raise TypeError if `c` itself is an object that cannot have a singleton class (highly unlikely for RClass).
2506
+ */
2507
+ MRB_API void
2508
+ mrb_define_class_method(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec)
2509
+ {
2510
+ mrb_define_singleton_method(mrb, (struct RObject*)c, name, func, aspec);
2511
+ }
2512
+
2513
+ /*
2514
+ * Defines a class method for a class/module `c` using a symbol for the method name.
2515
+ * Class methods are effectively singleton methods defined on the class object itself.
2516
+ *
2517
+ * @param mrb The mruby state.
2518
+ * @param c The class/module (`RClass*`) for which to define the class method.
2519
+ * @param name The symbol ID (`mrb_sym`) of the class method name.
2520
+ * @param func The C function (mrb_func_t) that implements the method.
2521
+ * @param aspec The argument specification for the method.
2522
+ * @sideeffect This function internally calls `mrb_define_singleton_method_id` on the
2523
+ * class object `c`. This involves:
2524
+ * 1. Ensuring `c`'s singleton class exists (creating it if needed).
2525
+ * 2. Defining the method in `c`'s singleton class.
2526
+ * 3. Clearing the relevant method cache.
2527
+ * @raise TypeError if `c` itself is an object that cannot have a singleton class (highly unlikely for RClass).
2528
+ */
2529
+ MRB_API void
2530
+ mrb_define_class_method_id(mrb_state *mrb, struct RClass *c, mrb_sym name, mrb_func_t func, mrb_aspec aspec)
2531
+ {
2532
+ mrb_define_singleton_method_id(mrb, (struct RObject*)c, name, func, aspec);
2533
+ }
2534
+
2535
+ /*
2536
+ * Defines a module function for a module `c` using a symbol for the name.
2537
+ * A module function is a shorthand for defining a method that is both a
2538
+ * public class method (callable on the module itself) and a private
2539
+ * instance method (callable within the context of classes that include the module).
2540
+ *
2541
+ * @param mrb The mruby state.
2542
+ * @param c The module (`RClass*` where `c->tt` should be `MRB_TT_MODULE`)
2543
+ * for which to define the module function.
2544
+ * @param name The symbol ID (`mrb_sym`) of the module function name.
2545
+ * @param func The C function (mrb_func_t) that implements the function.
2546
+ * @param aspec The argument specification for the function.
2547
+ * @sideeffect
2548
+ * 1. Defines a public class method on `c` with the given `name`, `func`, and `aspec`.
2549
+ * This involves creating/accessing `c`'s singleton class.
2550
+ * 2. Defines a private instance method on `c` with the same `name`, `func`, and `aspec`.
2551
+ * 3. Clears the method cache for `name` in both contexts.
2552
+ */
2553
+ MRB_API void
2554
+ mrb_define_module_function_id(mrb_state *mrb, struct RClass *c, mrb_sym name, mrb_func_t func, mrb_aspec aspec)
2555
+ {
2556
+ mrb_define_class_method_id(mrb, c, name, func, aspec);
2557
+ mrb_define_private_method_id(mrb, c, name, func, aspec);
2558
+ }
2559
+
2560
+ /*
2561
+ * Defines a module function for a module `c` using a C string for the name.
2562
+ * A module function is a shorthand for defining a method that is both a
2563
+ * public class method (callable on the module itself) and a private
2564
+ * instance method (callable within the context of classes that include the module).
2565
+ *
2566
+ * @param mrb The mruby state.
2567
+ * @param c The module (`RClass*` where `c->tt` should be `MRB_TT_MODULE`)
2568
+ * for which to define the module function.
2569
+ * @param name The C string name of the module function. This name will be interned.
2570
+ * @param func The C function (mrb_func_t) that implements the function.
2571
+ * @param aspec The argument specification for the function.
2572
+ * @sideeffect
2573
+ * 1. Interns the `name` string to a symbol.
2574
+ * 2. Calls `mrb_define_module_function_id` with the interned symbol, which in turn:
2575
+ * a. Defines a public class method on `c`.
2576
+ * b. Defines a private instance method on `c`.
2577
+ * 3. Clears the method cache for the method name in both contexts.
2578
+ */
2579
+ MRB_API void
2580
+ mrb_define_module_function(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec)
2581
+ {
2582
+ mrb_define_module_function_id(mrb, c, mrb_intern_cstr(mrb, name), func, aspec);
2583
+ }
2584
+
2585
+ #ifndef MRB_NO_METHOD_CACHE
2586
+ /* clear whole method cache table */
2587
+ MRB_API void
2588
+ mrb_method_cache_clear(mrb_state *mrb)
2589
+ {
2590
+ static const struct mrb_cache_entry ce_zero ={0};
2591
+
2592
+ for (int i=0; i<MRB_METHOD_CACHE_SIZE; i++) {
2593
+ mrb->cache[i] = ce_zero;
2594
+ }
2595
+ }
2596
+
2597
+ /* clear method cache for a class */
2598
+ void
2599
+ mrb_mc_clear_by_class(mrb_state *mrb, struct RClass *c)
2600
+ {
2601
+ struct mrb_cache_entry *mc = mrb->cache;
2602
+
2603
+ for (int i=0; i<MRB_METHOD_CACHE_SIZE; mc++,i++) {
2604
+ if (mc->c == c || mc->c0 == c) mc->c = NULL;
2605
+ }
2606
+ }
2607
+
2608
+ static void
2609
+ mc_clear_by_id(mrb_state *mrb, mrb_sym id)
2610
+ {
2611
+ struct mrb_cache_entry *mc = mrb->cache;
2612
+
2613
+ for (int i=0; i<MRB_METHOD_CACHE_SIZE; mc++,i++) {
2614
+ if (mc->mid == id) mc->c = NULL;
2615
+ }
2616
+ }
2617
+ #endif // MRB_NO_METHOD_CACHE
2618
+
2619
+ mrb_method_t
2620
+ mrb_vm_find_method(mrb_state *mrb, struct RClass *c, struct RClass **cp, mrb_sym mid)
2621
+ {
2622
+ mrb_method_t m;
2623
+ #ifndef MRB_NO_METHOD_CACHE
2624
+ struct RClass *oc = c;
2625
+ int h = mrb_int_hash_func(mrb, ((intptr_t)oc) ^ mid) & (MRB_METHOD_CACHE_SIZE-1);
2626
+ struct mrb_cache_entry *mc = &mrb->cache[h];
2627
+
2628
+ if (mc->c == c && mc->mid == mid) {
2629
+ *cp = mc->c0;
2630
+ return mc->m;
2631
+ }
2632
+ #endif
2633
+
2634
+ while (c) {
2635
+ mrb_mt_tbl *h = c->mt;
2636
+
2637
+ if (h) {
2638
+ union mrb_mt_ptr ptr;
2639
+ uint32_t flags;
2640
+ if (mt_get(mrb, h, mid, &ptr, &flags)) {
2641
+ if (ptr.proc == 0) break;
2642
+ *cp = c;
2643
+ m = create_method_value(mrb, flags, ptr);
2644
+ #ifndef MRB_NO_METHOD_CACHE
2645
+ mc->c = oc;
2646
+ mc->c0 = c;
2647
+ mc->mid = mid;
2648
+ mc->m = m;
2649
+ #endif
2650
+ return m;
2651
+ }
2652
+ }
2653
+ c = c->super;
2654
+ }
2655
+ MRB_METHOD_FROM_PROC(m, NULL);
2656
+ return m; /* no method */
2657
+ }
2658
+
2659
+ /*
2660
+ * Searches for a method in the method table of a class and its ancestors
2661
+ * within the context of the current virtual machine.
2662
+ * This function is primarily used internally by the VM and dispatch mechanism.
2663
+ *
2664
+ * @param mrb The mruby state.
2665
+ * @param cp A pointer to a pointer to the class (`RClass*`) from which to start
2666
+ * the method search. On successful find, the `RClass*` pointed to by `cp`
2667
+ * is updated to the class where the method was actually found.
2668
+ * @param mid The symbol ID of the method name to search for.
2669
+ * @return An `mrb_method_t` structure representing the found method.
2670
+ * If the method is not found or is undefined, the returned `mrb_method_t`
2671
+ * will have its `proc` field set to NULL (use `MRB_METHOD_UNDEF_P` to check).
2672
+ * @sideeffect If the method is found and method caching is enabled (i.e.,
2673
+ * `MRB_NO_METHOD_CACHE` is not defined), this function will update
2674
+ * the VM's method cache with the found method for the original class
2675
+ * in `*cp` and the method ID `mid`.
2676
+ */
2677
+ MRB_API mrb_method_t
2678
+ mrb_method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid)
2679
+ {
2680
+ return mrb_vm_find_method(mrb, *cp, cp, mid);
2681
+ }
2682
+
2683
+ /*
2684
+ * Searches for a method in a class `c` and its ancestors.
2685
+ * This is a higher-level wrapper around `mrb_method_search_vm`.
2686
+ *
2687
+ * @param mrb The mruby state.
2688
+ * @param c The class (`RClass*`) in which to start the search.
2689
+ * @param mid The symbol ID (`mrb_sym`) of the method name.
2690
+ * @return An `mrb_method_t` structure for the found method.
2691
+ * @raise NameError if the method specified by `mid` is not found or is undefined
2692
+ * in class `c` or its ancestors.
2693
+ * @sideeffect May update the method cache if the method is found (via the
2694
+ * internal call to `mrb_method_search_vm`).
2695
+ */
2696
+ MRB_API mrb_method_t
2697
+ mrb_method_search(mrb_state *mrb, struct RClass *c, mrb_sym mid)
2698
+ {
2699
+ mrb_method_t m;
2700
+
2701
+ m = mrb_method_search_vm(mrb, &c, mid);
2702
+ if (MRB_METHOD_UNDEF_P(m)) {
2703
+ mrb_name_error(mrb, mid, "undefined method '%n' for class %C", mid, c);
2704
+ }
2705
+ return m;
2706
+ }
2707
+
2708
+ #define ONSTACK_ALLOC_MAX 32
2709
+
2710
+ static mrb_sym
2711
+ prepare_name_common(mrb_state *mrb, mrb_sym sym, const char *prefix, const char *suffix)
2712
+ {
2713
+ char onstack[ONSTACK_ALLOC_MAX];
2714
+ mrb_int sym_len;
2715
+ const char *sym_str = mrb_sym_name_len(mrb, sym, &sym_len);
2716
+ size_t prefix_len = prefix ? strlen(prefix) : 0;
2717
+ size_t suffix_len = suffix ? strlen(suffix) : 0;
2718
+ size_t name_len = sym_len + prefix_len + suffix_len;
2719
+ char *buf = name_len > sizeof(onstack) ? (char*)mrb_alloca(mrb, name_len) : onstack;
2720
+ char *p = buf;
2721
+
2722
+ if (prefix_len > 0) {
2723
+ memcpy(p, prefix, prefix_len);
2724
+ p += prefix_len;
2725
+ }
2726
+
2727
+ memcpy(p, sym_str, sym_len);
2728
+ p += sym_len;
2729
+
2730
+ if (suffix_len > 0) {
2731
+ memcpy(p, suffix, suffix_len);
2732
+ }
2733
+
2734
+ return mrb_intern(mrb, buf, name_len);
2735
+ }
2736
+
2737
+ static mrb_value
2738
+ prepare_ivar_name(mrb_state *mrb, mrb_sym sym)
2739
+ {
2740
+ sym = prepare_name_common(mrb, sym, "@", NULL);
2741
+ mrb_iv_name_sym_check(mrb, sym);
2742
+ return mrb_symbol_value(sym);
2743
+ }
2744
+
2745
+ static mrb_sym
2746
+ prepare_writer_name(mrb_state *mrb, mrb_sym sym)
2747
+ {
2748
+ return prepare_name_common(mrb, sym, NULL, "=");
2749
+ }
2750
+
2751
+ static mrb_value
2752
+ mod_attr_define(mrb_state *mrb, mrb_value mod, mrb_value (*accessor)(mrb_state*, mrb_value), mrb_sym (*access_name)(mrb_state*, mrb_sym))
2753
+ {
2754
+ struct RClass *c = mrb_class_ptr(mod);
2755
+ const mrb_value *argv;
2756
+ mrb_int argc;
2757
+
2758
+ mrb_get_args(mrb, "*", &argv, &argc);
2759
+
2760
+ int ai = mrb_gc_arena_save(mrb);
2761
+ for (int i=0; i<argc; i++) {
2762
+ mrb_sym method = to_sym(mrb, argv[i]);
2763
+ mrb_value name = prepare_ivar_name(mrb, method);
2764
+ if (access_name) {
2765
+ method = access_name(mrb, method);
2766
+ }
2767
+
2768
+ struct RProc *p = mrb_proc_new_cfunc_with_env(mrb, accessor, 1, &name);
2769
+ mrb_method_t m;
2770
+ MRB_METHOD_FROM_PROC(m, p);
2771
+ mrb_define_method_raw(mrb, c, method, m);
2772
+ mrb_gc_arena_restore(mrb, ai);
2773
+ }
2774
+ return mrb_nil_value();
2775
+ }
2776
+
2777
+ static mrb_value
2778
+ attr_reader(mrb_state *mrb, mrb_value obj)
2779
+ {
2780
+ mrb_value name = mrb_proc_cfunc_env_get(mrb, 0);
2781
+ return mrb_iv_get(mrb, obj, to_sym(mrb, name));
2782
+ }
2783
+
2784
+ static mrb_value
2785
+ mrb_mod_attr_reader(mrb_state *mrb, mrb_value mod)
2786
+ {
2787
+ return mod_attr_define(mrb, mod, attr_reader, NULL);
2788
+ }
2789
+
2790
+ static mrb_value
2791
+ attr_writer(mrb_state *mrb, mrb_value obj)
2792
+ {
2793
+ mrb_value name = mrb_proc_cfunc_env_get(mrb, 0);
2794
+ mrb_value val = mrb_get_arg1(mrb);
2795
+
2796
+ mrb_iv_set(mrb, obj, to_sym(mrb, name), val);
2797
+ return val;
2798
+ }
2799
+
2800
+ static mrb_value
2801
+ mrb_mod_attr_writer(mrb_state *mrb, mrb_value mod)
2802
+ {
2803
+ return mod_attr_define(mrb, mod, attr_writer, prepare_writer_name);
2804
+ }
2805
+
2806
+ static mrb_value
2807
+ mrb_mod_attr_accessor(mrb_state *mrb, mrb_value mod)
2808
+ {
2809
+ mrb_mod_attr_reader(mrb, mod);
2810
+ return mrb_mod_attr_writer(mrb, mod);
2811
+ }
2812
+
2813
+ static mrb_value
2814
+ mrb_instance_alloc(mrb_state *mrb, mrb_value cv)
2815
+ {
2816
+ struct RClass *c = mrb_class_ptr(cv);
2817
+ enum mrb_vtype ttype = MRB_INSTANCE_TT(c);
2818
+
2819
+ if (c->tt == MRB_TT_SCLASS)
2820
+ mrb_raise(mrb, E_TYPE_ERROR, "can't create instance of singleton class");
2821
+
2822
+ if (c == mrb->nil_class || c == mrb->false_class) {
2823
+ mrb_assert(ttype == 0);
2824
+ }
2825
+ else if (ttype == 0) {
2826
+ ttype = MRB_TT_OBJECT;
2827
+ }
2828
+ if (MRB_UNDEF_ALLOCATOR_P(c)) {
2829
+ mrb_raisef(mrb, E_TYPE_ERROR, "allocator undefined for %v", cv);
2830
+ }
2831
+ if (ttype <= MRB_TT_CPTR) {
2832
+ mrb_raisef(mrb, E_TYPE_ERROR, "can't create instance of %v", cv);
2833
+ }
2834
+
2835
+ struct RObject *o = (struct RObject*)mrb_obj_alloc(mrb, ttype, c);
2836
+ return mrb_obj_value(o);
2837
+ }
2838
+
2839
+ /*
2840
+ * call-seq:
2841
+ * class.new(args, ...) -> obj
2842
+ *
2843
+ * Creates a new object of *class*'s class, then
2844
+ * invokes that object's `initialize` method,
2845
+ * passing it *args*. This is the method that ends
2846
+ * up getting called whenever an object is constructed using
2847
+ * `.new`.
2848
+ *
2849
+ */
2850
+
2851
+ mrb_value
2852
+ mrb_instance_new(mrb_state *mrb, mrb_value cv)
2853
+ {
2854
+ const mrb_value *argv;
2855
+ mrb_int argc;
2856
+ mrb_value blk;
2857
+
2858
+ mrb_get_args(mrb, "*!&", &argv, &argc, &blk);
2859
+ mrb_value obj = mrb_instance_alloc(mrb, cv);
2860
+ mrb_sym init = MRB_SYM(initialize);
2861
+ if (!mrb_func_basic_p(mrb, obj, init, mrb_do_nothing)) {
2862
+ mrb_funcall_with_block(mrb, obj, init, argc, argv, blk);
2863
+ }
2864
+ return obj;
2865
+ }
2866
+
2867
+ /*
2868
+ * Creates a new instance of class `c` and initializes it by calling its `initialize` method.
2869
+ *
2870
+ * This function first allocates a new object of the given class `c`.
2871
+ * Then, it calls the `initialize` method on this new object, passing
2872
+ * `argc` and `argv` as arguments. If the `initialize` method is not
2873
+ * explicitly defined or is the default (empty) one, it is not called.
2874
+ *
2875
+ * @param mrb The mruby state.
2876
+ * @param c A pointer to the `RClass` structure of the class to instantiate.
2877
+ * @param argc The number of arguments to pass to the `initialize` method.
2878
+ * @param argv A pointer to an array of `mrb_value` arguments for `initialize`.
2879
+ * @return The newly created and initialized `mrb_value` object.
2880
+ * @raise TypeError if `c` is a singleton class, or if its allocator is undefined,
2881
+ * or if it's a built-in type that cannot be instantiated this way
2882
+ * (e.g., `MRB_TT_CPTR`). This check occurs in `mrb_instance_alloc`.
2883
+ * @sideeffect
2884
+ * 1. Allocates a new object on the mruby heap.
2885
+ * 2. Calls the `initialize` method of the new object if it's a user-defined one.
2886
+ * This `initialize` call can have arbitrary side effects.
2887
+ */
2888
+ MRB_API mrb_value
2889
+ mrb_obj_new(mrb_state *mrb, struct RClass *c, mrb_int argc, const mrb_value *argv)
2890
+ {
2891
+ mrb_value obj = mrb_instance_alloc(mrb, mrb_obj_value(c));
2892
+ mrb_sym mid = MRB_SYM(initialize);
2893
+
2894
+ if (!mrb_func_basic_p(mrb, obj, mid, mrb_do_nothing)) {
2895
+ mrb_funcall_argv(mrb, obj, mid, argc, argv);
2896
+ }
2897
+ return obj;
2898
+ }
2899
+
2900
+ static mrb_value
2901
+ mrb_class_initialize(mrb_state *mrb, mrb_value obj)
2902
+ {
2903
+ struct RClass *c = mrb_class_ptr(obj);
2904
+
2905
+ if (c->iv) {
2906
+ mrb_raise(mrb, E_TYPE_ERROR, "already initialized class");
2907
+ }
2908
+
2909
+ mrb_value a, b;
2910
+ mrb_get_args(mrb, "|C&", &a, &b);
2911
+ if (!mrb_nil_p(b)) {
2912
+ mrb_yield_with_class(mrb, b, 1, &obj, obj, c);
2913
+ }
2914
+ return obj;
2915
+ }
2916
+
2917
+ static mrb_value
2918
+ mrb_class_new_class(mrb_state *mrb, mrb_value cv)
2919
+ {
2920
+ mrb_value super, blk;
2921
+ mrb_int n = mrb_get_args(mrb, "|C&", &super, &blk);
2922
+
2923
+ if (n == 0) {
2924
+ super = mrb_obj_value(mrb->object_class);
2925
+ }
2926
+ mrb_value new_class = mrb_obj_value(mrb_class_new(mrb, mrb_class_ptr(super)));
2927
+ mrb_sym mid = MRB_SYM(initialize);
2928
+ if (mrb_func_basic_p(mrb, new_class, mid, mrb_class_initialize)) {
2929
+ mrb_class_initialize(mrb, new_class);
2930
+ }
2931
+ else {
2932
+ mrb_funcall_with_block(mrb, new_class, mid, n, &super, blk);
2933
+ }
2934
+ mrb_class_inherited(mrb, mrb_class_ptr(super), mrb_class_ptr(new_class));
2935
+ return new_class;
2936
+ }
2937
+
2938
+ static mrb_value
2939
+ mrb_class_superclass(mrb_state *mrb, mrb_value klass)
2940
+ {
2941
+ struct RClass *c = mrb_class_ptr(klass);
2942
+
2943
+ c = find_origin(c)->super;
2944
+ while (c && c->tt == MRB_TT_ICLASS) {
2945
+ c = find_origin(c)->super;
2946
+ }
2947
+ if (!c) return mrb_nil_value();
2948
+ return mrb_obj_value(c);
2949
+ }
2950
+
2951
+ static mrb_value
2952
+ mrb_do_nothing(mrb_state *mrb, mrb_value cv)
2953
+ {
2954
+ return mrb_nil_value();
2955
+ }
2956
+
2957
+ static mrb_value
2958
+ mrb_bob_not(mrb_state *mrb, mrb_value cv)
2959
+ {
2960
+ return mrb_bool_value(!mrb_test(cv));
2961
+ }
2962
+
2963
+ /* 15.3.1.3.1 */
2964
+ /* 15.3.1.3.10 */
2965
+ /* 15.3.1.3.11 */
2966
+ /*
2967
+ * call-seq:
2968
+ * obj == other -> true or false
2969
+ * obj.equal?(other) -> true or false
2970
+ * obj.eql?(other) -> true or false
2971
+ *
2972
+ * Equality---At the `Object` level, `==` returns
2973
+ * `true` only if *obj* and *other* are the
2974
+ * same object. Typically, this method is overridden in descendant
2975
+ * classes to provide class-specific meaning.
2976
+ *
2977
+ * Unlike `==`, the `equal?` method should never be
2978
+ * overridden by subclasses: it is used to determine object identity
2979
+ * (that is, `a.equal?(b)` iff `a` is the same
2980
+ * object as `b`).
2981
+ *
2982
+ * The `eql?` method returns `true` if
2983
+ * *obj* and *anObject* have the same value. Used by
2984
+ * `Hash` to test members for equality. For objects of
2985
+ * class `Object`, `eql?` is synonymous with
2986
+ * `==`. Subclasses normally continue this tradition, but
2987
+ * there are exceptions. `Numeric` types, for example,
2988
+ * perform type conversion across `==`, but not across
2989
+ * `eql?`, so:
2990
+ *
2991
+ * 1 == 1.0 #=> true
2992
+ * 1.eql? 1.0 #=> false
2993
+ */
2994
+ mrb_value
2995
+ mrb_obj_equal_m(mrb_state *mrb, mrb_value self)
2996
+ {
2997
+ mrb_value arg = mrb_get_arg1(mrb);
2998
+
2999
+ return mrb_bool_value(mrb_obj_equal(mrb, self, arg));
3000
+ }
3001
+
3002
+ /*
3003
+ * Checks if instances of a class `c` (or its ancestors) respond to a given method.
3004
+ *
3005
+ * This function searches for the method `mid` in the method table of class `c`
3006
+ * and its ancestor classes and included modules.
3007
+ *
3008
+ * @param mrb The mruby state.
3009
+ * @param c The `RClass*` representing the class of the object.
3010
+ * @param mid The symbol ID (`mrb_sym`) of the method name.
3011
+ * @return `TRUE` if an object of class `c` would respond to the method `mid`
3012
+ * (i.e., the method is found and not undefined).
3013
+ * `FALSE` otherwise.
3014
+ * @sideeffect May update the method cache if the method is found (due to the
3015
+ * internal call to `mrb_method_search_vm`).
3016
+ */
3017
+ MRB_API mrb_bool
3018
+ mrb_obj_respond_to(mrb_state *mrb, struct RClass* c, mrb_sym mid)
3019
+ {
3020
+ mrb_method_t m = mrb_method_search_vm(mrb, &c, mid);
3021
+
3022
+ if (MRB_METHOD_UNDEF_P(m)) {
3023
+ return FALSE;
3024
+ }
3025
+ return TRUE;
3026
+ }
3027
+
3028
+ /*
3029
+ * Checks if a given mruby object `obj` responds to a method specified by `mid`.
3030
+ *
3031
+ * This function first determines the class of `obj` and then calls
3032
+ * `mrb_obj_respond_to` to perform the method lookup.
3033
+ *
3034
+ * @param mrb The mruby state.
3035
+ * @param obj The `mrb_value` object to check.
3036
+ * @param mid The symbol ID (`mrb_sym`) of the method name.
3037
+ * @return `TRUE` if the object `obj` responds to the method `mid`, `FALSE` otherwise.
3038
+ * @sideeffect This function calls `mrb_class(mrb, obj)` which might have side effects
3039
+ * if `obj` is a proxy object or has unusual class resolution.
3040
+ * It also has the side effects of `mrb_obj_respond_to` (e.g., method
3041
+ * cache updates).
3042
+ */
3043
+ MRB_API mrb_bool
3044
+ mrb_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym mid)
3045
+ {
3046
+ return mrb_obj_respond_to(mrb, mrb_class(mrb, obj), mid);
3047
+ }
3048
+
3049
+ /*
3050
+ * Returns the name (path) of a class or module `c`.
3051
+ *
3052
+ * If the class/module has a cached name (typically set when it's assigned to a
3053
+ * constant), that name is returned.
3054
+ * For top-level classes/modules, this is their direct name.
3055
+ * For nested classes/modules, it's the fully qualified name (e.g., `Outer::Inner`).
3056
+ * If no name is cached (e.g., for anonymous classes/modules), this function
3057
+ * attempts to find or construct a path representation (e.g., `#<Class:0xPTR>`).
3058
+ *
3059
+ * @param mrb The mruby state.
3060
+ * @param c The `RClass*` structure of the class or module.
3061
+ * @return An `mrb_value` (String) representing the path of the class/module.
3062
+ * - If a name is cached as a symbol (toplevel), it returns the symbol's string representation.
3063
+ * - If a name is cached as a string (nested), it returns a duplicate of that string.
3064
+ * - If no name is cached, it calls `mrb_class_find_path` to get or construct one.
3065
+ * The returned string is suitable for modification by the caller as it's either
3066
+ * a new string or a duplicate of an internal one.
3067
+ * @sideeffect May allocate a new string on the mruby heap if duplication or construction
3068
+ * of the path string is necessary.
3069
+ */
3070
+ MRB_API mrb_value
3071
+ mrb_class_path(mrb_state *mrb, struct RClass *c)
3072
+ {
3073
+ mrb_sym nsym = MRB_SYM(__classname__);
3074
+ mrb_value path = mrb_obj_iv_get(mrb, (struct RObject*)c, nsym);
3075
+
3076
+ if (mrb_nil_p(path)) {
3077
+ /* no name (yet) */
3078
+ return mrb_class_find_path(mrb, c);
3079
+ }
3080
+ else if (mrb_symbol_p(path)) {
3081
+ /* toplevel class/module */
3082
+ return mrb_sym_str(mrb, mrb_symbol(path));
3083
+ }
3084
+ return mrb_str_dup(mrb, path);
3085
+ }
3086
+
3087
+ /*
3088
+ * Returns the "real" class of a given class pointer `cl`.
3089
+ *
3090
+ * The "real" class is the underlying, non-singleton, non-iclass `RClass`.
3091
+ * This function traverses up the superclass chain, skipping any `MRB_TT_SCLASS`
3092
+ * (singleton class) or `MRB_TT_ICLASS` (module inclusion class / i-class)
3093
+ * encountered, until it finds an `RClass` that is a `MRB_TT_CLASS` or
3094
+ * `MRB_TT_MODULE`.
3095
+ *
3096
+ * @param cl A pointer to an `RClass` structure.
3097
+ * @return A pointer to the "real" `RClass` structure.
3098
+ * Returns `NULL` if the input `cl` is `NULL` or if the superclass
3099
+ * chain leads to `NULL` before a real class is found (which typically
3100
+ * should not happen for valid class structures).
3101
+ */
3102
+ MRB_API struct RClass*
3103
+ mrb_class_real(struct RClass* cl)
3104
+ {
3105
+ if (cl == 0) return NULL;
3106
+ while ((cl->tt == MRB_TT_SCLASS) || (cl->tt == MRB_TT_ICLASS)) {
3107
+ cl = cl->super;
3108
+ if (cl == 0) return NULL;
3109
+ }
3110
+ return cl;
3111
+ }
3112
+
3113
+ /*
3114
+ * Returns the name of a class/module `c` as a C string.
3115
+ *
3116
+ * This function provides a C string representation of the class/module name.
3117
+ * It typically calls `mrb_class_path` internally and then returns a pointer
3118
+ * to the string data of the resulting `mrb_value`.
3119
+ *
3120
+ * @param mrb The mruby state.
3121
+ * @param c The `RClass*` structure of the class or module.
3122
+ * @return A `const char*` pointing to the name of the class/module.
3123
+ * This could be the class name, a fully qualified name for nested
3124
+ * modules/classes, or a representation like "#<Class:0xPTR>" for
3125
+ * anonymous ones. Returns `NULL` if `c` is `NULL`.
3126
+ * @sideeffect This function may allocate memory on the mruby heap if `mrb_class_path`
3127
+ * needs to construct the name string (e.g., for anonymous classes or
3128
+ * if the name is not cached). The returned pointer is to the internal
3129
+ * buffer of an `mrb_value` string; its validity is tied to the lifetime
3130
+ * of that string value, which is subject to garbage collection unless
3131
+ * explicitly protected.
3132
+ */
3133
+ MRB_API const char*
3134
+ mrb_class_name(mrb_state *mrb, struct RClass* c)
3135
+ {
3136
+ if (c == NULL) return NULL;
3137
+
3138
+ mrb_value name = class_name_str(mrb, c);
3139
+ return RSTRING_PTR(name);
3140
+ }
3141
+
3142
+ /*
3143
+ * Returns the class name of a given mruby object `obj` as a C string.
3144
+ *
3145
+ * This function first retrieves the class of the object using `mrb_obj_class`
3146
+ * (which gets the "real" class, traversing SCLASS/ICLASS), and then
3147
+ * gets the name of that class using `mrb_class_name`.
3148
+ *
3149
+ * @param mrb The mruby state.
3150
+ * @param obj The `mrb_value` object whose class name is to be retrieved.
3151
+ * @return A `const char*` pointing to the name of the object's class.
3152
+ * See `mrb_class_name` for details on the format of the name.
3153
+ * @sideeffect This function has the combined side effects of `mrb_obj_class`
3154
+ * and `mrb_class_name`. This may include memory allocation on the
3155
+ * mruby heap for constructing the class name string or for class
3156
+ * structure creation if the object's class or metaclass components
3157
+ * are not yet fully initialized. The lifetime of the returned pointer
3158
+ * is tied to the underlying string `mrb_value`.
3159
+ */
3160
+ MRB_API const char*
3161
+ mrb_obj_classname(mrb_state *mrb, mrb_value obj)
3162
+ {
3163
+ return mrb_class_name(mrb, mrb_obj_class(mrb, obj));
3164
+ }
3165
+
3166
+ /*
3167
+ * Ensures a class can be derived from super.
3168
+ *
3169
+ * \param super a reference to an object.
3170
+ * \exception TypeError if \a super is not a Class or \a super is a singleton class.
3171
+ */
3172
+ static void
3173
+ mrb_check_inheritable(mrb_state *mrb, struct RClass *super)
3174
+ {
3175
+ if (super->tt != MRB_TT_CLASS) {
3176
+ mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%C given)", super);
3177
+ }
3178
+ if (super->tt == MRB_TT_SCLASS) {
3179
+ mrb_raise(mrb, E_TYPE_ERROR, "can't make subclass of singleton class");
3180
+ }
3181
+ if (super == mrb->class_class) {
3182
+ mrb_raise(mrb, E_TYPE_ERROR, "can't make subclass of Class");
3183
+ }
3184
+ }
3185
+
3186
+ /*
3187
+ * Creates a new, unnamed class.
3188
+ *
3189
+ * This function is the core mechanism for creating new classes in mruby.
3190
+ * The created class will not have a name (i.e., it's anonymous) until it is
3191
+ * assigned to a constant.
3192
+ *
3193
+ * @param mrb The mruby state.
3194
+ * @param super A pointer to the `RClass` structure of the superclass.
3195
+ * If `super` is `NULL`, `Object` (mrb->object_class) will be used
3196
+ * as the superclass by default (though `boot_defclass` handles this).
3197
+ * @return A pointer to the `RClass` structure of the newly created class.
3198
+ * @raise TypeError if `super` is not a valid class to inherit from (e.g., it's a
3199
+ * singleton class, or it's the `Class` class itself).
3200
+ * This check is performed by `mrb_check_inheritable`.
3201
+ * @sideeffect
3202
+ * 1. Allocates a new `RClass` object on the mruby heap.
3203
+ * 2. Initializes its method table (`mt`).
3204
+ * 3. Sets its superclass to the provided `super` (or `Object` if `super` is `NULL`).
3205
+ * 4. Copies instance type information (`MRB_INSTANCE_TT`) and the
3206
+ * `MRB_FL_UNDEF_ALLOCATE` flag from the superclass if `super` is provided.
3207
+ * 5. Creates and attaches a metaclass (singleton class) to the new class.
3208
+ */
3209
+ MRB_API struct RClass*
3210
+ mrb_class_new(mrb_state *mrb, struct RClass *super)
3211
+ {
3212
+ if (super) {
3213
+ mrb_check_inheritable(mrb, super);
3214
+ }
3215
+ else {
3216
+ super = mrb->object_class;
3217
+ }
3218
+
3219
+ struct RClass *c = boot_defclass(mrb, super, MRB_INSTANCE_TT(super));
3220
+ c->flags |= super->flags & MRB_FL_UNDEF_ALLOCATE;
3221
+ make_metaclass(mrb, c);
3222
+
3223
+ return c;
3224
+ }
3225
+
3226
+ /*
3227
+ * Creates a new, unnamed module.
3228
+ *
3229
+ * This function is the core mechanism for creating new modules in mruby.
3230
+ * The created module will not have a name (i.e., it's anonymous) until it is
3231
+ * assigned to a constant.
3232
+ *
3233
+ * @param mrb The mruby state.
3234
+ * @return A pointer to the `RClass` structure of the newly created module.
3235
+ * The `tt` field of this `RClass` will be `MRB_TT_MODULE`.
3236
+ * @sideeffect
3237
+ * 1. Allocates a new `RClass` object on the mruby heap.
3238
+ * 2. Sets its class to `mrb->module_class`.
3239
+ * 3. Initializes its method table (`mt`).
3240
+ */
3241
+ MRB_API struct RClass*
3242
+ mrb_module_new(mrb_state *mrb)
3243
+ {
3244
+ struct RClass *m = MRB_OBJ_ALLOC(mrb, MRB_TT_MODULE, mrb->module_class);
3245
+ boot_initmod(mrb, m);
3246
+ return m;
3247
+ }
3248
+
3249
+ /*
3250
+ * call-seq:
3251
+ * obj.class => class
3252
+ *
3253
+ * Returns the class of *obj*, now preferred over
3254
+ * `Object#type`, as an object's type in Ruby is only
3255
+ * loosely tied to that object's class. This method must always be
3256
+ * called with an explicit receiver, as `class` is also a
3257
+ * reserved word in Ruby.
3258
+ *
3259
+ * 1.class #=> Integer
3260
+ * self.class #=> Object
3261
+ */
3262
+
3263
+ /*
3264
+ * Returns the "real" class of an object.
3265
+ * This is the preferred way to get the class of an object in C extension code.
3266
+ * It correctly handles various mruby internal object structures by first calling
3267
+ * `mrb_class` (which gets the direct class, potentially a singleton or i-class)
3268
+ * and then `mrb_class_real` to resolve it to the actual user-facing class.
3269
+ *
3270
+ * @param mrb The mruby state.
3271
+ * @param obj The `mrb_value` object whose class is to be retrieved.
3272
+ * @return A pointer to the `RClass` structure of the object's "real" class.
3273
+ * For example, for an instance of a regular class, it returns the class itself.
3274
+ * For an instance of a class that includes modules, it still returns the class itself,
3275
+ * not the i-classes. For a class object, it returns `Class`.
3276
+ * @sideeffect This function itself has minimal side effects, but the underlying
3277
+ * `mrb_class` and `mrb_class_real` might perform lookups or traversals.
3278
+ */
3279
+ MRB_API struct RClass*
3280
+ mrb_obj_class(mrb_state *mrb, mrb_value obj)
3281
+ {
3282
+ return mrb_class_real(mrb_class(mrb, obj));
3283
+ }
3284
+
3285
+ /*
3286
+ * Defines an alias for an existing method within a class or module `c`.
3287
+ * The new method `a` will be an alias of the old method `b`.
3288
+ *
3289
+ * @param mrb The mruby state.
3290
+ * @param c The class or module (`RClass*`) in which to define the alias.
3291
+ * @param a The symbol ID (`mrb_sym`) for the new method name (the alias).
3292
+ * @param b The symbol ID (`mrb_sym`) for the original method name to be aliased.
3293
+ * @return This function does not return a value.
3294
+ * @raise NameError if the original method `b` is not found in class `c` or its ancestors.
3295
+ * @sideeffect
3296
+ * 1. Searches for the original method `b` in class `c` and its ancestors.
3297
+ * 2. If `b` is found:
3298
+ * a. If `b` is a C function (`MRB_METHOD_CFUNC_P` is true), or if `b` is already
3299
+ * an alias proc (`MRB_PROC_ALIAS_P` is true for the proc body), the method `m`
3300
+ * (representing `b`) is directly used for the new alias `a`.
3301
+ * b. If `b` is a Ruby-defined method (a non-CFUNC, non-alias `RProc`), a new `RProc`
3302
+ * of type `MRB_PROC_ALIAS` is created. This new proc stores the original
3303
+ * method's symbol `b` and its `RProc` as its `upper`. This ensures that
3304
+ * the alias `a` continues to point to the definition of `b` at the time of
3305
+ * aliasing, even if `b` is later redefined. The visibility of `b` is copied
3306
+ * to this new alias proc.
3307
+ * c. The method (either the original `m` or the new alias proc) is then defined
3308
+ * in class `c` under the new name `a` using `mrb_define_method_raw`.
3309
+ * 3. The method cache for the new alias name `a` is cleared.
3310
+ * 4. If `a` and `b` are the same, the function does nothing and returns early.
3311
+ */
3312
+ MRB_API void
3313
+ mrb_alias_method(mrb_state *mrb, struct RClass *c, mrb_sym a, mrb_sym b)
3314
+ {
3315
+ if (a == b) return;
3316
+ mrb_method_t m = mrb_method_search(mrb, c, b);
3317
+
3318
+ if (!MRB_METHOD_CFUNC_P(m)) {
3319
+ const struct RProc *p = MRB_METHOD_PROC(m);
3320
+ if (!MRB_PROC_CFUNC_P(p) && !MRB_PROC_ALIAS_P(p)) {
3321
+ struct RProc *pnew = MRB_OBJ_ALLOC(mrb, MRB_TT_PROC, mrb->proc_class);
3322
+ int vis = MRB_METHOD_VISIBILITY(m);
3323
+
3324
+ pnew->body.mid = b;
3325
+ pnew->upper = p;
3326
+ pnew->e.env = NULL;
3327
+ pnew->flags |= MRB_PROC_ALIAS;
3328
+ MRB_METHOD_FROM_PROC(m, pnew);
3329
+ MRB_METHOD_SET_VISIBILITY(m, vis);
3330
+ }
3331
+ }
3332
+ mrb_define_method_raw(mrb, c, a, m);
3333
+ }
3334
+
3335
+ /*
3336
+ * Defines an alias for an existing method within a class or module `klass`.
3337
+ * This version takes C string names for both the new alias and the original method.
3338
+ *
3339
+ * @param mrb The mruby state.
3340
+ * @param klass The class or module (`RClass*`) in which to define the alias.
3341
+ * @param name1 The C string for the new method name (the alias).
3342
+ * @param name2 The C string for the original method name to be aliased.
3343
+ * @return This function does not return a value.
3344
+ * @raise NameError if the original method `name2` (after being interned) is not found.
3345
+ * @sideeffect
3346
+ * 1. Interns both `name1` and `name2` to get their `mrb_sym` IDs.
3347
+ * 2. Calls `mrb_alias_method` with the class `klass` and the obtained symbols.
3348
+ * (See `mrb_alias_method` for further side effects like method table modification
3349
+ * and cache clearing).
3350
+ */
3351
+ MRB_API void
3352
+ mrb_define_alias(mrb_state *mrb, struct RClass *klass, const char *name1, const char *name2)
3353
+ {
3354
+ mrb_alias_method(mrb, klass, mrb_intern_cstr(mrb, name1), mrb_intern_cstr(mrb, name2));
3355
+ }
3356
+
3357
+ /*
3358
+ * Defines an alias for an existing method within a class or module `klass`,
3359
+ * using symbol IDs for both names.
3360
+ *
3361
+ * This function is a direct call to `mrb_alias_method`.
3362
+ *
3363
+ * @param mrb The mruby state.
3364
+ * @param klass The class or module (`RClass*`) in which to define the alias.
3365
+ * @param a The symbol ID (`mrb_sym`) for the new method name (the alias).
3366
+ * @param b The symbol ID (`mrb_sym`) for the original method name to be aliased.
3367
+ * @return This function does not return a value.
3368
+ * @raise NameError if the original method `b` is not found in `klass` or its ancestors.
3369
+ * @sideeffect Calls `mrb_alias_method`, which modifies the method table of `klass`
3370
+ * and clears the method cache for the new alias `a`.
3371
+ * (See `mrb_alias_method` for more detailed side effects).
3372
+ */
3373
+ MRB_API void
3374
+ mrb_define_alias_id(mrb_state *mrb, struct RClass *klass, mrb_sym a, mrb_sym b)
3375
+ {
3376
+ mrb_alias_method(mrb, klass, a, b);
3377
+ }
3378
+
3379
+ /*
3380
+ * call-seq:
3381
+ * mod.to_s -> string
3382
+ *
3383
+ * Return a string representing this module or class. For basic
3384
+ * classes and modules, this is the name. For singletons, we
3385
+ * show information on the thing we're attached to as well.
3386
+ */
3387
+
3388
+ mrb_value
3389
+ mrb_mod_to_s(mrb_state *mrb, mrb_value klass)
3390
+ {
3391
+ if (mrb_sclass_p(klass)) {
3392
+ mrb_value v = mrb_iv_get(mrb, klass, MRB_SYM(__attached__));
3393
+ mrb_value str = mrb_str_new_lit(mrb, "#<Class:");
3394
+
3395
+ if (class_ptr_p(v)) {
3396
+ mrb_str_cat_str(mrb, str, mrb_inspect(mrb, v));
3397
+ }
3398
+ else {
3399
+ mrb_str_cat_str(mrb, str, mrb_any_to_s(mrb, v));
3400
+ }
3401
+ return mrb_str_cat_lit(mrb, str, ">");
3402
+ }
3403
+ else {
3404
+ return class_name_str(mrb, mrb_class_ptr(klass));
3405
+ }
3406
+ }
3407
+
3408
+ static mrb_value
3409
+ mrb_mod_alias(mrb_state *mrb, mrb_value mod)
3410
+ {
3411
+ struct RClass *c = mrb_class_ptr(mod);
3412
+ mrb_sym new_name, old_name;
3413
+
3414
+ mrb_get_args(mrb, "nn", &new_name, &old_name);
3415
+ mrb_alias_method(mrb, c, new_name, old_name);
3416
+ mrb_method_added(mrb, c, new_name);
3417
+ return mod;
3418
+ }
3419
+
3420
+ static void
3421
+ undef_method(mrb_state *mrb, struct RClass *c, mrb_sym a)
3422
+ {
3423
+ mrb_sym undefined;
3424
+ mrb_value recv;
3425
+ mrb_method_t m;
3426
+
3427
+ MRB_METHOD_FROM_PROC(m, NULL);
3428
+ mrb_define_method_raw(mrb, c, a, m);
3429
+ if (c->tt == MRB_TT_SCLASS) {
3430
+ undefined = MRB_SYM(singleton_method_undefined);
3431
+ recv = mrb_iv_get(mrb, mrb_obj_value(c), MRB_SYM(__attached__));
3432
+ }
3433
+ else {
3434
+ undefined = MRB_SYM(method_undefined);
3435
+ recv = mrb_obj_value(c);
3436
+ }
3437
+ if (!mrb_func_basic_p(mrb, recv, undefined, mrb_do_nothing)) {
3438
+ mrb_value sym = mrb_symbol_value(a);
3439
+ mrb_funcall_argv(mrb, recv, undefined, 1, &sym);
3440
+ }
3441
+ }
3442
+
3443
+ /*
3444
+ * Undefines a method specified by symbol `a` in class/module `c`.
3445
+ *
3446
+ * This action prevents objects of class `c` (or classes including module `c`)
3447
+ * from responding to the method `a`. If the method was inherited, the version
3448
+ * in the superclass will no longer be accessible through `c`.
3449
+ * A special "undefined" entry is added to `c`'s method table for `a`.
3450
+ *
3451
+ * @param mrb The mruby state.
3452
+ * @param c The class or module (`RClass*`) in which to undefine the method.
3453
+ * @param a The symbol ID (`mrb_sym`) of the method to undefine.
3454
+ * @return This function does not return a value.
3455
+ * @raise NameError if the method `a` is not defined in `c` or its ancestors
3456
+ * (i.e., if `c` does not respond to `a` before undefinition).
3457
+ * @sideeffect
3458
+ * 1. Modifies the method table of `c` by adding an entry that marks `a` as undefined.
3459
+ * 2. Triggers `method_undefined` (for regular classes/modules) or
3460
+ * `singleton_method_undefined` (for singleton classes) callbacks on `c`
3461
+ * or its attached object, if these hooks are defined.
3462
+ * 3. Clears the method cache for the method symbol `a`.
3463
+ */
3464
+ MRB_API void
3465
+ mrb_undef_method_id(mrb_state *mrb, struct RClass *c, mrb_sym a)
3466
+ {
3467
+ if (!mrb_obj_respond_to(mrb, c, a)) {
3468
+ mrb_name_error(mrb, a, "undefined method '%n' for class '%C'", a, c);
3469
+ }
3470
+ undef_method(mrb, c, a);
3471
+ }
3472
+
3473
+ /*
3474
+ * Undefines a method specified by a C string `name` in class/module `c`.
3475
+ *
3476
+ * This function interns the C string `name` to a symbol and then calls
3477
+ * `mrb_undef_method_id` to perform the undefinition.
3478
+ *
3479
+ * @param mrb The mruby state.
3480
+ * @param c The class or module (`RClass*`) in which to undefine the method.
3481
+ * @param name The C string name of the method to undefine.
3482
+ * @return This function does not return a value.
3483
+ * @raise NameError if the method `name` (after interned to a symbol) is not
3484
+ * defined in `c` or its ancestors.
3485
+ * @sideeffect
3486
+ * 1. Interns the `name` string.
3487
+ * 2. All side effects of `mrb_undef_method_id` apply (method table modification,
3488
+ * callback triggering, cache clearing).
3489
+ */
3490
+ MRB_API void
3491
+ mrb_undef_method(mrb_state *mrb, struct RClass *c, const char *name)
3492
+ {
3493
+ undef_method(mrb, c, mrb_intern_cstr(mrb, name));
3494
+ }
3495
+
3496
+ /*
3497
+ * Undefines a class method specified by symbol `name` for class/module `c`.
3498
+ *
3499
+ * Class methods are singleton methods of the class object. This function
3500
+ * retrieves the singleton class of `c` and then undefines the method there.
3501
+ *
3502
+ * @param mrb The mruby state.
3503
+ * @param c The class or module (`RClass*`) whose class method is to be undefined.
3504
+ * @param name The symbol ID (`mrb_sym`) of the class method to undefine.
3505
+ * @return This function does not return a value.
3506
+ * @raise TypeError if `c` cannot have a singleton class (e.g., if it's an
3507
+ * immediate value, though highly unlikely for an `RClass*`).
3508
+ * @raise NameError if the class method `name` is not defined on `c`.
3509
+ * @sideeffect
3510
+ * 1. Retrieves or creates the singleton class of `c`.
3511
+ * 2. All side effects of `mrb_undef_method_id` apply to this singleton class
3512
+ * (method table modification, callback triggering, cache clearing).
3513
+ */
3514
+ MRB_API void
3515
+ mrb_undef_class_method_id(mrb_state *mrb, struct RClass *c, mrb_sym name)
3516
+ {
3517
+ mrb_undef_method_id(mrb, mrb_class_ptr(mrb_singleton_class(mrb, mrb_obj_value(c))), name);
3518
+ }
3519
+
3520
+ /*
3521
+ * Undefines a class method specified by a C string `name` for class/module `c`.
3522
+ *
3523
+ * This function interns the C string `name` to a symbol and then calls
3524
+ * `mrb_undef_class_method_id` (which undefines the method on `c`'s singleton class).
3525
+ *
3526
+ * @param mrb The mruby state.
3527
+ * @param c The class or module (`RClass*`) whose class method is to be undefined.
3528
+ * @param name The C string name of the class method to undefine.
3529
+ * @return This function does not return a value.
3530
+ * @raise TypeError if `c` cannot have a singleton class.
3531
+ * @raise NameError if the class method `name` (after interned) is not defined on `c`.
3532
+ * @sideeffect
3533
+ * 1. Interns the `name` string.
3534
+ * 2. Retrieves or creates the singleton class of `c`.
3535
+ * 3. All side effects of `mrb_undef_method_id` apply to this singleton class.
3536
+ */
3537
+ MRB_API void
3538
+ mrb_undef_class_method(mrb_state *mrb, struct RClass *c, const char *name)
3539
+ {
3540
+ mrb_undef_method(mrb, mrb_class_ptr(mrb_singleton_class(mrb, mrb_obj_value(c))), name);
3541
+ }
3542
+
3543
+ /*
3544
+ * Removes a method specified by symbol `mid` directly from class/module `c0`.
3545
+ *
3546
+ * Unlike `mrb_undef_method_id`, this function only removes the method definition
3547
+ * from the specified class/module `c0`. If the method is defined in an ancestor,
3548
+ * that inherited method will become active after the removal from `c0`.
3549
+ *
3550
+ * @param mrb The mruby state.
3551
+ * @param c0 The class or module (`RClass*`) from which to remove the method.
3552
+ * The method is removed from the "origin" of this class if it's an ICLASS/SCLASS.
3553
+ * @param mid The symbol ID (`mrb_sym`) of the method to remove.
3554
+ * @return This function does not return a value.
3555
+ * @raise NameError if the method `mid` is not defined directly in the method
3556
+ * table of `c0` (or its origin).
3557
+ * @sideeffect
3558
+ * 1. Removes the method entry for `mid` from `c0`'s (or its origin's) method table.
3559
+ * 2. Triggers `method_removed` (for regular classes/modules) or
3560
+ * `singleton_method_removed` (for singleton classes) callbacks on `c0`
3561
+ * or its attached object, if these hooks are defined.
3562
+ * 3. Clears the method cache for the method symbol `mid`.
3563
+ */
3564
+ MRB_API void
3565
+ mrb_remove_method(mrb_state *mrb, struct RClass *c0, mrb_sym mid)
3566
+ {
3567
+ struct RClass *c = c0;
3568
+ mrb_bool found = FALSE;
3569
+
3570
+ MRB_CLASS_ORIGIN(c);
3571
+ mrb_mt_tbl *h = c->mt;
3572
+ if (h) {
3573
+ found = mt_del(mrb, h, mid);
3574
+ /* insert removed tombstone to block ROM chain lookup */
3575
+ if (h->next && mt_chain_has(h->next, mid)) {
3576
+ union mrb_mt_ptr tombstone;
3577
+ tombstone.func = NULL;
3578
+ found = TRUE;
3579
+ if (mt_frozen_p(h)) {
3580
+ h->alloc &= ~MRB_MT_FROZEN_BIT;
3581
+ }
3582
+ else if (mt_readonly_p(h)) {
3583
+ mrb_mt_tbl *top = mt_new(mrb);
3584
+ top->next = h;
3585
+ h = c->mt = top;
3586
+ }
3587
+ mt_put(mrb, h, mid, MRB_MT_FUNC, tombstone);
3588
+ }
3589
+ }
3590
+ if (!found) {
3591
+ mrb_name_error(mrb, mid, "method '%n' not defined in %C", mid, c);
3592
+ }
3593
+ mc_clear_by_id(mrb, mid);
3594
+ if (c0->tt == MRB_TT_SCLASS) {
3595
+ mrb_sym cb = MRB_SYM(singleton_method_removed);
3596
+ mrb_value recv = mrb_iv_get(mrb, mrb_obj_value(c0), MRB_SYM(__attached__));
3597
+ if (!mrb_func_basic_p(mrb, recv, cb, mrb_do_nothing)) {
3598
+ mrb_value sym = mrb_symbol_value(mid);
3599
+ mrb_funcall_argv(mrb, recv, cb, 1, &sym);
3600
+ }
3601
+ }
3602
+ else {
3603
+ mrb_sym cb = MRB_SYM(method_removed);
3604
+ mrb_value recv = mrb_obj_value(c0);
3605
+ if (!mrb_func_basic_p(mrb, recv, cb, mrb_do_nothing)) {
3606
+ mrb_value sym = mrb_symbol_value(mid);
3607
+ mrb_funcall_argv(mrb, recv, cb, 1, &sym);
3608
+ }
3609
+ }
3610
+ }
3611
+
3612
+ static mrb_value
3613
+ mrb_mod_undef(mrb_state *mrb, mrb_value mod)
3614
+ {
3615
+ struct RClass *c = mrb_class_ptr(mod);
3616
+ mrb_int argc;
3617
+ const mrb_value *argv;
3618
+
3619
+ mrb_get_args(mrb, "*", &argv, &argc);
3620
+ while (argc--) {
3621
+ mrb_undef_method_id(mrb, c, to_sym(mrb, *argv));
3622
+ argv++;
3623
+ }
3624
+ return mrb_nil_value();
3625
+ }
3626
+
3627
+ static void
3628
+ check_const_name_sym(mrb_state *mrb, mrb_sym id)
3629
+ {
3630
+ mrb_int len;
3631
+ const char *name = mrb_sym_name_len(mrb, id, &len);
3632
+ if (!mrb_const_name_p(mrb, name, len)) {
3633
+ mrb_name_error(mrb, id, "wrong constant name %n", id);
3634
+ }
3635
+ }
3636
+
3637
+ static mrb_value
3638
+ mrb_mod_const_defined(mrb_state *mrb, mrb_value mod)
3639
+ {
3640
+ mrb_sym id;
3641
+ mrb_bool inherit = TRUE;
3642
+
3643
+ mrb_get_args(mrb, "n|b", &id, &inherit);
3644
+ check_const_name_sym(mrb, id);
3645
+ if (inherit) {
3646
+ return mrb_bool_value(mrb_const_defined(mrb, mod, id));
3647
+ }
3648
+ return mrb_bool_value(mrb_const_defined_at(mrb, mod, id));
3649
+ }
3650
+
3651
+ static mrb_value
3652
+ mrb_const_get_sym(mrb_state *mrb, mrb_value mod, mrb_sym id)
3653
+ {
3654
+ check_const_name_sym(mrb, id);
3655
+ return mrb_const_get(mrb, mod, id);
3656
+ }
3657
+
3658
+ static mrb_value
3659
+ mrb_mod_const_get(mrb_state *mrb, mrb_value mod)
3660
+ {
3661
+ mrb_value path = mrb_get_arg1(mrb);
3662
+
3663
+ if (mrb_symbol_p(path)) {
3664
+ /* const get with symbol */
3665
+ return mrb_const_get_sym(mrb, mod, mrb_symbol(path));
3666
+ }
3667
+
3668
+ /* const get with class path string */
3669
+ mrb_ensure_string_type(mrb, path);
3670
+
3671
+ char *ptr = RSTRING_PTR(path);
3672
+ mrb_int len = RSTRING_LEN(path);
3673
+ mrb_int off = 0;
3674
+
3675
+ while (off < len) {
3676
+ mrb_int end = mrb_str_index_lit(mrb, path, "::", off);
3677
+ if (end == -1) end = len;
3678
+ mrb_sym id = mrb_intern(mrb, ptr+off, end-off);
3679
+ mod = mrb_const_get_sym(mrb, mod, id);
3680
+ if (end == len)
3681
+ off = end;
3682
+ else {
3683
+ off = end + 2;
3684
+ if (off == len) { /* trailing "::" */
3685
+ mrb_name_error(mrb, id, "wrong constant name '%v'", path);
3686
+ }
3687
+ }
3688
+ }
3689
+
3690
+ return mod;
3691
+ }
3692
+
3693
+ static mrb_value
3694
+ mrb_mod_const_set(mrb_state *mrb, mrb_value mod)
3695
+ {
3696
+ mrb_sym id;
3697
+ mrb_value value;
3698
+
3699
+ mrb_get_args(mrb, "no", &id, &value);
3700
+ check_const_name_sym(mrb, id);
3701
+ mrb_const_set(mrb, mod, id, value);
3702
+ return value;
3703
+ }
3704
+
3705
+ static mrb_value
3706
+ mrb_mod_remove_const(mrb_state *mrb, mrb_value mod)
3707
+ {
3708
+ mrb_sym id;
3709
+
3710
+ mrb_get_args(mrb, "n", &id);
3711
+ check_const_name_sym(mrb, id);
3712
+
3713
+ mrb_value val = mrb_iv_remove(mrb, mod, id);
3714
+ if (mrb_undef_p(val)) {
3715
+ mrb_name_error(mrb, id, "constant %n not defined", id);
3716
+ }
3717
+ return val;
3718
+ }
3719
+
3720
+ mrb_value
3721
+ mrb_const_missing(mrb_state *mrb, mrb_value mod, mrb_sym sym)
3722
+ {
3723
+ if (mrb_class_real(mrb_class_ptr(mod)) != mrb->object_class) {
3724
+ mrb_name_error(mrb, sym, "uninitialized constant %v::%n", mod, sym);
3725
+ }
3726
+ else {
3727
+ mrb_name_error(mrb, sym, "uninitialized constant %n", sym);
3728
+ }
3729
+ /* not reached */
3730
+ return mrb_nil_value();
3731
+ }
3732
+
3733
+ mrb_value
3734
+ mrb_mod_const_missing(mrb_state *mrb, mrb_value mod)
3735
+ {
3736
+ mrb_sym sym;
3737
+
3738
+ mrb_get_args(mrb, "n", &sym);
3739
+ mrb->c->ci->mid = 0;
3740
+ return mrb_const_missing(mrb, mod, sym);
3741
+ }
3742
+
3743
+ /* 15.2.2.4.34 */
3744
+ /*
3745
+ * call-seq:
3746
+ * mod.method_defined?(symbol) -> true or false
3747
+ *
3748
+ * Returns `true` if the named method is defined by
3749
+ * _mod_ (or its included modules and, if _mod_ is a class,
3750
+ * its ancestors). Public and protected methods are matched.
3751
+ *
3752
+ * module A
3753
+ * def method1() end
3754
+ * end
3755
+ * class B
3756
+ * def method2() end
3757
+ * end
3758
+ * class C < B
3759
+ * include A
3760
+ * def method3() end
3761
+ * end
3762
+ *
3763
+ * A.method_defined? :method1 #=> true
3764
+ * C.method_defined? "method1" #=> true
3765
+ * C.method_defined? "method2" #=> true
3766
+ * C.method_defined? "method3" #=> true
3767
+ * C.method_defined? "method4" #=> false
3768
+ */
3769
+
3770
+ static mrb_value
3771
+ mrb_mod_method_defined(mrb_state *mrb, mrb_value mod)
3772
+ {
3773
+ mrb_sym id;
3774
+
3775
+ mrb_get_args(mrb, "n", &id);
3776
+ return mrb_bool_value(mrb_obj_respond_to(mrb, mrb_class_ptr(mod), id));
3777
+ }
3778
+
3779
+ void
3780
+ mrb_method_added(mrb_state *mrb, struct RClass *c, mrb_sym mid)
3781
+ {
3782
+ mrb_sym added;
3783
+ mrb_value recv = mrb_obj_value(c);
3784
+
3785
+ if (c->tt == MRB_TT_SCLASS) {
3786
+ added = MRB_SYM(singleton_method_added);
3787
+ recv = mrb_iv_get(mrb, recv, MRB_SYM(__attached__));
3788
+ }
3789
+ else {
3790
+ added = MRB_SYM(method_added);
3791
+ }
3792
+ if (!mrb_func_basic_p(mrb, recv, added, mrb_do_nothing)) {
3793
+ mrb_value sym = mrb_symbol_value(mid);
3794
+ mrb_funcall_argv(mrb, recv, added, 1, &sym);
3795
+ }
3796
+ }
3797
+
3798
+ mrb_value
3799
+ define_method_m(mrb_state *mrb, struct RClass *c, int vis)
3800
+ {
3801
+ mrb_sym mid;
3802
+ mrb_value proc = mrb_undef_value();
3803
+ mrb_value blk;
3804
+
3805
+ mrb_get_args(mrb, "n|o&", &mid, &proc, &blk);
3806
+ switch (mrb_type(proc)) {
3807
+ case MRB_TT_PROC:
3808
+ blk = proc;
3809
+ break;
3810
+ case MRB_TT_UNDEF:
3811
+ /* ignored */
3812
+ break;
3813
+ default:
3814
+ mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %T (expected Proc)", proc);
3815
+ break;
3816
+ }
3817
+ if (mrb_nil_p(blk)) {
3818
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
3819
+ }
3820
+ struct RProc *p = MRB_OBJ_ALLOC(mrb, MRB_TT_PROC, mrb->proc_class);
3821
+ mrb_proc_copy(mrb, p, mrb_proc_ptr(blk));
3822
+ p->flags |= MRB_PROC_STRICT;
3823
+
3824
+ mrb_method_t m;
3825
+ MRB_METHOD_FROM_PROC(m, p);
3826
+ MRB_METHOD_SET_VISIBILITY(m, vis);
3827
+ mrb_define_method_raw(mrb, c, mid, m);
3828
+ mrb_method_added(mrb, c, mid);
3829
+ return mrb_symbol_value(mid);
3830
+ }
3831
+
3832
+ mrb_value
3833
+ mrb_mod_define_method_m(mrb_state *mrb, struct RClass *c)
3834
+ {
3835
+ return define_method_m(mrb, c, MRB_METHOD_PUBLIC_FL);
3836
+ }
3837
+
3838
+ static mrb_value
3839
+ mod_define_method(mrb_state *mrb, mrb_value self)
3840
+ {
3841
+ return mrb_mod_define_method_m(mrb, mrb_class_ptr(self));
3842
+ }
3843
+
3844
+ static mrb_value
3845
+ top_define_method(mrb_state *mrb, mrb_value self)
3846
+ {
3847
+ return define_method_m(mrb, mrb->object_class, MRB_METHOD_PRIVATE_FL);
3848
+ }
3849
+
3850
+ static mrb_value
3851
+ mrb_mod_eqq(mrb_state *mrb, mrb_value mod)
3852
+ {
3853
+ mrb_value obj = mrb_get_arg1(mrb);
3854
+ mrb_bool eqq = mrb_obj_is_kind_of(mrb, obj, mrb_class_ptr(mod));
3855
+
3856
+ return mrb_bool_value(eqq);
3857
+ }
3858
+
3859
+ static mrb_value
3860
+ mrb_mod_dup(mrb_state *mrb, mrb_value self)
3861
+ {
3862
+ mrb_value mod = mrb_obj_clone(mrb, self);
3863
+ mrb_obj_ptr(mod)->frozen = 0;
3864
+ return mod;
3865
+ }
3866
+
3867
+ static mrb_value
3868
+ mrb_mod_module_function(mrb_state *mrb, mrb_value mod)
3869
+ {
3870
+ const mrb_value *argv;
3871
+ mrb_int argc;
3872
+
3873
+ mrb_check_type(mrb, mod, MRB_TT_MODULE);
3874
+
3875
+ mrb_get_args(mrb, "*", &argv, &argc);
3876
+ if (argc == 0) {
3877
+ /* set MODFUNC SCOPE if implemented */
3878
+ return mod;
3879
+ }
3880
+
3881
+ /* set PRIVATE method visibility if implemented */
3882
+ /* mrb_mod_dummy_visibility(mrb, mod); */
3883
+
3884
+ struct RClass *rclass = mrb_class_ptr(mod);
3885
+ int ai = mrb_gc_arena_save(mrb);
3886
+ for (int i=0; i<argc; i++) {
3887
+ mrb_check_type(mrb, argv[i], MRB_TT_SYMBOL);
3888
+
3889
+ mrb_sym mid = mrb_symbol(argv[i]);
3890
+ mrb_method_t m = mrb_method_search(mrb, rclass, mid);
3891
+
3892
+ prepare_singleton_class(mrb, (struct RBasic*)rclass);
3893
+ MRB_METHOD_SET_VISIBILITY(m, MRB_METHOD_PUBLIC_FL);
3894
+ mrb_define_method_raw(mrb, rclass->c, mid, m);
3895
+ mrb_gc_arena_restore(mrb, ai);
3896
+ }
3897
+
3898
+ return mod;
3899
+ }
3900
+
3901
+ static struct RClass*
3902
+ mrb_singleton_class_clone(mrb_state *mrb, mrb_value obj)
3903
+ {
3904
+ struct RClass *klass = mrb_basic_ptr(obj)->c;
3905
+
3906
+ if (klass->tt != MRB_TT_SCLASS)
3907
+ return klass;
3908
+ else {
3909
+ /* copy singleton(unnamed) class */
3910
+ struct RClass *clone = (struct RClass*)mrb_obj_alloc(mrb, klass->tt, mrb->class_class);
3911
+
3912
+ switch (mrb_type(obj)) {
3913
+ case MRB_TT_CLASS:
3914
+ case MRB_TT_SCLASS:
3915
+ break;
3916
+ default:
3917
+ clone->c = mrb_singleton_class_clone(mrb, mrb_obj_value(klass));
3918
+ break;
3919
+ }
3920
+ clone->super = klass->super;
3921
+ if (klass->iv) {
3922
+ mrb_iv_copy(mrb, mrb_obj_value(clone), mrb_obj_value(klass));
3923
+ mrb_obj_iv_set(mrb, (struct RObject*)clone, MRB_SYM(__attached__), obj);
3924
+ }
3925
+ if (klass->mt) {
3926
+ clone->mt = mt_copy(mrb, klass->mt);
3927
+ }
3928
+ else {
3929
+ clone->mt = mt_new(mrb);
3930
+ }
3931
+ clone->tt = MRB_TT_SCLASS;
3932
+ return clone;
3933
+ }
3934
+ }
3935
+
3936
+ static void
3937
+ copy_class(mrb_state *mrb, mrb_value dst, mrb_value src)
3938
+ {
3939
+ struct RClass *dc = mrb_class_ptr(dst);
3940
+ struct RClass *sc = mrb_class_ptr(src);
3941
+ /* if the origin is not the same as the class, then the origin and
3942
+ the current class need to be copied */
3943
+ if (sc->flags & MRB_FL_CLASS_IS_PREPENDED) {
3944
+ struct RClass *c0 = sc->super;
3945
+ struct RClass *c1 = dc;
3946
+
3947
+ /* copy prepended iclasses */
3948
+ while (!(c0->flags & MRB_FL_CLASS_IS_ORIGIN)) {
3949
+ c1->super = mrb_class_ptr(mrb_obj_dup(mrb, mrb_obj_value(c0)));
3950
+ c1 = c1->super;
3951
+ c0 = c0->super;
3952
+ }
3953
+ c1->super = mrb_class_ptr(mrb_obj_dup(mrb, mrb_obj_value(c0)));
3954
+ c1->super->flags |= MRB_FL_CLASS_IS_ORIGIN;
3955
+ }
3956
+ if (sc->mt) {
3957
+ if (sc->tt == MRB_TT_ICLASS && !(sc->flags & MRB_FL_CLASS_IS_ORIGIN)) {
3958
+ dc->mt = sc->mt;
3959
+ }
3960
+ else {
3961
+ dc->mt = mt_copy(mrb, sc->mt);
3962
+ }
3963
+ }
3964
+ dc->super = sc->super;
3965
+ dc->flags = sc->flags;
3966
+ dc->frozen = 0;
3967
+ }
3968
+
3969
+ /* 15.3.1.3.16 */
3970
+ mrb_value mrb_obj_init_copy(mrb_state *mrb, mrb_value self);
3971
+
3972
+ static void
3973
+ init_copy(mrb_state *mrb, mrb_value dest, mrb_value obj)
3974
+ {
3975
+ mrb_assert((mrb_type(dest) == mrb_type(obj)));
3976
+ switch (mrb_unboxed_type(obj)) {
3977
+ case MRB_TT_ICLASS:
3978
+ copy_class(mrb, dest, obj);
3979
+ return;
3980
+ case MRB_TT_CLASS:
3981
+ case MRB_TT_MODULE:
3982
+ copy_class(mrb, dest, obj);
3983
+ mrb_iv_copy(mrb, dest, obj);
3984
+ mrb_iv_remove(mrb, dest, MRB_SYM(__classname__));
3985
+ break;
3986
+ case MRB_TT_OBJECT:
3987
+ case MRB_TT_SCLASS:
3988
+ case MRB_TT_HASH:
3989
+ case MRB_TT_CDATA:
3990
+ case MRB_TT_EXCEPTION:
3991
+ mrb_iv_copy(mrb, dest, obj);
3992
+ break;
3993
+ case MRB_TT_ISTRUCT:
3994
+ mrb_istruct_copy(dest, obj);
3995
+ break;
3996
+ #if !defined(MRB_NO_FLOAT) && defined(MRB_WORD_BOXING)
3997
+ case MRB_TT_FLOAT:
3998
+ {
3999
+ struct RFloat *f = (struct RFloat*)mrb_obj_ptr(dest);
4000
+ f->f = mrb_float(obj);
4001
+ }
4002
+ break;
4003
+ #endif
4004
+ #ifdef MRB_USE_BIGINT
4005
+ case MRB_TT_BIGINT:
4006
+ mrb_bint_copy(mrb, dest, obj);
4007
+ break;
4008
+ #endif
4009
+ #ifdef MRB_USE_RATIONAL
4010
+ case MRB_TT_RATIONAL:
4011
+ mrb_rational_copy(mrb, dest, obj);
4012
+ break;
4013
+ #endif
4014
+ #ifdef MRB_USE_COMPLEX
4015
+ case MRB_TT_COMPLEX:
4016
+ mrb_complex_copy(mrb, dest, obj);
4017
+ break;
4018
+ #endif
4019
+
4020
+ default:
4021
+ break;
4022
+ }
4023
+ if (!mrb_func_basic_p(mrb, dest, MRB_SYM(initialize_copy), mrb_obj_init_copy)) {
4024
+ mrb_funcall_argv(mrb, dest, MRB_SYM(initialize_copy), 1, &obj);
4025
+ }
4026
+ }
4027
+
4028
+ /* 15.3.1.3.8 */
4029
+ /*
4030
+ * call-seq:
4031
+ * obj.clone -> an_object
4032
+ *
4033
+ * Produces a shallow copy of *obj*---the instance variables of
4034
+ * *obj* are copied, but not the objects they reference. Copies
4035
+ * the frozen state of *obj*. See also the discussion
4036
+ * under `Object#dup`.
4037
+ *
4038
+ * class Klass
4039
+ * attr_accessor :str
4040
+ * end
4041
+ * s1 = Klass.new #=> #<Klass:0x401b3a38>
4042
+ * s1.str = "Hello" #=> "Hello"
4043
+ * s2 = s1.clone #=> #<Klass:0x401b3998 @str="Hello">
4044
+ * s2.str[1,4] = "i" #=> "i"
4045
+ * s1.inspect #=> "#<Klass:0x401b3a38 @str=\"Hi\">"
4046
+ * s2.inspect #=> "#<Klass:0x401b3998 @str=\"Hi\">"
4047
+ *
4048
+ * This method may have class-specific behavior. If so, that
4049
+ * behavior will be documented under the #`initialize_copy` method of
4050
+ * the class.
4051
+ *
4052
+ * Some Class(True False Nil Symbol Integer Float) Object cannot clone.
4053
+ */
4054
+ /*
4055
+ * Creates a shallow copy of the given object `self`.
4056
+ *
4057
+ * This function performs a shallow copy, meaning instance variables are copied,
4058
+ * but the objects they refer to are not duplicated. The frozen state of the
4059
+ * original object is also copied to the clone. If the object has a singleton
4060
+ * class, that singleton class is also cloned and associated with the new object.
4061
+ * After the new object is created and its basic state is copied, its
4062
+ * `initialize_copy` method is called with the original object as an argument,
4063
+ * allowing for class-specific adjustments to the cloning process.
4064
+ *
4065
+ * @param mrb The mruby state.
4066
+ * @param self The `mrb_value` object to clone.
4067
+ * @return A new `mrb_value` which is a clone of `self`.
4068
+ * @raise TypeError if `self` is an immediate value (e.g., Fixnum, Symbol in some
4069
+ * configurations) or if `self` is a singleton class itself, as these
4070
+ * cannot be cloned.
4071
+ * @sideeffect
4072
+ * 1. Allocates a new object on the mruby heap.
4073
+ * 2. Copies instance variables from `self` to the new object.
4074
+ * 3. If `self` has a singleton class, it is cloned and assigned to the new object.
4075
+ * This involves further allocations and setup for the new singleton class.
4076
+ * 4. The `frozen` state of `self` is propagated to the clone.
4077
+ * 5. Calls the `initialize_copy` method on the newly created clone, passing `self`
4078
+ * as an argument. This method can have arbitrary side effects.
4079
+ */
4080
+ MRB_API mrb_value
4081
+ mrb_obj_clone(mrb_state *mrb, mrb_value self)
4082
+ {
4083
+ if (mrb_immediate_p(self)) {
4084
+ return self;
4085
+ }
4086
+ if (mrb_sclass_p(self)) {
4087
+ mrb_raise(mrb, E_TYPE_ERROR, "can't clone singleton class");
4088
+ }
4089
+ struct RObject *p = (struct RObject*)mrb_obj_alloc(mrb, mrb_unboxed_type(self), mrb_obj_class(mrb, self));
4090
+ p->c = mrb_singleton_class_clone(mrb, self);
4091
+ mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)p->c);
4092
+
4093
+ mrb_value clone = mrb_obj_value(p);
4094
+ init_copy(mrb, clone, self);
4095
+ p->frozen = mrb_obj_ptr(self)->frozen;
4096
+
4097
+ return clone;
4098
+ }
4099
+
4100
+ /* 15.3.1.3.9 */
4101
+ /*
4102
+ * call-seq:
4103
+ * obj.dup -> an_object
4104
+ *
4105
+ * Produces a shallow copy of *obj*---the instance variables of
4106
+ * *obj* are copied, but not the objects they reference.
4107
+ * `dup` copies the frozen state of *obj*. See also
4108
+ * the discussion under `Object#clone`. In general,
4109
+ * `clone` and `dup` may have different semantics
4110
+ * in descendant classes. While `clone` is used to duplicate
4111
+ * an object, including its internal state, `dup` typically
4112
+ * uses the class of the descendant object to create the new instance.
4113
+ *
4114
+ * This method may have class-specific behavior. If so, that
4115
+ * behavior will be documented under the #`initialize_copy` method of
4116
+ * the class.
4117
+ */
4118
+
4119
+ /*
4120
+ * Creates a shallow copy of the given object `obj`.
4121
+ *
4122
+ * This function performs a shallow copy, meaning instance variables are copied,
4123
+ * but the objects they refer to are not duplicated. Unlike `mrb_obj_clone`,
4124
+ * `mrb_obj_dup` does *not* copy the frozen state of the original object; the
4125
+ * duplicated object is always unfrozen. Also, it does not copy the singleton class.
4126
+ * After the new object is created and its basic state is copied, its
4127
+ * `initialize_copy` method is called with the original object as an argument.
4128
+ *
4129
+ * @param mrb The mruby state.
4130
+ * @param obj The `mrb_value` object to duplicate.
4131
+ * @return A new `mrb_value` which is a duplicate of `obj`.
4132
+ * @raise TypeError if `obj` is an immediate value (e.g., Fixnum, Symbol in some
4133
+ * configurations) or if `obj` is a singleton class itself, as these
4134
+ * cannot be duplicated.
4135
+ * @sideeffect
4136
+ * 1. Allocates a new object on the mruby heap with the same class as `obj`.
4137
+ * 2. Copies instance variables from `obj` to the new object.
4138
+ * 3. The new object is *not* frozen, regardless of `obj`'s frozen state.
4139
+ * 4. The singleton class of `obj` (if any) is *not* copied.
4140
+ * 5. Calls the `initialize_copy` method on the newly created duplicate, passing `obj`
4141
+ * as an argument. This method can have arbitrary side effects.
4142
+ */
4143
+ MRB_API mrb_value
4144
+ mrb_obj_dup(mrb_state *mrb, mrb_value obj)
4145
+ {
4146
+ if (mrb_immediate_p(obj)) {
4147
+ return obj;
4148
+ }
4149
+ if (mrb_sclass_p(obj)) {
4150
+ mrb_raise(mrb, E_TYPE_ERROR, "can't dup singleton class");
4151
+ }
4152
+
4153
+ struct RBasic *p = mrb_obj_alloc(mrb, mrb_type(obj), mrb_obj_class(mrb, obj));
4154
+ mrb_value dup = mrb_obj_value(p);
4155
+ init_copy(mrb, dup, obj);
4156
+
4157
+ return dup;
4158
+ }
4159
+
4160
+ /* implementation of __id__ */
4161
+ mrb_value mrb_obj_id_m(mrb_state *mrb, mrb_value self);
4162
+
4163
+ mrb_noreturn void
4164
+ mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args)
4165
+ {
4166
+ mrb_no_method_error(mrb, name, args, "undefined method '%n' for %T", name, self);
4167
+ }
4168
+
4169
+ /* 15.3.1.3.30 */
4170
+ /*
4171
+ * call-seq:
4172
+ * obj.method_missing(symbol [, *args] ) -> result
4173
+ *
4174
+ * Invoked by Ruby when *obj* is sent a message it cannot handle.
4175
+ * *symbol* is the symbol for the method called, and *args*
4176
+ * are any arguments that were passed to it. By default, the interpreter
4177
+ * raises an error when this method is called. However, it is possible
4178
+ * to override the method to provide more dynamic behavior.
4179
+ * If it is decided that a particular method should not be handled, then
4180
+ * *super* should be called, so that ancestors can pick up the
4181
+ * missing method.
4182
+ * The example below creates
4183
+ * a class `Roman`, which responds to methods with names
4184
+ * consisting of roman numerals, returning the corresponding integer
4185
+ * values.
4186
+ *
4187
+ * class Roman
4188
+ * def romanToInt(str)
4189
+ * # ...
4190
+ * end
4191
+ * def method_missing(sym)
4192
+ * str = sym.to_s
4193
+ * romanToInt(str)
4194
+ * end
4195
+ * end
4196
+ *
4197
+ * r = Roman.new
4198
+ * r.iv #=> 4
4199
+ * r.xxiii #=> 23
4200
+ * r.mm #=> 2000
4201
+ */
4202
+ mrb_value
4203
+ mrb_obj_missing(mrb_state *mrb, mrb_value mod)
4204
+ {
4205
+ mrb_sym name;
4206
+ const mrb_value *a;
4207
+ mrb_int alen;
4208
+
4209
+ mrb->c->ci->mid = 0;
4210
+ mrb_get_args(mrb, "n*!", &name, &a, &alen);
4211
+ mrb_method_missing(mrb, name, mod, mrb_ary_new_from_values(mrb, alen, a));
4212
+ /* not reached */
4213
+ return mrb_nil_value();
4214
+ }
4215
+
4216
+ static mrb_value
4217
+ inspect_main(mrb_state *mrb, mrb_value mod)
4218
+ {
4219
+ return mrb_str_new_lit(mrb, "main");
4220
+ }
4221
+
4222
+ static const mrb_code new_iseq[] = {
4223
+ OP_ENTER, 0x0, 0x10, 0x3, // 000 OP_ENTER 0:0:1:0:0:1:1
4224
+ OP_SSEND, 4, 0, 0, // 004 OP_SSEND R4 :allocate n=0
4225
+ OP_MOVE, 0, 4, // 008 OP_MOVE R0 R4
4226
+ OP_MOVE, 4, 3, // 011 OP_MOVE R4 R3 ; &
4227
+ OP_MOVE, 3, 2, // 014 OP_MOVE R3 R2 ; **
4228
+ OP_MOVE, 2, 1, // 017 OP_MOVE R2 R1 ; *
4229
+ OP_SSENDB, 1, 1, 255, // 020 OP_SSENDB R1 :initialize n=*|nk=*
4230
+ OP_RETURN, 0 // 024 OP_RETURN R0
4231
+ };
4232
+
4233
+ MRB_PRESYM_DEFINE_VAR_AND_INITER(new_syms, 2, MRB_SYM(allocate), MRB_SYM(initialize))
4234
+
4235
+ static const mrb_irep new_irep = {
4236
+ 4, 6, 0, MRB_IREP_STATIC,
4237
+ new_iseq, NULL, new_syms, NULL, NULL, NULL,
4238
+ sizeof(new_iseq), 0, 2, 0, 0,
4239
+ };
4240
+
4241
+ mrb_alignas(8)
4242
+ static const struct RProc new_proc = {
4243
+ NULL, MRB_TT_PROC, MRB_GC_RED, MRB_OBJ_IS_FROZEN, MRB_PROC_SCOPE | MRB_PROC_STRICT,
4244
+ { &new_irep }, NULL, { NULL }
4245
+ };
4246
+
4247
+ static void
4248
+ init_class_new(mrb_state *mrb, struct RClass *cls)
4249
+ {
4250
+ mrb_method_t m;
4251
+
4252
+ MRB_PRESYM_INIT_SYMBOLS(mrb, new_syms);
4253
+ MRB_METHOD_FROM_PROC(m, &new_proc);
4254
+ mrb_define_method_raw(mrb, cls, MRB_SYM(new), m);
4255
+ }
4256
+
4257
+ static const mrb_code neq_iseq[] = {
4258
+ OP_ENTER, 0x4, 0, 0, // 000 OP_ENTER 1:0:0:0:0:0:0
4259
+ OP_EQ, 0, // 004 OP_EQ R0 (R1)
4260
+ OP_JMPNOT, 0, 0, 5, // 006 OP_JMPNOT R0 015
4261
+ OP_LOADFALSE, 0, // 010 OP_LOADFALSE R0 (false)
4262
+ OP_JMP, 0, 2, // 012 OP_JMP 017
4263
+ OP_LOADTRUE, 0, // 015 OP_LOADTRUE R0 (true)
4264
+ OP_RETURN, 0 // 017 OP_RETURN R0
4265
+ };
4266
+
4267
+ static const mrb_irep neq_irep = {
4268
+ 4, 6, 0, MRB_IREP_STATIC,
4269
+ neq_iseq, NULL, NULL, NULL, NULL, NULL,
4270
+ sizeof(neq_iseq), 0, 2, 0, 0,
4271
+ };
4272
+
4273
+ mrb_alignas(8)
4274
+ static const struct RProc neq_proc = {
4275
+ NULL, MRB_TT_PROC, MRB_GC_RED, MRB_OBJ_IS_FROZEN, MRB_PROC_SCOPE | MRB_PROC_STRICT,
4276
+ { &neq_irep }, NULL, { NULL }
4277
+ };
4278
+
4279
+ /* ---------------------------*/
4280
+ static const mrb_mt_entry bob_rom_entries[] = {
4281
+ MRB_MT_ENTRY(mrb_obj_equal_m, MRB_OPSYM(eq), MRB_ARGS_REQ(1)), /* 15.3.1.3.1 */
4282
+ MRB_MT_ENTRY(mrb_bob_not, MRB_OPSYM(not), MRB_ARGS_NONE()),
4283
+ MRB_MT_ENTRY(mrb_obj_id_m, MRB_SYM(__id__), MRB_ARGS_NONE()), /* 15.3.1.3.4 */
4284
+ MRB_MT_ENTRY(mrb_f_send, MRB_SYM(__send__), MRB_ARGS_REQ(1)|MRB_ARGS_REST()|MRB_ARGS_BLOCK()), /* 15.3.1.3.5 */
4285
+ MRB_MT_ENTRY(mrb_obj_equal_m, MRB_SYM_Q(equal), MRB_ARGS_REQ(1)), /* 15.3.1.3.11 */
4286
+ MRB_MT_ENTRY(mrb_do_nothing, MRB_SYM(initialize), MRB_ARGS_NONE() | MRB_MT_PRIVATE),
4287
+ MRB_MT_ENTRY(mrb_obj_instance_eval, MRB_SYM(instance_eval), MRB_ARGS_OPT(1)|MRB_ARGS_BLOCK()), /* 15.3.1.3.18 */
4288
+ MRB_MT_ENTRY(mrb_obj_missing, MRB_SYM(method_missing), MRB_ARGS_ANY() | MRB_MT_PRIVATE), /* 15.3.1.3.30 */
4289
+ MRB_MT_ENTRY(mrb_do_nothing, MRB_SYM(singleton_method_added), MRB_ARGS_REQ(1) | MRB_MT_PRIVATE),
4290
+ MRB_MT_ENTRY(mrb_do_nothing, MRB_SYM(singleton_method_removed), MRB_ARGS_REQ(1) | MRB_MT_PRIVATE),
4291
+ MRB_MT_ENTRY(mrb_do_nothing, MRB_SYM(singleton_method_undefined), MRB_ARGS_REQ(1) | MRB_MT_PRIVATE),
4292
+ };
4293
+
4294
+ static const mrb_mt_entry cls_rom_entries[] = {
4295
+ MRB_MT_ENTRY(mrb_instance_alloc, MRB_SYM(allocate), MRB_ARGS_NONE()),
4296
+ MRB_MT_ENTRY(mrb_do_nothing, MRB_SYM(inherited), MRB_ARGS_REQ(1) | MRB_MT_PRIVATE),
4297
+ MRB_MT_ENTRY(mrb_class_initialize, MRB_SYM(initialize), MRB_ARGS_OPT(1) | MRB_MT_PRIVATE), /* 15.2.3.3.1 */
4298
+ MRB_MT_ENTRY(mrb_class_superclass, MRB_SYM(superclass), MRB_ARGS_NONE()), /* 15.2.3.3.4 */
4299
+ };
4300
+
4301
+ static const mrb_mt_entry mod_rom_entries[] = {
4302
+ MRB_MT_ENTRY(mrb_mod_eqq, MRB_OPSYM(eqq), MRB_ARGS_REQ(1)), /* 15.2.2.4.7 */
4303
+ MRB_MT_ENTRY(mrb_mod_alias, MRB_SYM(alias_method), MRB_ARGS_ANY()), /* 15.2.2.4.8 */
4304
+ MRB_MT_ENTRY(mrb_mod_ancestors, MRB_SYM(ancestors), MRB_ARGS_NONE()), /* 15.2.2.4.9 */
4305
+ MRB_MT_ENTRY(mrb_mod_attr_accessor, MRB_SYM(attr_accessor), MRB_ARGS_ANY()), /* 15.2.2.4.12 */
4306
+ MRB_MT_ENTRY(mrb_mod_attr_reader, MRB_SYM(attr_reader), MRB_ARGS_ANY()), /* 15.2.2.4.13 */
4307
+ MRB_MT_ENTRY(mrb_mod_attr_writer, MRB_SYM(attr_writer), MRB_ARGS_ANY()), /* 15.2.2.4.14 */
4308
+ MRB_MT_ENTRY(mrb_mod_module_eval, MRB_SYM(class_eval), MRB_ARGS_ANY()), /* 15.2.2.4.15 */
4309
+ MRB_MT_ENTRY(mrb_do_nothing, MRB_SYM(const_added), MRB_ARGS_REQ(1) | MRB_MT_PRIVATE),
4310
+ MRB_MT_ENTRY(mrb_mod_const_defined, MRB_SYM_Q(const_defined), MRB_ARGS_ARG(1,1)), /* 15.2.2.4.20 */
4311
+ MRB_MT_ENTRY(mrb_mod_const_get, MRB_SYM(const_get), MRB_ARGS_REQ(1)), /* 15.2.2.4.21 */
4312
+ MRB_MT_ENTRY(mrb_mod_const_missing, MRB_SYM(const_missing), MRB_ARGS_REQ(1)),
4313
+ MRB_MT_ENTRY(mrb_mod_const_set, MRB_SYM(const_set), MRB_ARGS_REQ(2)), /* 15.2.2.4.23 */
4314
+ MRB_MT_ENTRY(mod_define_method, MRB_SYM(define_method), MRB_ARGS_ARG(1,1)),
4315
+ MRB_MT_ENTRY(mrb_mod_dup, MRB_SYM(dup), MRB_ARGS_NONE()),
4316
+ MRB_MT_ENTRY(mrb_do_nothing, MRB_SYM(extended), MRB_ARGS_REQ(1) | MRB_MT_PRIVATE), /* 15.2.2.4.26 */
4317
+ MRB_MT_ENTRY(mrb_mod_include, MRB_SYM(include), MRB_ARGS_ANY()), /* 15.2.2.4.27 */
4318
+ MRB_MT_ENTRY(mrb_mod_include_p, MRB_SYM_Q(include), MRB_ARGS_REQ(1)), /* 15.2.2.4.28 */
4319
+ MRB_MT_ENTRY(mrb_do_nothing, MRB_SYM(included), MRB_ARGS_REQ(1) | MRB_MT_PRIVATE), /* 15.2.2.4.29 */
4320
+ MRB_MT_ENTRY(mrb_mod_initialize, MRB_SYM(initialize), MRB_ARGS_NONE() | MRB_MT_PRIVATE), /* 15.2.2.4.31 */
4321
+ MRB_MT_ENTRY(mrb_mod_to_s, MRB_SYM(inspect), MRB_ARGS_NONE()),
4322
+ MRB_MT_ENTRY(mrb_do_nothing, MRB_SYM(method_added), MRB_ARGS_REQ(1) | MRB_MT_PRIVATE),
4323
+ MRB_MT_ENTRY(mrb_do_nothing, MRB_SYM(method_removed), MRB_ARGS_REQ(1) | MRB_MT_PRIVATE),
4324
+ MRB_MT_ENTRY(mrb_mod_method_defined, MRB_SYM_Q(method_defined), MRB_ARGS_REQ(1)), /* 15.2.2.4.34 */
4325
+ MRB_MT_ENTRY(mrb_do_nothing, MRB_SYM(method_undefined), MRB_ARGS_REQ(1) | MRB_MT_PRIVATE),
4326
+ MRB_MT_ENTRY(mrb_mod_module_eval, MRB_SYM(module_eval), MRB_ARGS_ANY()), /* 15.2.2.4.35 */
4327
+ MRB_MT_ENTRY(mrb_mod_module_function, MRB_SYM(module_function), MRB_ARGS_ANY() | MRB_MT_PRIVATE),
4328
+ MRB_MT_ENTRY(mrb_mod_prepend, MRB_SYM(prepend), MRB_ARGS_ANY()),
4329
+ MRB_MT_ENTRY(mrb_do_nothing, MRB_SYM(prepended), MRB_ARGS_REQ(1) | MRB_MT_PRIVATE),
4330
+ MRB_MT_ENTRY(mrb_mod_private, MRB_SYM(private), MRB_ARGS_ANY() | MRB_MT_PRIVATE), /* 15.2.2.4.36 */
4331
+ MRB_MT_ENTRY(mrb_mod_protected, MRB_SYM(protected), MRB_ARGS_ANY() | MRB_MT_PRIVATE), /* 15.2.2.4.37 */
4332
+ MRB_MT_ENTRY(mrb_mod_public, MRB_SYM(public), MRB_ARGS_ANY() | MRB_MT_PRIVATE), /* 15.2.2.4.38 */
4333
+ MRB_MT_ENTRY(mrb_mod_remove_const, MRB_SYM(remove_const), MRB_ARGS_REQ(1) | MRB_MT_PRIVATE), /* 15.2.2.4.40 */
4334
+ MRB_MT_ENTRY(mrb_mod_to_s, MRB_SYM(to_s), MRB_ARGS_NONE()),
4335
+ MRB_MT_ENTRY(mrb_mod_undef, MRB_SYM(undef_method), MRB_ARGS_ANY()), /* 15.2.2.4.41 */
4336
+ };
4337
+
4338
+ void
4339
+ mrb_init_class(mrb_state *mrb)
4340
+ {
4341
+ struct RClass *bob; /* BasicObject */
4342
+ struct RClass *obj; /* Object */
4343
+ struct RClass *mod; /* Module */
4344
+ struct RClass *cls; /* Class */
4345
+
4346
+ /* boot class hierarchy */
4347
+ bob = boot_defclass(mrb, 0, MRB_TT_OBJECT);
4348
+ obj = boot_defclass(mrb, bob, MRB_TT_OBJECT); mrb->object_class = obj;
4349
+ mod = boot_defclass(mrb, obj, MRB_TT_MODULE); mrb->module_class = mod;/* obj -> mod */
4350
+ cls = boot_defclass(mrb, mod, MRB_TT_CLASS); mrb->class_class = cls; /* obj -> cls */
4351
+
4352
+ /* fix-up loose ends */
4353
+ bob->c = obj->c = mod->c = cls->c = cls;
4354
+ make_metaclass(mrb, bob);
4355
+ make_metaclass(mrb, obj);
4356
+ make_metaclass(mrb, mod);
4357
+ make_metaclass(mrb, cls);
4358
+
4359
+ /* name basic classes */
4360
+ mrb_define_const_id(mrb, bob, MRB_SYM(BasicObject), mrb_obj_value(bob));
4361
+ mrb_define_const_id(mrb, obj, MRB_SYM(Object), mrb_obj_value(obj));
4362
+ mrb_define_const_id(mrb, obj, MRB_SYM(Module), mrb_obj_value(mod));
4363
+ mrb_define_const_id(mrb, obj, MRB_SYM(Class), mrb_obj_value(cls));
4364
+
4365
+ /* name each classes */
4366
+ mrb_class_name_class(mrb, NULL, bob, MRB_SYM(BasicObject));
4367
+ mrb_class_name_class(mrb, NULL, obj, MRB_SYM(Object)); /* 15.2.1 */
4368
+ mrb_class_name_class(mrb, NULL, mod, MRB_SYM(Module)); /* 15.2.2 */
4369
+ mrb_class_name_class(mrb, NULL, cls, MRB_SYM(Class)); /* 15.2.3 */
4370
+
4371
+ MRB_MT_INIT_ROM(mrb, bob, bob_rom_entries);
4372
+
4373
+ mrb_method_t m;
4374
+ MRB_METHOD_FROM_PROC(m, &neq_proc);
4375
+ mrb_define_method_raw(mrb, bob, MRB_OPSYM(neq), m);
4376
+
4377
+ mrb_define_class_method_id(mrb, cls, MRB_SYM(new), mrb_class_new_class, MRB_ARGS_OPT(1)|MRB_ARGS_BLOCK());
4378
+ MRB_MT_INIT_ROM(mrb, cls, cls_rom_entries);
4379
+
4380
+ init_class_new(mrb, cls);
4381
+
4382
+ MRB_MT_INIT_ROM(mrb, mod, mod_rom_entries);
4383
+ mrb_define_alias_id(mrb, mod, MRB_SYM(attr), MRB_SYM(attr_reader)); /* 15.2.2.4.11 */
4384
+
4385
+ mrb_undef_method_id(mrb, cls, MRB_SYM(module_function));
4386
+
4387
+ mrb->top_self = MRB_OBJ_ALLOC(mrb, MRB_TT_OBJECT, mrb->object_class);
4388
+ mrb_define_singleton_method_id(mrb, mrb->top_self, MRB_SYM(inspect), inspect_main, MRB_ARGS_NONE());
4389
+ mrb_define_singleton_method_id(mrb, mrb->top_self, MRB_SYM(to_s), inspect_main, MRB_ARGS_NONE());
4390
+ mrb_define_singleton_method_id(mrb, mrb->top_self, MRB_SYM(define_method), top_define_method, MRB_ARGS_ARG(1,1));
4391
+ mrb_define_singleton_method_id(mrb, mrb->top_self, MRB_SYM(public), top_public, MRB_ARGS_ANY());
4392
+ mrb_define_singleton_method_id(mrb, mrb->top_self, MRB_SYM(private), top_private, MRB_ARGS_ANY());
4393
+ mrb_define_singleton_method_id(mrb, mrb->top_self, MRB_SYM(protected), top_protected, MRB_ARGS_ANY());
4394
+ }