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,2355 @@
1
+ /*
2
+ ** hash.c - Hash class
3
+ **
4
+ ** See Copyright Notice in mruby.h
5
+ */
6
+
7
+ #include <string.h>
8
+ #include <mruby.h>
9
+ #include <mruby/array.h>
10
+ #include <mruby/class.h>
11
+ #include <mruby/hash.h>
12
+ #include <mruby/string.h>
13
+ #include <mruby/variable.h>
14
+ #include <mruby/proc.h>
15
+ #include <mruby/internal.h>
16
+ #include <mruby/presym.h>
17
+
18
+
19
+ /*
20
+ * === Glossary
21
+ *
22
+ * [EA]
23
+ * Entry Array. Store `Hash' entries in insertion order.
24
+ *
25
+ * [AR]
26
+ * Array Table Implementation. The structure of `Hash` that doesn't have a
27
+ * hash table and linearly searches EA. It is used when `Hash` size <= 16.
28
+ *
29
+ * [IB]
30
+ * Index Buckets. The buckets of hash table, where the bucket value is EA
31
+ * index. The index is represented by variable length bits according to
32
+ * the capacity.
33
+ *
34
+ * [HT]
35
+ * Hash Table Implementation. The structure of `Hash` that has IB and is
36
+ * searched by hash table algorithm. It is used when `Hash` size > 16.
37
+ * Collision resolution strategy is open addressing method.
38
+ *
39
+ * [size]
40
+ * The number of `Hash` entries (value of `Hash#size`).
41
+ *
42
+ * [slot]
43
+ * The generic term for EA or IB elements.
44
+ *
45
+ * [active]
46
+ * The state in which a slot is recognized as a `Hash` entry.
47
+ *
48
+ * [deleted]
49
+ * The state in which a slot is marked as deleted.
50
+ *
51
+ * [used]
52
+ * The state in which a slot is active or deleted.
53
+ *
54
+ * [empty]
55
+ * The state in which a slot is not used. Capacity is equal to the sum of
56
+ * the number of used slots and the number of empty slots.
57
+ */
58
+
59
+ #define EA_N_RESERVED_INDICES 2 /* empty and deleted */
60
+
61
+ #define EA_MAX_INCREASE UINT16_MAX
62
+ #define EA_MAX_CAPA U32(lesser(IB_MAX_CAPA - EA_N_RESERVED_INDICES, MRB_INT_MAX))
63
+ #define IB_MAX_CAPA (U32(1) << IB_MAX_BIT)
64
+ #define IB_TYPE_BIT 32
65
+ #define IB_INIT_BIT ( \
66
+ ib_upper_bound_for(32) <= AR_MAX_SIZE ? 6 : \
67
+ ib_upper_bound_for(16) <= AR_MAX_SIZE ? 5 : \
68
+ 4 \
69
+ )
70
+ #define IB_MAX_BIT (IB_TYPE_BIT - 1)
71
+ #define AR_DEFAULT_CAPA 4
72
+ #define AR_MAX_SIZE 16
73
+ #define H_MAX_SIZE EA_MAX_CAPA
74
+
75
+ mrb_static_assert(offsetof(struct RHash, iv) == offsetof(struct RObject, iv));
76
+ mrb_static_assert(AR_MAX_SIZE < (1 << MRB_HASH_AR_EA_CAPA_BIT));
77
+
78
+ typedef struct hash_entry {
79
+ mrb_value key;
80
+ mrb_value val;
81
+ } hash_entry;
82
+
83
+ typedef struct hash_table {
84
+ hash_entry *ea;
85
+ #ifdef MRB_32BIT
86
+ uint32_t ea_capa;
87
+ uint32_t ea_n_used;
88
+ #endif
89
+ uint32_t ib[];
90
+ } hash_table;
91
+
92
+ typedef struct index_buckets_iter {
93
+ struct RHash *h;
94
+ uint32_t bit;
95
+ uint32_t mask;
96
+ uint32_t initial_pos;
97
+ uint32_t pos;
98
+ uint32_t ary_index;
99
+ uint32_t ea_index;
100
+ uint32_t shift1;
101
+ uint32_t shift2;
102
+ uint32_t step;
103
+ } index_buckets_iter;
104
+
105
+ /*
106
+ * `c_` :: receiver class (category)
107
+ * `n_` :: attribute name
108
+ * `t_` :: attribute type
109
+ * `p_` :: struct member path
110
+ * `k_` :: macro key
111
+ */
112
+ #define DEFINE_GETTER(c_, n_, t_, p_) \
113
+ MRB_INLINE t_ c_##_##n_(const struct RHash *h) {return h->p_;}
114
+ #define DEFINE_SETTER(c_, n_, t_, p_) \
115
+ MRB_INLINE void c_##_set_##n_(struct RHash *h, t_ v) {h->p_ = v;}
116
+ #define DEFINE_ACCESSOR(c_, n_, t_, p_) \
117
+ DEFINE_GETTER(c_, n_, t_, p_) \
118
+ DEFINE_SETTER(c_, n_, t_, p_)
119
+ #define DEFINE_FLAG_GETTER(c_, n_, t_, k_) \
120
+ MRB_INLINE t_ c_##_##n_(const struct RHash *h) { \
121
+ return (t_)((h->flags & MRB_HASH_##k_##_MASK) >> MRB_HASH_##k_##_SHIFT); \
122
+ }
123
+ #define DEFINE_FLAG_SETTER(c_, n_, t_, k_) \
124
+ MRB_INLINE void c_##_set_##n_(struct RHash *h, t_ v) { \
125
+ h->flags &= ~MRB_HASH_##k_##_MASK; \
126
+ h->flags |= v << MRB_HASH_##k_##_SHIFT; \
127
+ }
128
+ #define DEFINE_FLAG_ACCESSOR(c_, n_, t_, k_) \
129
+ DEFINE_FLAG_GETTER(c_, n_, t_, k_) \
130
+ DEFINE_FLAG_SETTER(c_, n_, t_, k_)
131
+ #define DEFINE_INCREMENTER(c_, n_) \
132
+ MRB_INLINE void c_##_inc_##n_(struct RHash *h) { \
133
+ c_##_set_##n_(h, c_##_##n_(h) + 1); \
134
+ }
135
+ #define DEFINE_DECREMENTER(c_, n_) \
136
+ MRB_INLINE void c_##_dec_##n_(struct RHash *h) { \
137
+ c_##_set_##n_(h, c_##_##n_(h) - 1); \
138
+ }
139
+ #define DEFINE_SWITCHER(n_, k_) \
140
+ MRB_INLINE void h_##n_##_on(struct RHash *h) { \
141
+ h->flags |= MRB_HASH_##k_; \
142
+ } \
143
+ MRB_INLINE void h_##n_##_off(struct RHash *h) { \
144
+ h->flags &= ~MRB_HASH_##k_; \
145
+ } \
146
+ MRB_INLINE mrb_bool h_##n_##_p(const struct RHash *h) { \
147
+ return (h->flags & MRB_HASH_##k_) == MRB_HASH_##k_; \
148
+ }
149
+
150
+ #ifdef MRB_64BIT
151
+ DEFINE_ACCESSOR(ar, ea_capa, uint32_t, ea_capa) /* ar_ea_capa ar_set_ea_capa */
152
+ DEFINE_ACCESSOR(ar, ea_n_used, uint32_t, ea_n_used) /* ar_ea_n_used ar_set_ea_n_used */
153
+ DEFINE_ACCESSOR(ht, ea_capa, uint32_t, ea_capa) /* ht_ea_capa ht_set_ea_capa */
154
+ DEFINE_ACCESSOR(ht, ea_n_used, uint32_t, ea_n_used) /* ht_ea_n_used ht_set_ea_n_used */
155
+ #else
156
+ DEFINE_FLAG_ACCESSOR(ar, ea_capa, uint32_t, AR_EA_CAPA) /* ar_ea_capa ar_set_ea_capa */
157
+ DEFINE_FLAG_ACCESSOR(ar, ea_n_used, uint32_t, AR_EA_N_USED) /* ar_ea_n_used ar_set_ea_n_used */
158
+ DEFINE_ACCESSOR(ht, ea_capa, uint32_t, hsh.ht->ea_capa) /* ht_ea_capa ht_set_ea_capa */
159
+ DEFINE_ACCESSOR(ht, ea_n_used, uint32_t, hsh.ht->ea_n_used) /* ht_ea_n_used ht_set_ea_n_used */
160
+ #endif
161
+ DEFINE_FLAG_ACCESSOR(ib, bit, uint32_t, IB_BIT) /* ib_bit ib_set_bit */
162
+ DEFINE_ACCESSOR(ar, size, uint32_t, size) /* ar_size ar_set_size */
163
+ DEFINE_ACCESSOR(ar, ea, hash_entry*, hsh.ea) /* ar_ea ar_set_ea */
164
+ DEFINE_DECREMENTER(ar, size) /* ar_dec_size */
165
+ DEFINE_ACCESSOR(ht, size, uint32_t, size) /* ht_size ht_set_size */
166
+ DEFINE_ACCESSOR(ht, ea, hash_entry*, hsh.ht->ea) /* ht_ea ht_set_ea */
167
+ DEFINE_GETTER(ht, ib, uint32_t*, hsh.ht->ib) /* ht_ib */
168
+ DEFINE_INCREMENTER(ht, size) /* ht_inc_size */
169
+ DEFINE_DECREMENTER(ht, size) /* ht_dec_size */
170
+ DEFINE_GETTER(h, size, uint32_t, size) /* h_size */
171
+ DEFINE_ACCESSOR(h, ht, hash_table*, hsh.ht) /* h_ht h_set_ht */
172
+ DEFINE_SWITCHER(ht, HT) /* h_ht_on h_ht_off h_ht_p */
173
+
174
+ #define EA_EACH_USED(ea, n_used, entry_var) \
175
+ for (hash_entry *entry_var = (ea), *ea_end__ = (entry_var) + (n_used); \
176
+ entry_var < ea_end__; \
177
+ entry_var++)
178
+
179
+ #define EA_EACH(ea, size, entry_var) \
180
+ for (uint32_t ea_size__ = (size); ea_size__; ea_size__ = 0) \
181
+ for (hash_entry *entry_var = (ea); \
182
+ ea_size__ && (entry_var = entry_skip_deleted(entry_var), TRUE); \
183
+ entry_var++, ea_size__--)
184
+
185
+ #define IB_CYCLE_BY_KEY(mrb, h, key, it_var) \
186
+ for (index_buckets_iter it_var[1] = { ib_it_init(mrb, h, key) }; \
187
+ (ib_it_next(it_var), TRUE); \
188
+ /* do nothing */)
189
+
190
+ #define IB_FIND_BY_KEY(mrb, h, key, it_var) \
191
+ for (index_buckets_iter it_var[1] = { ib_it_init(mrb, h, key) }; \
192
+ ib_it_find_by_key(mrb, it_var, key); \
193
+ it_var[0].h = NULL)
194
+
195
+ #define H_EACH(h, entry_var) \
196
+ EA_EACH((h_ar_p(h) ? ar_ea(h) : ht_ea(h)), \
197
+ (h_ar_p(h) ? ar_size(h) : ht_size(h)), \
198
+ entry_var)
199
+
200
+ /*
201
+ * In `H_CHECK_MODIFIED()`, in the case of `MRB_NO_BOXING`, `ht_ea()` or
202
+ * `ht_ea_capa()` for AR may read uninitialized area (#5332). Therefore, do
203
+ * not use those macros for AR in `MRB_NO_BOXING` (but in the case of
204
+ * `MRB_64BIT`, `ht_ea_capa()` is the same as `ar_ea_capa()`, so use it).
205
+ */
206
+ #ifdef MRB_NO_BOXING
207
+ # define H_CHECK_MODIFIED_USE_HT_EA_FOR_AR FALSE
208
+ # ifdef MRB_64BIT
209
+ # define H_CHECK_MODIFIED_USE_HT_EA_CAPA_FOR_AR TRUE
210
+ # else
211
+ # define H_CHECK_MODIFIED_USE_HT_EA_CAPA_FOR_AR FALSE
212
+ # endif /* MRB_64BIT */
213
+ #else
214
+ # define H_CHECK_MODIFIED_USE_HT_EA_FOR_AR TRUE
215
+ # define H_CHECK_MODIFIED_USE_HT_EA_CAPA_FOR_AR TRUE
216
+ /*
217
+ * `H_CHECK_MODIFIED` raises an exception when a dangerous modification is
218
+ * made to `h` by executing `code`.
219
+ *
220
+ * `H_CHECK_MODIFIED` macro is not called if `h->hsh.ht` (`h->hsh.ea`) is `NULL`
221
+ * (`Hash` size is zero). And because the `hash_entry` is rather large,
222
+ * `h->hsh.ht->ea` and `h->hsh.ht->ea_capa` are able to be safely accessed even for
223
+ * AR. This nature is used to eliminate branch of AR or HT.
224
+ *
225
+ * `HT_ASSERT_SAFE_READ` checks if members can be accessed according to its
226
+ * assumptions.
227
+ */
228
+ # define HT_ASSERT_SAFE_READ(attr_name) \
229
+ mrb_static_assert( \
230
+ offsetof(hash_table, attr_name) + sizeof(((hash_table*)0)->attr_name) <= \
231
+ sizeof(hash_entry))
232
+ HT_ASSERT_SAFE_READ(ea);
233
+ # ifdef MRB_32BIT
234
+ HT_ASSERT_SAFE_READ(ea_capa);
235
+ # endif
236
+ # undef HT_ASSERT_SAFE_READ
237
+ #endif /* MRB_NO_BOXING */
238
+
239
+ /*
240
+ * `H_CHECK_MODIFIED` raises an exception when a dangerous modification is
241
+ * made to `h` by executing code block.
242
+ */
243
+ #define H_CHECK_MODIFIED(mrb, h) \
244
+ for (struct h_check_modified h_checker__ = h_check_modified_init(mrb, h); \
245
+ h_checker__.tbl; \
246
+ h_check_modified_validate(mrb, &h_checker__, h), h_checker__.tbl = NULL)
247
+
248
+ #define U32(v) ((uint32_t)(v))
249
+ #define h_ar_p(h) (!h_ht_p(h))
250
+ #define h_ar_on(h) h_ht_off(h)
251
+ #define lesser(a, b) ((a) < (b) ? (a) : (b))
252
+ #define RHASH_IFNONE(hash) mrb_iv_get(mrb, (hash), MRB_SYM(ifnone))
253
+ #define RHASH_PROCDEFAULT(hash) RHASH_IFNONE(hash)
254
+
255
+ static uint32_t ib_upper_bound_for(uint32_t capa);
256
+ static uint32_t ib_bit_to_capa(uint32_t bit);
257
+ static hash_entry *ib_it_entry(index_buckets_iter *it);
258
+ static void ht_init(
259
+ mrb_state *mrb, struct RHash *h, uint32_t size,
260
+ hash_entry *ea, uint32_t ea_capa, hash_table *ht, uint32_t ib_bit);
261
+ static void ht_set(mrb_state *mrb, struct RHash *h, mrb_value key, mrb_value val);
262
+
263
+ static uint32_t
264
+ next_power2(uint32_t v)
265
+ {
266
+ mrb_assert(v != 0);
267
+ #ifdef __GNUC__
268
+ return U32(1) << ((sizeof(unsigned) * CHAR_BIT) - __builtin_clz(v));
269
+ #else
270
+ v |= v >> 1;
271
+ v |= v >> 2;
272
+ v |= v >> 4;
273
+ v |= v >> 8;
274
+ v |= v >> 16;
275
+ v++;
276
+ return v;
277
+ #endif
278
+ }
279
+
280
+ struct h_check_modified {
281
+ uint32_t flags;
282
+ void *tbl;
283
+ uint32_t ht_ea_capa;
284
+ hash_entry *ht_ea;
285
+ };
286
+
287
+ #define H_CHECK_MODIFIED_FLAGS_MASK (MRB_HASH_HT | MRB_HASH_IB_BIT_MASK | MRB_HASH_AR_EA_CAPA_MASK)
288
+
289
+ static struct h_check_modified
290
+ h_check_modified_init(mrb_state *mrb, struct RHash *h)
291
+ {
292
+ mrb_assert(h->hsh.ht);
293
+
294
+ struct h_check_modified checker;
295
+ checker.flags = h->flags & H_CHECK_MODIFIED_FLAGS_MASK;
296
+ checker.tbl = h->hsh.ht;
297
+ checker.ht_ea_capa = (H_CHECK_MODIFIED_USE_HT_EA_CAPA_FOR_AR || h_ht_p(h)) ? ht_ea_capa(h) : 0;
298
+ checker.ht_ea = (H_CHECK_MODIFIED_USE_HT_EA_FOR_AR || h_ht_p(h)) ? ht_ea(h) : NULL;
299
+ return checker;
300
+ }
301
+
302
+ static void
303
+ h_check_modified_validate(mrb_state *mrb, struct h_check_modified *checker, struct RHash *h)
304
+ {
305
+ if (checker->flags != (h->flags & H_CHECK_MODIFIED_FLAGS_MASK) ||
306
+ checker->tbl != h->hsh.ht ||
307
+ ((H_CHECK_MODIFIED_USE_HT_EA_CAPA_FOR_AR || h_ht_p(h)) &&
308
+ checker->ht_ea_capa != ht_ea_capa(h)) ||
309
+ ((H_CHECK_MODIFIED_USE_HT_EA_FOR_AR || h_ht_p(h)) &&
310
+ checker->ht_ea != ht_ea(h))) {
311
+ mrb_raise(mrb, E_RUNTIME_ERROR, "hash modified");
312
+ }
313
+ }
314
+
315
+ #ifndef MRB_NO_FLOAT
316
+ static uint32_t
317
+ float_hash_code(mrb_float f)
318
+ {
319
+ if (f == 0.0) return 0;
320
+ /* normalize -0.0 to 0.0 */
321
+ if (f == -0.0) f = 0.0;
322
+ return mrb_byte_hash((const uint8_t*)&f, sizeof(f));
323
+ }
324
+ #endif
325
+
326
+ uint32_t
327
+ mrb_obj_hash_code(mrb_state *mrb, mrb_value key)
328
+ {
329
+ enum mrb_vtype tt = mrb_type(key);
330
+ uint32_t hash_code;
331
+ mrb_value hash_code_obj;
332
+ switch (tt) {
333
+ case MRB_TT_STRING:
334
+ hash_code = mrb_str_hash(mrb, key);
335
+ break;
336
+ case MRB_TT_TRUE:
337
+ case MRB_TT_FALSE:
338
+ case MRB_TT_SYMBOL:
339
+ hash_code = U32(mrb_fixnum(key));
340
+ break;
341
+ case MRB_TT_INTEGER:
342
+ if (mrb_fixnum_p(key)) {
343
+ hash_code = U32(mrb_fixnum(key));
344
+ }
345
+ else {
346
+ #ifdef MRB_USE_BIGINT
347
+ hash_code = U32(mrb_integer(mrb_bint_hash(mrb, key)));
348
+ #else
349
+ /* This path should not be reached if bignum is not configured.
350
+ * Hashing object_id is a fallback to avoid uninitialized value. */
351
+ hash_code = U32(mrb_obj_id(key));
352
+ #endif
353
+ }
354
+ break;
355
+ #ifndef MRB_NO_FLOAT
356
+ case MRB_TT_FLOAT:
357
+ hash_code = float_hash_code(mrb_float(key));
358
+ break;
359
+ #endif
360
+ default:
361
+ hash_code_obj = mrb_funcall_argv(mrb, key, MRB_SYM(hash), 0, NULL);
362
+ hash_code = U32(tt) ^ U32(mrb_integer(hash_code_obj));
363
+ break;
364
+ }
365
+ return hash_code ^ (hash_code << 2) ^ (hash_code >> 2);
366
+ }
367
+
368
+ static uint32_t
369
+ obj_hash_code(mrb_state *mrb, mrb_value key, struct RHash *h)
370
+ {
371
+ uint32_t hash_code = 0;
372
+
373
+ H_CHECK_MODIFIED(mrb, h) {
374
+ hash_code = mrb_obj_hash_code(mrb, key);
375
+ }
376
+ return hash_code;
377
+ }
378
+
379
+ static mrb_bool
380
+ obj_eql(mrb_state *mrb, mrb_value a, mrb_value b, struct RHash *h)
381
+ {
382
+ mrb_bool eql = FALSE;
383
+
384
+ switch (mrb_type(a)) {
385
+ case MRB_TT_STRING:
386
+ return mrb_str_equal(mrb, a, b);
387
+
388
+ case MRB_TT_SYMBOL:
389
+ if (!mrb_symbol_p(b)) return FALSE;
390
+ return mrb_symbol(a) == mrb_symbol(b);
391
+
392
+ case MRB_TT_INTEGER:
393
+ if (!mrb_integer_p(b)) return FALSE;
394
+ return mrb_integer(a) == mrb_integer(b);
395
+
396
+ #ifndef MRB_NO_FLOAT
397
+ case MRB_TT_FLOAT:
398
+ if (!mrb_float_p(b)) return FALSE;
399
+ return mrb_float(a) == mrb_float(b);
400
+ #endif
401
+
402
+ default:
403
+ H_CHECK_MODIFIED(mrb, h) {eql = mrb_eql(mrb, a, b);}
404
+ return eql;
405
+ }
406
+ }
407
+
408
+ static inline mrb_bool
409
+ entry_deleted_p(const hash_entry* entry)
410
+ {
411
+ return mrb_undef_p(entry->key);
412
+ }
413
+
414
+ static void
415
+ entry_delete(hash_entry* entry)
416
+ {
417
+ entry->key = mrb_undef_value();
418
+ }
419
+
420
+ static hash_entry*
421
+ entry_skip_deleted(hash_entry *e)
422
+ {
423
+ for (; entry_deleted_p(e); e++)
424
+ ;
425
+ return e;
426
+ }
427
+
428
+ static uint32_t
429
+ ea_next_capa_for(uint32_t size, uint32_t max_capa)
430
+ {
431
+ if (size < AR_DEFAULT_CAPA) {
432
+ return AR_DEFAULT_CAPA;
433
+ }
434
+ else {
435
+ /*
436
+ * For 32-bit CPU, the theoretical value of maximum EA capacity is
437
+ * `UINT32_MAX / sizeof (hash_entry)`. At this time, if
438
+ * `EA_INCREASE_RATIO` is the current value, 32-bit range will not be
439
+ * exceeded during the calculation of `capa`, so `size_t` is used.
440
+ */
441
+ size_t capa = ((size_t)size * 6) / 5 + 6;
442
+ size_t inc = capa - size;
443
+ if (EA_MAX_INCREASE < inc) capa = size + EA_MAX_INCREASE;
444
+ return capa <= max_capa ? U32(capa) : max_capa;
445
+ }
446
+ }
447
+
448
+ static hash_entry*
449
+ ea_resize(mrb_state *mrb, hash_entry *ea, uint32_t capa)
450
+ {
451
+ return (hash_entry*)mrb_realloc(mrb, ea, sizeof(hash_entry) * capa);
452
+ }
453
+
454
+ static void
455
+ ea_compress(hash_entry *ea, uint32_t n_used)
456
+ {
457
+ hash_entry *w_entry = ea;
458
+ EA_EACH_USED(ea, n_used, r_entry) {
459
+ if (entry_deleted_p(r_entry)) continue;
460
+ if (r_entry != w_entry) *w_entry = *r_entry;
461
+ w_entry++;
462
+ }
463
+ }
464
+
465
+ /*
466
+ * Increase or decrease capacity of `ea` to a standard size that can
467
+ * accommodate `*capap + 1` entries (but, not exceed `max_capa`). Set the
468
+ * changed capacity to `*capap` and return a pointer to `mrb_realloc`ed EA.
469
+ */
470
+ static hash_entry*
471
+ ea_adjust(mrb_state *mrb, hash_entry *ea, uint32_t *capap, uint32_t max_capa)
472
+ {
473
+ *capap = ea_next_capa_for(*capap, max_capa);
474
+ return ea_resize(mrb, ea, *capap);
475
+ }
476
+
477
+ static hash_entry*
478
+ ea_dup(mrb_state *mrb, const hash_entry *ea, uint32_t capa)
479
+ {
480
+ size_t byte_size = sizeof(hash_entry) * capa;
481
+ hash_entry *new_ea = (hash_entry*)mrb_malloc(mrb, byte_size);
482
+ return (hash_entry*)memcpy(new_ea, ea, byte_size);
483
+ }
484
+
485
+ static hash_entry*
486
+ ea_get_by_key(mrb_state *mrb, hash_entry *ea, uint32_t size, mrb_value key,
487
+ struct RHash *h)
488
+ {
489
+ EA_EACH(ea, size, entry) {
490
+ if (obj_eql(mrb, key, entry->key, h)) return entry;
491
+ }
492
+ return NULL;
493
+ }
494
+
495
+ static hash_entry*
496
+ ea_get(hash_entry *ea, uint32_t index)
497
+ {
498
+ return &ea[index];
499
+ }
500
+
501
+ static void
502
+ ea_set(hash_entry *ea, uint32_t index, mrb_value key, mrb_value val)
503
+ {
504
+ ea[index].key = key;
505
+ ea[index].val = val;
506
+ }
507
+
508
+ static void
509
+ ar_init(struct RHash *h, uint32_t size,
510
+ hash_entry *ea, uint32_t ea_capa, uint32_t ea_n_used)
511
+ {
512
+ h_ar_on(h);
513
+ ar_set_size(h, size);
514
+ ar_set_ea(h, ea);
515
+ ar_set_ea_capa(h, ea_capa);
516
+ ar_set_ea_n_used(h, ea_n_used);
517
+ }
518
+
519
+ static void
520
+ ar_free(mrb_state *mrb, struct RHash *h)
521
+ {
522
+ mrb_free(mrb, ar_ea(h));
523
+ }
524
+
525
+ static void
526
+ ar_adjust_ea(mrb_state *mrb, struct RHash *h, uint32_t size, uint32_t max_ea_capa)
527
+ {
528
+ uint32_t ea_capa = size;
529
+ hash_entry *ea = ea_adjust(mrb, ar_ea(h), &ea_capa, max_ea_capa);
530
+ ar_set_ea(h, ea);
531
+ ar_set_ea_capa(h, ea_capa);
532
+ }
533
+
534
+ static void
535
+ ar_compress(mrb_state *mrb, struct RHash *h)
536
+ {
537
+ uint32_t size = ar_size(h);
538
+ ea_compress(ar_ea(h), ar_ea_n_used(h));
539
+ ar_set_ea_n_used(h, size);
540
+ ar_adjust_ea(mrb, h, size, lesser(ar_ea_capa(h), AR_MAX_SIZE));
541
+ }
542
+
543
+ static mrb_bool
544
+ ar_get(mrb_state *mrb, struct RHash *h, mrb_value key, mrb_value *valp)
545
+ {
546
+ EA_EACH(ar_ea(h), ar_size(h), entry) {
547
+ if (!obj_eql(mrb, key, entry->key, h)) continue;
548
+ *valp = entry->val;
549
+ return TRUE;
550
+ }
551
+ return FALSE;
552
+ }
553
+
554
+ static void
555
+ ar_set(mrb_state *mrb, struct RHash *h, mrb_value key, mrb_value val)
556
+ {
557
+ uint32_t size = ar_size(h);
558
+ hash_entry *entry;
559
+ if ((entry = ea_get_by_key(mrb, ar_ea(h), size, key, h))) {
560
+ entry->val = val;
561
+ }
562
+ else {
563
+ uint32_t ea_capa = ar_ea_capa(h), ea_n_used = ar_ea_n_used(h);
564
+ if (ea_capa == ea_n_used) {
565
+ if (size == ea_n_used) {
566
+ if (size == AR_MAX_SIZE) {
567
+ ht_init(mrb, h, size, ar_ea(h), ea_capa, NULL, IB_INIT_BIT);
568
+ ht_set(mrb, h, key, val);
569
+ return;
570
+ }
571
+ else {
572
+ ar_adjust_ea(mrb, h, size, AR_MAX_SIZE);
573
+ }
574
+ }
575
+ else {
576
+ ar_compress(mrb, h);
577
+ ea_n_used = size;
578
+ }
579
+ }
580
+ ea_set(ar_ea(h), ea_n_used, key, val);
581
+ ar_set_size(h, ++size);
582
+ ar_set_ea_n_used(h, ++ea_n_used);
583
+ }
584
+ }
585
+
586
+ static mrb_bool
587
+ ar_delete(mrb_state *mrb, struct RHash *h, mrb_value key, mrb_value *valp)
588
+ {
589
+ hash_entry *entry = ea_get_by_key(mrb, ar_ea(h), ar_size(h), key, h);
590
+ if (!entry) return FALSE;
591
+ *valp = entry->val;
592
+ entry_delete(entry);
593
+ ar_dec_size(h);
594
+ return TRUE;
595
+ }
596
+
597
+ static void
598
+ ar_shift(mrb_state *mrb, struct RHash *h, mrb_value *keyp, mrb_value *valp)
599
+ {
600
+ uint32_t size = ar_size(h);
601
+ EA_EACH(ar_ea(h), size, entry) {
602
+ *keyp = entry->key;
603
+ *valp = entry->val;
604
+ entry_delete(entry);
605
+ ar_set_size(h, --size);
606
+ return;
607
+ }
608
+ }
609
+
610
+ static void
611
+ ar_rehash(mrb_state *mrb, struct RHash *h)
612
+ {
613
+ /* see comments in `h_rehash` */
614
+ uint32_t size = ar_size(h), w_size = 0, ea_capa = ar_ea_capa(h);
615
+ hash_entry *ea = ar_ea(h), *w_entry;
616
+ EA_EACH(ea, size, r_entry) {
617
+ if ((w_entry = ea_get_by_key(mrb, ea, w_size, r_entry->key, h))) {
618
+ w_entry->val = r_entry->val;
619
+ ar_set_size(h, --size);
620
+ entry_delete(r_entry);
621
+ }
622
+ else {
623
+ if (w_size != U32(r_entry - ea)) {
624
+ ea_set(ea, w_size, r_entry->key, r_entry->val);
625
+ entry_delete(r_entry);
626
+ }
627
+ w_size++;
628
+ }
629
+ }
630
+ mrb_assert(size == w_size);
631
+ ar_set_ea_n_used(h, size);
632
+ ar_adjust_ea(mrb, h, size, ea_capa);
633
+ }
634
+
635
+ static uint32_t
636
+ ib_it_pos_for(index_buckets_iter *it, uint32_t v)
637
+ {
638
+ return v & it->mask;
639
+ }
640
+
641
+ static uint32_t
642
+ ib_it_empty_value(const index_buckets_iter *it)
643
+ {
644
+ return it->mask;
645
+ }
646
+
647
+ static uint32_t
648
+ ib_it_deleted_value(const index_buckets_iter *it)
649
+ {
650
+ return it->mask - 1;
651
+ }
652
+
653
+ static mrb_bool
654
+ ib_it_empty_p(const index_buckets_iter *it)
655
+ {
656
+ return it->ea_index == ib_it_empty_value(it);
657
+ }
658
+
659
+ static mrb_bool
660
+ ib_it_deleted_p(const index_buckets_iter *it)
661
+ {
662
+ return it->ea_index == ib_it_deleted_value(it);
663
+ }
664
+
665
+ static mrb_bool
666
+ ib_it_active_p(const index_buckets_iter *it)
667
+ {
668
+ return it->ea_index < ib_it_deleted_value(it);
669
+ }
670
+
671
+ static index_buckets_iter
672
+ ib_it_init(mrb_state *mrb, struct RHash *h, mrb_value key)
673
+ {
674
+ index_buckets_iter it;
675
+ it.h = h;
676
+ it.bit = ib_bit(h);
677
+ it.mask = ib_bit_to_capa(it.bit) - 1;
678
+ it.initial_pos = ib_it_pos_for(&it, obj_hash_code(mrb, key, h));
679
+ it.pos = it.initial_pos;
680
+ it.step = 0;
681
+ return it;
682
+ }
683
+
684
+ static void
685
+ ib_it_next(index_buckets_iter *it)
686
+ {
687
+ /*
688
+ * [IB image]
689
+ *
690
+ * ary_index(1) --.
691
+ * \ .-- shift1(3) .-- shift2(29)
692
+ * pos(6) --. \ / /
693
+ * View | \ \ <-o-> <----------o---------->
694
+ * -------- +---------------------\----\--+-----------------------------+-----
695
+ * array | 0 `--. `-|--- o 1 | ...
696
+ * +---------+---------+-----+\--+-----+---------+---------+---+-----
697
+ * buckets | 0 | 1 | ... | o 6 | 7 | 8 | ...
698
+ * +---------+---------+-----+=========+---------+---------+---------
699
+ * bit set |1 1 1 0 0|0 0 0 1 1| ... |0 1 0 1 1|0 1 1 1 0|0 1 0 1 0| ...
700
+ * +---------+---------+-----+========*+---------+---------+---------
701
+ * <---o---> \
702
+ * \ `-- bit_pos(34)
703
+ * `-- bit(5)
704
+ */
705
+
706
+ /* Slide to handle as `capa == 32` to avoid 64-bit operations */
707
+ uint32_t slid_pos = it->pos & (IB_TYPE_BIT - 1);
708
+ uint32_t slid_bit_pos = it->bit * (slid_pos + 1) - 1;
709
+ uint32_t slid_ary_index = slid_bit_pos / IB_TYPE_BIT;
710
+ it->ary_index = slid_ary_index + it->pos / IB_TYPE_BIT * it->bit;
711
+ it->shift2 = (slid_ary_index + 1) * IB_TYPE_BIT - slid_bit_pos - 1;
712
+ it->ea_index = (ht_ib(it->h)[it->ary_index] >> it->shift2) & it->mask;
713
+ if (IB_TYPE_BIT - it->bit < it->shift2) {
714
+ it->shift1 = IB_TYPE_BIT - it->shift2;
715
+ it->ea_index |= (ht_ib(it->h)[it->ary_index - 1] << it->shift1) & it->mask;
716
+ }
717
+ else {
718
+ it->shift1 = 0;
719
+ }
720
+ it->step++;
721
+ it->pos = ib_it_pos_for(it, it->initial_pos + (it->step * it->step + it->step) / 2);
722
+ }
723
+
724
+ static mrb_bool
725
+ ib_it_find_by_key(mrb_state *mrb, index_buckets_iter *it, mrb_value key)
726
+ {
727
+ if (!it->h) return FALSE;
728
+
729
+ for (;;) {
730
+ ib_it_next(it);
731
+ if (ib_it_empty_p(it)) return FALSE;
732
+ if (!ib_it_deleted_p(it) &&
733
+ obj_eql(mrb, key, ib_it_entry(it)->key, it->h)) {
734
+ return TRUE;
735
+ }
736
+ }
737
+ }
738
+
739
+ static uint32_t
740
+ ib_it_get(const index_buckets_iter *it)
741
+ {
742
+ return it->ea_index;
743
+ }
744
+
745
+ static void
746
+ ib_it_set(index_buckets_iter *it, uint32_t ea_index)
747
+ {
748
+ uint32_t mask, i;
749
+ it->ea_index = ea_index;
750
+ if (it->shift1) {
751
+ i = it->ary_index - 1;
752
+ mask = it->mask >> it->shift1;
753
+ ht_ib(it->h)[i] = (ht_ib(it->h)[i] & ~mask) | (ea_index >> it->shift1);
754
+ }
755
+ i = it->ary_index;
756
+ mask = it->mask << it->shift2;
757
+ ht_ib(it->h)[i] = (ht_ib(it->h)[i] & ~mask) | (ea_index << it->shift2);
758
+ }
759
+
760
+ static void
761
+ ib_it_delete(index_buckets_iter *it)
762
+ {
763
+ ib_it_set(it, ib_it_deleted_value(it));
764
+ }
765
+
766
+ static hash_entry*
767
+ ib_it_entry(index_buckets_iter *it)
768
+ {
769
+ return ea_get(ht_ea(it->h), it->ea_index);
770
+ }
771
+
772
+ static uint32_t
773
+ ib_capa_to_bit(uint32_t capa)
774
+ {
775
+ #ifdef __GNUC__
776
+ return U32(__builtin_ctz(capa));
777
+ #else
778
+ /* http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn */
779
+ static const uint32_t MultiplyDeBruijnBitPosition2[] = {
780
+ 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
781
+ 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
782
+ };
783
+ return MultiplyDeBruijnBitPosition2[U32(capa * 0x077CB531U) >> 27];
784
+ #endif
785
+ }
786
+
787
+ static uint32_t
788
+ ib_bit_to_capa(uint32_t bit)
789
+ {
790
+ return U32(1) << bit;
791
+ }
792
+
793
+ static uint32_t
794
+ ib_upper_bound_for(uint32_t capa)
795
+ {
796
+ return (capa >> 2) | (capa >> 1); /* 3/4 */
797
+ }
798
+
799
+ static uint32_t
800
+ ib_bit_for(uint32_t size)
801
+ {
802
+ uint32_t capa = next_power2(size);
803
+ if (capa != IB_MAX_CAPA && ib_upper_bound_for(capa) < size) capa *= 2;
804
+ return ib_capa_to_bit(capa);
805
+ }
806
+
807
+ static uint32_t
808
+ ib_byte_size_for(uint32_t ib_bit)
809
+ {
810
+ mrb_assert(IB_INIT_BIT <= ib_bit);
811
+ uint32_t ary_size = IB_INIT_BIT == 4 ?
812
+ ib_bit_to_capa(ib_bit) * 2 / IB_TYPE_BIT * ib_bit / 2 :
813
+ ib_bit_to_capa(ib_bit) / IB_TYPE_BIT * ib_bit;
814
+ return U32(sizeof(uint32_t) * ary_size);
815
+ }
816
+
817
+ static void
818
+ ib_init(mrb_state *mrb, struct RHash *h, uint32_t ib_bit, size_t ib_byte_size)
819
+ {
820
+ hash_entry *ea = ht_ea(h);
821
+ memset(ht_ib(h), 0xff, ib_byte_size);
822
+ ib_set_bit(h, ib_bit);
823
+ EA_EACH_USED(ea, ht_ea_n_used(h), entry) {
824
+ IB_CYCLE_BY_KEY(mrb, h, entry->key, it) {
825
+ if (!ib_it_empty_p(it)) continue;
826
+ ib_it_set(it, U32(entry - ea));
827
+ break;
828
+ }
829
+ }
830
+ }
831
+
832
+ static void
833
+ ht_init(mrb_state *mrb, struct RHash *h, uint32_t size,
834
+ hash_entry *ea, uint32_t ea_capa, hash_table *ht, uint32_t ib_bit)
835
+ {
836
+ size_t ib_byte_size = ib_byte_size_for(ib_bit);
837
+ size_t ht_byte_size = sizeof(hash_table) + ib_byte_size;
838
+ ht = (hash_table*)mrb_realloc(mrb, ht, ht_byte_size);
839
+ h_ht_on(h);
840
+ h_set_ht(h, ht);
841
+ ht_set_size(h, size);
842
+ ht_set_ea(h, ea);
843
+ ht_set_ea_capa(h, ea_capa);
844
+ ht_set_ea_n_used(h, size);
845
+ ib_init(mrb, h, ib_bit, ib_byte_size);
846
+ }
847
+
848
+ static void
849
+ ht_free(mrb_state *mrb, struct RHash *h)
850
+ {
851
+ mrb_free(mrb, ht_ea(h));
852
+ mrb_free(mrb, h_ht(h));
853
+ }
854
+
855
+ static hash_table*
856
+ ht_dup(mrb_state *mrb, const struct RHash *h)
857
+ {
858
+ size_t ib_byte_size = ib_byte_size_for(ib_bit(h));
859
+ size_t ht_byte_size = sizeof(hash_table) + ib_byte_size;
860
+ hash_table *new_ht = (hash_table*)mrb_malloc(mrb, ht_byte_size);
861
+ return (hash_table*)memcpy(new_ht, h_ht(h), ht_byte_size);
862
+ }
863
+
864
+ static void
865
+ ht_adjust_ea(mrb_state *mrb, struct RHash *h, uint32_t size, uint32_t max_ea_capa)
866
+ {
867
+ uint32_t ea_capa = size;
868
+ hash_entry *ea = ea_adjust(mrb, ht_ea(h), &ea_capa, max_ea_capa);
869
+ ht_set_ea(h, ea);
870
+ ht_set_ea_capa(h, ea_capa);
871
+ }
872
+
873
+ static void
874
+ ht_to_ar(mrb_state *mrb, struct RHash *h)
875
+ {
876
+ uint32_t size = ht_size(h), ea_capa = size;
877
+ hash_entry *ea = ht_ea(h);
878
+ ea_compress(ea, ht_ea_n_used(h));
879
+ ea = ea_adjust(mrb, ea, &ea_capa, AR_MAX_SIZE);
880
+ mrb_free(mrb, h_ht(h));
881
+ ar_init(h, size, ea, ea_capa, size);
882
+ }
883
+
884
+ static mrb_bool
885
+ ht_get(mrb_state *mrb, struct RHash *h, mrb_value key, mrb_value *valp)
886
+ {
887
+ IB_FIND_BY_KEY(mrb, h, key, it) {
888
+ *valp = ib_it_entry(it)->val;
889
+ return TRUE;
890
+ }
891
+ return FALSE;
892
+ }
893
+
894
+ static void
895
+ ht_set_as_ar(mrb_state *mrb, struct RHash *h, mrb_value key, mrb_value val)
896
+ {
897
+ ht_to_ar(mrb, h);
898
+ ar_set(mrb, h, key, val);
899
+ }
900
+
901
+ static void
902
+ ht_set(mrb_state *mrb, struct RHash *h, mrb_value key, mrb_value val)
903
+ {
904
+ uint32_t size = ht_size(h);
905
+ uint32_t ib_bit_width = ib_bit(h), ib_capa = ib_bit_to_capa(ib_bit_width);
906
+ if (ib_upper_bound_for(ib_capa) <= size) {
907
+ if (size != ht_ea_n_used(h)) ea_compress(ht_ea(h), ht_ea_n_used(h));
908
+ ht_init(mrb, h, size, ht_ea(h), ht_ea_capa(h), h_ht(h), ++ib_bit_width);
909
+ }
910
+ else if (size != ht_ea_n_used(h)) {
911
+ if (ib_capa - EA_N_RESERVED_INDICES <= ht_ea_n_used(h)) goto compress;
912
+ if (ht_ea_capa(h) == ht_ea_n_used(h)) {
913
+ if (size <= AR_MAX_SIZE) {
914
+ ht_set_as_ar(mrb, h, key, val);
915
+ return;
916
+ }
917
+ if (ea_next_capa_for(size, EA_MAX_CAPA) <= ht_ea_capa(h)) {
918
+ compress:
919
+ ea_compress(ht_ea(h), ht_ea_n_used(h));
920
+ ht_adjust_ea(mrb, h, size, ht_ea_capa(h));
921
+ ht_init(mrb, h, size, ht_ea(h), ht_ea_capa(h), h_ht(h), ib_bit_width);
922
+ }
923
+ }
924
+ }
925
+
926
+ mrb_assert(ht_size(h) < ib_bit_to_capa(ib_bit(h)));
927
+ IB_CYCLE_BY_KEY(mrb, h, key, it) {
928
+ if (ib_it_active_p(it)) {
929
+ if (!obj_eql(mrb, key, ib_it_entry(it)->key, h)) continue;
930
+ ib_it_entry(it)->val = val;
931
+ }
932
+ else if (ib_it_deleted_p(it)) {
933
+ continue;
934
+ }
935
+ else {
936
+ uint32_t ea_n_used = ht_ea_n_used(h);
937
+ if (ea_n_used == H_MAX_SIZE) {
938
+ mrb_assert(ht_size(h) == ea_n_used);
939
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "hash too big");
940
+ }
941
+ if (ea_n_used == ht_ea_capa(h)) ht_adjust_ea(mrb, h, ea_n_used, EA_MAX_CAPA);
942
+ ib_it_set(it, ea_n_used);
943
+ ea_set(ht_ea(h), ea_n_used, key, val);
944
+ ht_inc_size(h);
945
+ ht_set_ea_n_used(h, ++ea_n_used);
946
+ }
947
+ return;
948
+ }
949
+ }
950
+
951
+ static mrb_bool
952
+ ht_delete(mrb_state *mrb, struct RHash *h, mrb_value key, mrb_value *valp)
953
+ {
954
+ IB_FIND_BY_KEY(mrb, h, key, it) {
955
+ hash_entry *entry = ib_it_entry(it);
956
+ *valp = entry->val;
957
+ ib_it_delete(it);
958
+ entry_delete(entry);
959
+ ht_dec_size(h);
960
+ return TRUE;
961
+ }
962
+ return FALSE;
963
+ }
964
+
965
+ static void
966
+ ht_shift(mrb_state *mrb, struct RHash *h, mrb_value *keyp, mrb_value *valp)
967
+ {
968
+ hash_entry *ea = ht_ea(h);
969
+ EA_EACH(ea, ht_size(h), entry) {
970
+ IB_CYCLE_BY_KEY(mrb, h, entry->key, it) {
971
+ if (ib_it_get(it) != U32(entry - ea)) continue;
972
+ *keyp = entry->key;
973
+ *valp = entry->val;
974
+ ib_it_delete(it);
975
+ entry_delete(entry);
976
+ ht_dec_size(h);
977
+ return;
978
+ }
979
+ }
980
+ }
981
+
982
+ static void
983
+ ht_rehash(mrb_state *mrb, struct RHash *h)
984
+ {
985
+ /* see comments in `h_rehash` */
986
+ uint32_t size = ht_size(h);
987
+ if (size <= AR_MAX_SIZE) {
988
+ ht_to_ar(mrb, h);
989
+ ar_rehash(mrb, h);
990
+ return;
991
+ }
992
+ uint32_t w_size = 0, ea_capa = ht_ea_capa(h);
993
+ hash_entry *ea = ht_ea(h);
994
+ ht_init(mrb, h, 0, ea, ea_capa, h_ht(h), ib_bit_for(size));
995
+ ht_set_size(h, size);
996
+ ht_set_ea_n_used(h, ht_ea_n_used(h));
997
+ EA_EACH(ea, size, r_entry) {
998
+ IB_CYCLE_BY_KEY(mrb, h, r_entry->key, it) {
999
+ if (ib_it_active_p(it)) {
1000
+ if (!obj_eql(mrb, r_entry->key, ib_it_entry(it)->key, h)) continue;
1001
+ ib_it_entry(it)->val = r_entry->val;
1002
+ ht_set_size(h, --size);
1003
+ entry_delete(r_entry);
1004
+ }
1005
+ else {
1006
+ if (w_size != U32(r_entry - ea)) {
1007
+ ea_set(ea, w_size, r_entry->key, r_entry->val);
1008
+ entry_delete(r_entry);
1009
+ }
1010
+ ib_it_set(it, w_size++);
1011
+ }
1012
+ break;
1013
+ }
1014
+ }
1015
+ mrb_assert(size == w_size);
1016
+ ht_set_ea_n_used(h, size);
1017
+ size <= AR_MAX_SIZE ? ht_to_ar(mrb, h) : ht_adjust_ea(mrb, h, size, ea_capa);
1018
+ }
1019
+
1020
+ static mrb_value
1021
+ h_key_for(mrb_state *mrb, mrb_value key)
1022
+ {
1023
+ if (mrb_string_p(key) && !mrb_frozen_p(mrb_str_ptr(key))) {
1024
+ key = mrb_str_dup(mrb, key);
1025
+ mrb_str_ptr(key)->frozen = 1;
1026
+ }
1027
+ return key;
1028
+ }
1029
+
1030
+ static struct RHash*
1031
+ h_alloc(mrb_state *mrb)
1032
+ {
1033
+ return MRB_OBJ_ALLOC(mrb, MRB_TT_HASH, mrb->hash_class);
1034
+ }
1035
+
1036
+ static void
1037
+ h_init(struct RHash *h)
1038
+ {
1039
+ ar_init(h, 0, NULL, 0, 0);
1040
+ }
1041
+
1042
+ static void
1043
+ h_free_table(mrb_state *mrb, struct RHash *h)
1044
+ {
1045
+ (h_ar_p(h) ? ar_free : ht_free)(mrb, h);
1046
+ }
1047
+
1048
+ static void
1049
+ h_clear(mrb_state *mrb, struct RHash *h)
1050
+ {
1051
+ h_free_table(mrb, h);
1052
+ h_init(h);
1053
+ }
1054
+
1055
+ static mrb_bool
1056
+ h_get(mrb_state *mrb, struct RHash *h, mrb_value key, mrb_value *valp)
1057
+ {
1058
+ return (h_ar_p(h) ? ar_get : ht_get)(mrb, h, key, valp);
1059
+ }
1060
+
1061
+ static void
1062
+ h_set(mrb_state *mrb, struct RHash *h, mrb_value key, mrb_value val)
1063
+ {
1064
+ (h_ar_p(h) ? ar_set : ht_set)(mrb, h, key, val);
1065
+ }
1066
+
1067
+ static mrb_bool
1068
+ h_delete(mrb_state *mrb, struct RHash *h, mrb_value key, mrb_value *valp)
1069
+ {
1070
+ return (h_ar_p(h) ? ar_delete : ht_delete)(mrb, h, key, valp);
1071
+ }
1072
+
1073
+ /* find first element in the table, and remove it. */
1074
+ static void
1075
+ h_shift(mrb_state *mrb, struct RHash *h, mrb_value *keyp, mrb_value *valp)
1076
+ {
1077
+ (h_ar_p(h) ? ar_shift : ht_shift)(mrb, h, keyp, valp);
1078
+ }
1079
+
1080
+ static void
1081
+ h_rehash(mrb_state *mrb, struct RHash *h)
1082
+ {
1083
+ /*
1084
+ * ==== Comments common to `ar_rehash` and `ht_rehash`
1085
+ *
1086
+ * - Because reindex (such as elimination of duplicate keys) must be
1087
+ * guaranteed, it is necessary to set one by one.
1088
+ *
1089
+ * - To prevent EA from breaking if an exception occurs in the middle,
1090
+ * delete the slot before moving when moving the entry, and update size
1091
+ * at any time when overwriting.
1092
+ */
1093
+ (h_size(h) == 0 ? h_clear : h_ar_p(h) ? ar_rehash : ht_rehash)(mrb, h);
1094
+ }
1095
+
1096
+ static void
1097
+ h_replace(mrb_state *mrb, struct RHash *h, struct RHash *orig_h)
1098
+ {
1099
+ uint32_t size = h_size(orig_h);
1100
+ if (size == 0) {
1101
+ h_clear(mrb, h);
1102
+ }
1103
+ else if (h_ar_p(orig_h)) {
1104
+ uint32_t ea_capa = ar_ea_capa(orig_h);
1105
+ hash_entry *ea = ea_dup(mrb, ar_ea(orig_h), ea_capa);
1106
+ h_free_table(mrb, h);
1107
+ ar_init(h, size, ea, ea_capa, ar_ea_n_used(orig_h));
1108
+ }
1109
+ else { /* HT */
1110
+ uint32_t ea_capa = ht_ea_capa(orig_h);
1111
+ hash_entry *ea = ea_dup(mrb, ht_ea(orig_h), ea_capa);
1112
+ hash_table *ht = ht_dup(mrb, orig_h);
1113
+ h_free_table(mrb, h);
1114
+ h_ht_on(h);
1115
+ h_set_ht(h, ht);
1116
+ ht_set_size(h, size);
1117
+ ht_set_ea(h, ea);
1118
+ #ifdef MRB_64BIT
1119
+ ht_set_ea_capa(h, ea_capa);
1120
+ ht_set_ea_n_used(h, ht_ea_n_used(orig_h));
1121
+ #endif
1122
+ ib_set_bit(h, ib_bit(orig_h));
1123
+ }
1124
+ }
1125
+
1126
+ size_t
1127
+ mrb_gc_mark_hash(mrb_state *mrb, struct RHash *h)
1128
+ {
1129
+ H_EACH(h, entry) {
1130
+ mrb_gc_mark_value(mrb, entry->key);
1131
+ mrb_gc_mark_value(mrb, entry->val);
1132
+ }
1133
+ return h_size(h) * 2;
1134
+ }
1135
+
1136
+ void
1137
+ mrb_gc_free_hash(mrb_state *mrb, struct RHash *h)
1138
+ {
1139
+ h_free_table(mrb, h);
1140
+ }
1141
+
1142
+ size_t
1143
+ mrb_hash_memsize(mrb_value self)
1144
+ {
1145
+ struct RHash *h = mrb_hash_ptr(self);
1146
+ return mrb_obj_iv_tbl_memsize(self) +
1147
+ (h_ar_p(h) ? (ar_ea_capa(h) * sizeof(hash_entry)) :
1148
+ (ht_ea_capa(h) * sizeof(hash_entry) +
1149
+ sizeof(hash_table) +
1150
+ ib_byte_size_for(ib_bit(h))));
1151
+ }
1152
+
1153
+ /**
1154
+ * Iterates over each key-value pair in the given hash.
1155
+ *
1156
+ * This function calls the provided callback function `func` for each entry
1157
+ * in the hash `h`. The iteration order is the insertion order.
1158
+ *
1159
+ * The callback function `func` has the signature:
1160
+ * `int callback(mrb_state *mrb, mrb_value key, mrb_value value, void *data)`
1161
+ * - `mrb`: The mruby state.
1162
+ * - `key`: The key of the current hash entry.
1163
+ * - `value`: The value of the current hash entry.
1164
+ * - `data`: The user-supplied data pointer passed to `mrb_hash_foreach`.
1165
+ *
1166
+ * If the callback function returns a non-zero value, the iteration stops.
1167
+ *
1168
+ * Important: Modifying the hash `h` within the callback function can lead
1169
+ * to undefined behavior if not handled carefully (e.g., using `H_CHECK_MODIFIED`
1170
+ * as done internally for Ruby methods, though direct C API users must be cautious).
1171
+ * The `H_CHECK_MODIFIED` macro within this function is for internal safety
1172
+ * when this function is used to implement Ruby methods that might call
1173
+ * arbitrary Ruby code during iteration.
1174
+ *
1175
+ * @param mrb The mruby state.
1176
+ * @param h A pointer to the RHash structure to iterate over.
1177
+ * @param func The callback function to be called for each key-value pair.
1178
+ * @param data A void pointer that will be passed to the callback function.
1179
+ */
1180
+ MRB_API void
1181
+ mrb_hash_foreach(mrb_state *mrb, struct RHash *h, mrb_hash_foreach_func *func, void *data)
1182
+ {
1183
+ H_EACH(h, entry) {
1184
+ int n;
1185
+ H_CHECK_MODIFIED(mrb, h) {
1186
+ n = func(mrb, entry->key, entry->val, data);
1187
+ }
1188
+ if (n != 0) return;
1189
+ }
1190
+ }
1191
+
1192
+ mrb_value
1193
+ mrb_hash_first_key(mrb_state *mrb, mrb_value h)
1194
+ {
1195
+ H_EACH(mrb_hash_ptr(h), entry) {
1196
+ return entry->key;
1197
+ }
1198
+ return mrb_nil_value();
1199
+ }
1200
+
1201
+ /**
1202
+ * Creates a new, empty hash.
1203
+ *
1204
+ * This function allocates and initializes a new hash object.
1205
+ * The returned hash is empty and ready to have elements added to it.
1206
+ *
1207
+ * @param mrb The mruby state.
1208
+ * @return An mrb_value representing the new empty hash.
1209
+ */
1210
+ MRB_API mrb_value
1211
+ mrb_hash_new(mrb_state *mrb)
1212
+ {
1213
+ struct RHash *h = h_alloc(mrb);
1214
+ return mrb_obj_value(h);
1215
+ }
1216
+
1217
+ /**
1218
+ * Creates a new, empty hash with a specified initial capacity.
1219
+ *
1220
+ * This function allocates and initializes a new hash object, pre-allocating
1221
+ * internal structures to hold at least `capa` elements. This can be an
1222
+ * optimization if the number of elements to be stored is known in advance,
1223
+ * as it can prevent reallocations.
1224
+ *
1225
+ * If `capa` is 0, it behaves like `mrb_hash_new()`.
1226
+ * An error will be raised if `capa` is negative or excessively large.
1227
+ *
1228
+ * @param mrb The mruby state.
1229
+ * @param capa The initial capacity (number of elements) the hash should be
1230
+ * able to hold without needing to resize.
1231
+ * @return An mrb_value representing the new empty hash with preallocated capacity.
1232
+ */
1233
+ MRB_API mrb_value
1234
+ mrb_hash_new_capa(mrb_state *mrb, mrb_int capa)
1235
+ {
1236
+ if (capa < 0 || EA_MAX_CAPA < capa) {
1237
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "hash too big");
1238
+ return mrb_nil_value(); /* not reached */
1239
+ }
1240
+ else if (capa == 0) {
1241
+ return mrb_hash_new(mrb);
1242
+ }
1243
+ else {
1244
+ uint32_t size = U32(capa);
1245
+ struct RHash *h = h_alloc(mrb);
1246
+ hash_entry *ea = ea_resize(mrb, NULL, size);
1247
+ if (size <= AR_MAX_SIZE) {
1248
+ ar_init(h, 0, ea, size, 0);
1249
+ }
1250
+ else {
1251
+ ht_init(mrb, h, 0, ea, size, NULL, ib_bit_for(size));
1252
+ }
1253
+ return mrb_obj_value(h);
1254
+ }
1255
+ }
1256
+
1257
+ static mrb_value mrb_hash_default(mrb_state *mrb, mrb_value hash);
1258
+
1259
+ static void
1260
+ hash_modify(mrb_state *mrb, mrb_value hash)
1261
+ {
1262
+ mrb_check_frozen(mrb, mrb_hash_ptr(hash));
1263
+ }
1264
+
1265
+ static mrb_value
1266
+ hash_default(mrb_state *mrb, mrb_value hash, mrb_value key)
1267
+ {
1268
+ if (MRB_RHASH_DEFAULT_P(hash)) {
1269
+ if (MRB_RHASH_PROCDEFAULT_P(hash)) {
1270
+ return mrb_funcall_id(mrb, RHASH_PROCDEFAULT(hash), MRB_SYM(call), 2, hash, key);
1271
+ }
1272
+ else {
1273
+ return RHASH_IFNONE(hash);
1274
+ }
1275
+ }
1276
+ return mrb_nil_value();
1277
+ }
1278
+
1279
+ static void
1280
+ hash_replace(mrb_state *mrb, mrb_value self, mrb_value orig)
1281
+ {
1282
+ struct RHash *h = mrb_hash_ptr(self), *orig_h = mrb_hash_ptr(orig);
1283
+ uint32_t mask = MRB_HASH_DEFAULT | MRB_HASH_PROC_DEFAULT;
1284
+ mrb_sym name;
1285
+ h_replace(mrb, h, orig_h);
1286
+ name = MRB_SYM(ifnone);
1287
+ if (orig_h->flags & MRB_HASH_DEFAULT) {
1288
+ mrb_iv_set(mrb, self, name, mrb_iv_get(mrb, orig, name));
1289
+ }
1290
+ else {
1291
+ mrb_iv_remove(mrb, self, name);
1292
+ }
1293
+ h->flags &= ~mask;
1294
+ h->flags |= orig_h->flags & mask;
1295
+ }
1296
+
1297
+ static mrb_value
1298
+ mrb_hash_init_copy(mrb_state *mrb, mrb_value self)
1299
+ {
1300
+ mrb_value orig;
1301
+ mrb_get_args(mrb, "H", &orig);
1302
+ hash_modify(mrb, self);
1303
+ if (mrb_hash_ptr(self) != mrb_hash_ptr(orig)) hash_replace(mrb, self, orig);
1304
+ return self;
1305
+ }
1306
+
1307
+ /**
1308
+ * Creates a new hash that is a duplicate of the given hash.
1309
+ *
1310
+ * This function creates a shallow copy of the original hash `self`.
1311
+ * The keys and values themselves are not duplicated, but the internal
1312
+ * structure of the hash (entry array, hash table, default values/procs)
1313
+ * is copied.
1314
+ *
1315
+ * @param mrb The mruby state.
1316
+ * @param self The hash object (mrb_value) to duplicate.
1317
+ * @return An mrb_value representing the new duplicated hash.
1318
+ */
1319
+ MRB_API mrb_value
1320
+ mrb_hash_dup(mrb_state *mrb, mrb_value self)
1321
+ {
1322
+ struct RHash* copy_h = h_alloc(mrb);
1323
+ mrb_value copy = mrb_obj_value(copy_h);
1324
+ copy_h->c = mrb_hash_ptr(self)->c;
1325
+ hash_replace(mrb, copy, self);
1326
+ return copy;
1327
+ }
1328
+
1329
+ /**
1330
+ * Retrieves the value associated with a given key from the hash.
1331
+ *
1332
+ * If the key is found in the hash, its corresponding value is returned.
1333
+ * If the key is not found, this function considers the hash's default settings:
1334
+ * - If a default proc is set for the hash, it is called with the hash and key,
1335
+ * and its result is returned.
1336
+ * - If a default value is set, that value is returned.
1337
+ * - Otherwise (no key found and no default settings), nil is returned.
1338
+ * This function may also invoke a user-defined `default` method on the hash
1339
+ * if it has been overridden and no basic default proc/value handles the lookup.
1340
+ *
1341
+ * @param mrb The mruby state.
1342
+ * @param hash The hash object (mrb_value) to search.
1343
+ * @param key The key (mrb_value) to look up.
1344
+ * @return The associated mrb_value, or the result of the default proc,
1345
+ * or the default value, or nil if not found and no defaults apply.
1346
+ */
1347
+ MRB_API mrb_value
1348
+ mrb_hash_get(mrb_state *mrb, mrb_value hash, mrb_value key)
1349
+ {
1350
+ mrb_value val;
1351
+ mrb_sym mid;
1352
+
1353
+ if (h_get(mrb, mrb_hash_ptr(hash), key, &val)) {
1354
+ return val;
1355
+ }
1356
+
1357
+ mid = MRB_SYM(default);
1358
+ if (mrb_func_basic_p(mrb, hash, mid, mrb_hash_default)) {
1359
+ return hash_default(mrb, hash, key);
1360
+ }
1361
+ /* xxx mrb_funcall_tailcall(mrb, hash, "default", 1, key); */
1362
+ return mrb_funcall_argv(mrb, hash, mid, 1, &key);
1363
+ }
1364
+
1365
+ /**
1366
+ * Retrieves the value associated with a given key from the hash,
1367
+ * returning a C-provided default value if the key is not found.
1368
+ *
1369
+ * If the `key` is found in the `hash`, its corresponding value is returned.
1370
+ * If the `key` is not found, the `def` mrb_value provided to this function
1371
+ * is returned. This function does *not* use the hash's own default proc
1372
+ * or default value.
1373
+ *
1374
+ * @param mrb The mruby state.
1375
+ * @param hash The hash object (mrb_value) to search.
1376
+ * @param key The key (mrb_value) to look up.
1377
+ * @param def The default mrb_value to return if the key is not found.
1378
+ * @return The associated mrb_value if the key is found, otherwise `def`.
1379
+ */
1380
+ MRB_API mrb_value
1381
+ mrb_hash_fetch(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value def)
1382
+ {
1383
+ mrb_value val;
1384
+
1385
+ if (h_get(mrb, mrb_hash_ptr(hash), key, &val)) {
1386
+ return val;
1387
+ }
1388
+ /* not found */
1389
+ return def;
1390
+ }
1391
+
1392
+ /**
1393
+ * Sets or updates a key-value pair in the hash.
1394
+ *
1395
+ * Associates `val` with `key` in the `hash`. If `key` already exists,
1396
+ * its value is updated. If `key` does not exist, a new entry is created.
1397
+ * The hash is modified in place.
1398
+ *
1399
+ * If the `key` is a `MRB_TT_STRING` and not frozen, it will be duplicated
1400
+ * and the duplicate will be frozen before use.
1401
+ * Write barriers are triggered for garbage collection purposes for the key and value.
1402
+ *
1403
+ * @param mrb The mruby state.
1404
+ * @param hash The hash object (mrb_value) to modify.
1405
+ * @param key The key (mrb_value) for the entry.
1406
+ * @param val The value (mrb_value) to associate with the key.
1407
+ */
1408
+ MRB_API void
1409
+ mrb_hash_set(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value val)
1410
+ {
1411
+ hash_modify(mrb, hash);
1412
+ key = h_key_for(mrb, key);
1413
+ h_set(mrb, mrb_hash_ptr(hash), key, val);
1414
+ mrb_field_write_barrier_value(mrb, mrb_basic_ptr(hash), key);
1415
+ mrb_field_write_barrier_value(mrb, mrb_basic_ptr(hash), val);
1416
+ }
1417
+
1418
+ static void
1419
+ hash_set_default_proc(mrb_state *mrb, mrb_value hash, mrb_value proc)
1420
+ {
1421
+ struct RProc *p = mrb_proc_ptr(proc);
1422
+ if (MRB_PROC_STRICT_P(p)) {
1423
+ mrb_int n = mrb_proc_arity(p);
1424
+ if (n != 2 && (n >= 0 || n < -3)) {
1425
+ if (n < 0) n = -n-1;
1426
+ mrb_raisef(mrb, E_TYPE_ERROR, "default_proc takes two arguments (2 for %d)", n);
1427
+ }
1428
+ }
1429
+ mrb_iv_set(mrb, hash, MRB_SYM(ifnone), proc);
1430
+ RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT;
1431
+ RHASH(hash)->flags |= MRB_HASH_DEFAULT;
1432
+ }
1433
+
1434
+ /* 15.2.13.4.16 */
1435
+ /*
1436
+ * call-seq:
1437
+ * Hash.new -> new_hash
1438
+ * Hash.new(obj) -> new_hash
1439
+ * Hash.new {|hash, key| block } -> new_hash
1440
+ *
1441
+ * Returns a new, empty hash. If this hash is subsequently accessed by
1442
+ * a key that doesn't correspond to a hash entry, the value returned
1443
+ * depends on the style of `new` used to create the hash. In
1444
+ * the first form, the access returns `nil`. If
1445
+ * `obj` is specified, this single object will be used for
1446
+ * all default values. If a block is specified, it will be
1447
+ * called with the hash object and the key, and should return the
1448
+ * default value. It is the block's responsibility to store the value
1449
+ * in the hash if required.
1450
+ *
1451
+ * h = Hash.new("Go Fish")
1452
+ * h["a"] = 100
1453
+ * h["b"] = 200
1454
+ * h["a"] #=> 100
1455
+ * h["c"] #=> "Go Fish"
1456
+ * # The following alters the single default object
1457
+ * h["c"].upcase! #=> "GO FISH"
1458
+ * h["d"] #=> "GO FISH"
1459
+ * h.keys #=> ["a", "b"]
1460
+ *
1461
+ * # While this creates a new default object each time
1462
+ * h = Hash.new { |hash, key| hash[key] = "Go Fish: #{key}" }
1463
+ * h["c"] #=> "Go Fish: c"
1464
+ * h["c"].upcase! #=> "GO FISH: C"
1465
+ * h["d"] #=> "Go Fish: d"
1466
+ * h.keys #=> ["c", "d"]
1467
+ *
1468
+ */
1469
+
1470
+ static mrb_value
1471
+ mrb_hash_init(mrb_state *mrb, mrb_value hash)
1472
+ {
1473
+ mrb_value block, ifnone;
1474
+ mrb_bool ifnone_p;
1475
+
1476
+ ifnone = mrb_nil_value();
1477
+ mrb_get_args(mrb, "&|o?", &block, &ifnone, &ifnone_p);
1478
+ hash_modify(mrb, hash);
1479
+ if (!mrb_nil_p(block)) {
1480
+ if (ifnone_p) {
1481
+ mrb_argnum_error(mrb, 1, 0, 0);
1482
+ }
1483
+ hash_set_default_proc(mrb, hash, block);
1484
+ return hash;
1485
+ }
1486
+ if (ifnone_p && !mrb_nil_p(ifnone)) {
1487
+ RHASH(hash)->flags |= MRB_HASH_DEFAULT;
1488
+ mrb_iv_set(mrb, hash, MRB_SYM(ifnone), ifnone);
1489
+ }
1490
+ return hash;
1491
+ }
1492
+
1493
+ /* 15.2.13.4.2 */
1494
+ /*
1495
+ * call-seq:
1496
+ * hsh[key] -> value
1497
+ *
1498
+ * Element Reference---Retrieves the `value` object corresponding
1499
+ * to the `key` object. If not found, returns the default value (see
1500
+ * `Hash::new` for details).
1501
+ *
1502
+ * h = { "a" => 100, "b" => 200 }
1503
+ * h["a"] #=> 100
1504
+ * h["c"] #=> nil
1505
+ *
1506
+ */
1507
+ static mrb_value
1508
+ mrb_hash_aget(mrb_state *mrb, mrb_value self)
1509
+ {
1510
+ mrb_value key = mrb_get_arg1(mrb);
1511
+
1512
+ return mrb_hash_get(mrb, self, key);
1513
+ }
1514
+
1515
+ /* 15.2.13.4.5 */
1516
+ /*
1517
+ * call-seq:
1518
+ * hsh.default(key=nil) -> obj
1519
+ *
1520
+ * Returns the default value, the value that would be returned by
1521
+ * `hsh`[`key`] if `key` did not exist in `hsh`.
1522
+ * See also `Hash::new` and `Hash#default=`.
1523
+ *
1524
+ * h = Hash.new #=> {}
1525
+ * h.default #=> nil
1526
+ * h.default(2) #=> nil
1527
+ *
1528
+ * h = Hash.new("cat") #=> {}
1529
+ * h.default #=> "cat"
1530
+ * h.default(2) #=> "cat"
1531
+ *
1532
+ * h = Hash.new {|h,k| h[k] = k.to_i*10} #=> {}
1533
+ * h.default #=> nil
1534
+ * h.default(2) #=> 20
1535
+ */
1536
+
1537
+ static mrb_value
1538
+ mrb_hash_default(mrb_state *mrb, mrb_value hash)
1539
+ {
1540
+ mrb_value key;
1541
+ mrb_bool given;
1542
+
1543
+ mrb_get_args(mrb, "|o?", &key, &given);
1544
+ if (MRB_RHASH_DEFAULT_P(hash)) {
1545
+ if (MRB_RHASH_PROCDEFAULT_P(hash)) {
1546
+ if (!given) return mrb_nil_value();
1547
+ return mrb_funcall_id(mrb, RHASH_PROCDEFAULT(hash), MRB_SYM(call), 2, hash, key);
1548
+ }
1549
+ else {
1550
+ return RHASH_IFNONE(hash);
1551
+ }
1552
+ }
1553
+ return mrb_nil_value();
1554
+ }
1555
+
1556
+ /* 15.2.13.4.6 */
1557
+ /*
1558
+ * call-seq:
1559
+ * hsh.default = obj -> obj
1560
+ *
1561
+ * Sets the default value, the value returned for a key that does not
1562
+ * exist in the hash. It is not possible to set the default to a
1563
+ * `Proc` that will be executed on each key lookup.
1564
+ *
1565
+ * h = { "a" => 100, "b" => 200 }
1566
+ * h.default = "Go fish"
1567
+ * h["a"] #=> 100
1568
+ * h["z"] #=> "Go fish"
1569
+ * # This doesn't do what you might hope...
1570
+ * h.default = proc do |hash, key|
1571
+ * hash[key] = key + key
1572
+ * end
1573
+ * h[2] #=> #<Proc:0x401b3948@-:6>
1574
+ * h["cat"] #=> #<Proc:0x401b3948@-:6>
1575
+ */
1576
+
1577
+ static mrb_value
1578
+ mrb_hash_set_default(mrb_state *mrb, mrb_value hash)
1579
+ {
1580
+ mrb_value ifnone = mrb_get_arg1(mrb);
1581
+
1582
+ hash_modify(mrb, hash);
1583
+ mrb_iv_set(mrb, hash, MRB_SYM(ifnone), ifnone);
1584
+ RHASH(hash)->flags &= ~MRB_HASH_PROC_DEFAULT;
1585
+ if (!mrb_nil_p(ifnone)) {
1586
+ RHASH(hash)->flags |= MRB_HASH_DEFAULT;
1587
+ }
1588
+ else {
1589
+ RHASH(hash)->flags &= ~MRB_HASH_DEFAULT;
1590
+ }
1591
+ return ifnone;
1592
+ }
1593
+
1594
+ /* 15.2.13.4.7 */
1595
+ /*
1596
+ * call-seq:
1597
+ * hsh.default_proc -> anObject
1598
+ *
1599
+ * If `Hash::new` was invoked with a block, return that
1600
+ * block, otherwise return `nil`.
1601
+ *
1602
+ * h = Hash.new {|h,k| h[k] = k*k } #=> {}
1603
+ * p = h.default_proc #=> #<Proc:0x401b3d08@-:1>
1604
+ * a = [] #=> []
1605
+ * p.call(a, 2)
1606
+ * a #=> [nil, nil, 4]
1607
+ */
1608
+
1609
+ static mrb_value
1610
+ mrb_hash_default_proc(mrb_state *mrb, mrb_value hash)
1611
+ {
1612
+ if (MRB_RHASH_PROCDEFAULT_P(hash)) {
1613
+ return RHASH_PROCDEFAULT(hash);
1614
+ }
1615
+ return mrb_nil_value();
1616
+ }
1617
+
1618
+ /*
1619
+ * call-seq:
1620
+ * hsh.default_proc = proc_obj -> proc_obj
1621
+ *
1622
+ * Sets the default proc to be executed on each key lookup.
1623
+ *
1624
+ * h.default_proc = proc do |hash, key|
1625
+ * hash[key] = key + key
1626
+ * end
1627
+ * h[2] #=> 4
1628
+ * h["cat"] #=> "catcat"
1629
+ */
1630
+
1631
+ static mrb_value
1632
+ mrb_hash_set_default_proc(mrb_state *mrb, mrb_value hash)
1633
+ {
1634
+ mrb_value ifnone = mrb_get_arg1(mrb);
1635
+
1636
+ hash_modify(mrb, hash);
1637
+ mrb_bool has_ifnone = !mrb_nil_p(ifnone);
1638
+ if (has_ifnone) {
1639
+ mrb_check_type(mrb, ifnone, MRB_TT_PROC);
1640
+ }
1641
+ mrb_iv_set(mrb, hash, MRB_SYM(ifnone), ifnone);
1642
+ if (has_ifnone) {
1643
+ hash_set_default_proc(mrb, hash, ifnone);
1644
+ }
1645
+ else {
1646
+ RHASH(hash)->flags &= ~MRB_HASH_DEFAULT;
1647
+ RHASH(hash)->flags &= ~MRB_HASH_PROC_DEFAULT;
1648
+ }
1649
+ return ifnone;
1650
+ }
1651
+
1652
+ /**
1653
+ * Deletes a key-value pair from the hash.
1654
+ *
1655
+ * Removes the entry associated with `key` from the `hash`.
1656
+ * The hash is modified in place.
1657
+ *
1658
+ * @param mrb The mruby state.
1659
+ * @param hash The hash object (mrb_value) to modify.
1660
+ * @param key The key (mrb_value) of the entry to delete.
1661
+ * @return The value associated with the deleted key if found, otherwise nil.
1662
+ */
1663
+ MRB_API mrb_value
1664
+ mrb_hash_delete_key(mrb_state *mrb, mrb_value hash, mrb_value key)
1665
+ {
1666
+ mrb_value del_val;
1667
+
1668
+ hash_modify(mrb, hash);
1669
+ if (h_delete(mrb, mrb_hash_ptr(hash), key, &del_val)) {
1670
+ return del_val;
1671
+ }
1672
+
1673
+ /* not found */
1674
+ return mrb_nil_value();
1675
+ }
1676
+
1677
+ static mrb_value
1678
+ mrb_hash_delete(mrb_state *mrb, mrb_value self)
1679
+ {
1680
+ mrb_value key = mrb_get_arg1(mrb);
1681
+ mrb->c->ci->mid = 0;
1682
+ return mrb_hash_delete_key(mrb, self, key);
1683
+ }
1684
+
1685
+ /* 15.2.13.4.24 */
1686
+ /*
1687
+ * call-seq:
1688
+ * hsh.shift -> anArray or obj
1689
+ *
1690
+ * Removes a key-value pair from `hsh` and returns it as the
1691
+ * two-item array [ `key`, `value` ], or
1692
+ * the hash's default value if the hash is empty.
1693
+ *
1694
+ * h = { 1 => "a", 2 => "b", 3 => "c" }
1695
+ * h.shift #=> [1, "a"]
1696
+ * h #=> {2=>"b", 3=>"c"}
1697
+ */
1698
+
1699
+ static mrb_value
1700
+ mrb_hash_shift(mrb_state *mrb, mrb_value hash)
1701
+ {
1702
+ struct RHash *h = mrb_hash_ptr(hash);
1703
+
1704
+ hash_modify(mrb, hash);
1705
+ if (h_size(h) == 0) {
1706
+ return mrb_nil_value();
1707
+ }
1708
+ else {
1709
+ mrb_value del_key, del_val;
1710
+ h_shift(mrb, h, &del_key, &del_val);
1711
+ mrb_gc_protect(mrb, del_key);
1712
+ mrb_gc_protect(mrb, del_val);
1713
+ return mrb_assoc_new(mrb, del_key, del_val);
1714
+ }
1715
+ }
1716
+
1717
+ /* 15.2.13.4.4 */
1718
+ /*
1719
+ * call-seq:
1720
+ * hsh.clear -> hsh
1721
+ *
1722
+ * Removes all key-value pairs from `hsh`.
1723
+ *
1724
+ * h = { "a" => 100, "b" => 200 } #=> {"a"=>100, "b"=>200}
1725
+ * h.clear #=> {}
1726
+ *
1727
+ */
1728
+
1729
+ MRB_API mrb_value
1730
+ mrb_hash_clear(mrb_state *mrb, mrb_value hash)
1731
+ {
1732
+ hash_modify(mrb, hash);
1733
+ h_clear(mrb, mrb_hash_ptr(hash));
1734
+ return hash;
1735
+ }
1736
+
1737
+ /* 15.2.13.4.3 */
1738
+ /* 15.2.13.4.26 */
1739
+ /*
1740
+ * call-seq:
1741
+ * hsh[key] = value -> value
1742
+ * hsh.store(key, value) -> value
1743
+ *
1744
+ * Element Assignment---Associates the value given by
1745
+ * `value` with the key given by `key`.
1746
+ * `key` should not have its value changed while it is in
1747
+ * use as a key (a `String` passed as a key will be
1748
+ * duplicated and frozen).
1749
+ *
1750
+ * h = { "a" => 100, "b" => 200 }
1751
+ * h["a"] = 9
1752
+ * h["c"] = 4
1753
+ * h #=> {"a"=>9, "b"=>200, "c"=>4}
1754
+ *
1755
+ */
1756
+ static mrb_value
1757
+ mrb_hash_aset(mrb_state *mrb, mrb_value self)
1758
+ {
1759
+ mrb_int argc = mrb_get_argc(mrb);
1760
+
1761
+ if (argc != 2) {
1762
+ mrb_argnum_error(mrb, argc, 2, 2);
1763
+ }
1764
+
1765
+ const mrb_value *argv = mrb_get_argv(mrb);
1766
+ mrb_value key = argv[0];
1767
+ mrb_value val = argv[1];
1768
+
1769
+ mrb_hash_set(mrb, self, key, val);
1770
+ return val;
1771
+ }
1772
+
1773
+ /**
1774
+ * Returns the number of key-value pairs in the hash.
1775
+ *
1776
+ * @param mrb The mruby state (unused in the current implementation, but part of MRB_API convention).
1777
+ * @param hash The hash object (mrb_value) to get the size of.
1778
+ * @return An mrb_int representing the number of entries in the hash.
1779
+ */
1780
+ MRB_API mrb_int
1781
+ mrb_hash_size(mrb_state *mrb, mrb_value hash)
1782
+ {
1783
+ return (mrb_int)h_size(mrb_hash_ptr(hash));
1784
+ }
1785
+
1786
+ /* 15.2.13.4.20 */
1787
+ /* 15.2.13.4.25 */
1788
+ /*
1789
+ * call-seq:
1790
+ * hsh.length -> integer
1791
+ * hsh.size -> integer
1792
+ *
1793
+ * Returns the number of key-value pairs in the hash.
1794
+ *
1795
+ * h = { "d" => 100, "a" => 200, "v" => 300, "e" => 400 }
1796
+ * h.length #=> 4
1797
+ * h.delete("a") #=> 200
1798
+ * h.length #=> 3
1799
+ */
1800
+ static mrb_value
1801
+ mrb_hash_size_m(mrb_state *mrb, mrb_value self)
1802
+ {
1803
+ mrb_int size = mrb_hash_size(mrb, self);
1804
+ return mrb_int_value(mrb, size);
1805
+ }
1806
+
1807
+ MRB_API mrb_bool
1808
+ mrb_hash_empty_p(mrb_state *mrb, mrb_value self)
1809
+ {
1810
+ return h_size(mrb_hash_ptr(self)) == 0;
1811
+ }
1812
+
1813
+ /* 15.2.13.4.12 */
1814
+ /*
1815
+ * call-seq:
1816
+ * hsh.empty? -> true or false
1817
+ *
1818
+ * Returns `true` if `hsh` contains no key-value pairs.
1819
+ *
1820
+ * {}.empty? #=> true
1821
+ *
1822
+ */
1823
+ static mrb_value
1824
+ mrb_hash_empty_m(mrb_state *mrb, mrb_value self)
1825
+ {
1826
+ return mrb_bool_value(mrb_hash_empty_p(mrb, self));
1827
+ }
1828
+
1829
+ /* 15.2.13.4.19 */
1830
+ /*
1831
+ * call-seq:
1832
+ * hsh.keys -> array
1833
+ *
1834
+ * Returns a new array populated with the keys from this hash. See also
1835
+ * `Hash#values`.
1836
+ *
1837
+ * h = { "a" => 100, "b" => 200, "c" => 300, "d" => 400 }
1838
+ * h.keys #=> ["a", "b", "c", "d"]
1839
+ *
1840
+ */
1841
+
1842
+ MRB_API mrb_value
1843
+ mrb_hash_keys(mrb_state *mrb, mrb_value hash)
1844
+ {
1845
+ struct RHash *h = mrb_hash_ptr(hash);
1846
+ mrb_value ary = mrb_ary_new_capa(mrb, (mrb_int)h_size(h));
1847
+ H_EACH(h, entry) {
1848
+ mrb_ary_push(mrb, ary, entry->key);
1849
+ }
1850
+ return ary;
1851
+ }
1852
+
1853
+ /* 15.2.13.4.28 */
1854
+ /*
1855
+ * call-seq:
1856
+ * hsh.values -> array
1857
+ *
1858
+ * Returns a new array populated with the values from `hsh`. See
1859
+ * also `Hash#keys`.
1860
+ *
1861
+ * h = { "a" => 100, "b" => 200, "c" => 300 }
1862
+ * h.values #=> [100, 200, 300]
1863
+ *
1864
+ */
1865
+
1866
+ MRB_API mrb_value
1867
+ mrb_hash_values(mrb_state *mrb, mrb_value hash)
1868
+ {
1869
+ struct RHash *h = mrb_hash_ptr(hash);
1870
+ mrb_value ary = mrb_ary_new_capa(mrb, (mrb_int)h_size(h));
1871
+ H_EACH(h, entry) {
1872
+ mrb_ary_push(mrb, ary, entry->val);
1873
+ }
1874
+ return ary;
1875
+ }
1876
+
1877
+ /* 15.2.13.4.13 */
1878
+ /* 15.2.13.4.15 */
1879
+ /* 15.2.13.4.18 */
1880
+ /* 15.2.13.4.21 */
1881
+ /*
1882
+ * call-seq:
1883
+ * hsh.has_key?(key) -> true or false
1884
+ * hsh.include?(key) -> true or false
1885
+ * hsh.key?(key) -> true or false
1886
+ * hsh.member?(key) -> true or false
1887
+ *
1888
+ * Returns `true` if the given key is present in `hsh`.
1889
+ *
1890
+ * h = { "a" => 100, "b" => 200 }
1891
+ * h.has_key?("a") #=> true
1892
+ * h.has_key?("z") #=> false
1893
+ *
1894
+ */
1895
+
1896
+ MRB_API mrb_bool
1897
+ mrb_hash_key_p(mrb_state *mrb, mrb_value hash, mrb_value key)
1898
+ {
1899
+ mrb_value val;
1900
+ return h_get(mrb, mrb_hash_ptr(hash), key, &val);
1901
+ }
1902
+
1903
+ static mrb_value
1904
+ mrb_hash_has_key(mrb_state *mrb, mrb_value hash)
1905
+ {
1906
+ mrb_value key = mrb_get_arg1(mrb);
1907
+ mrb_bool key_p;
1908
+
1909
+ key_p = mrb_hash_key_p(mrb, hash, key);
1910
+ return mrb_bool_value(key_p);
1911
+ }
1912
+
1913
+ /* 15.2.13.4.14 */
1914
+ /* 15.2.13.4.27 */
1915
+ /*
1916
+ * call-seq:
1917
+ * hsh.has_value?(value) -> true or false
1918
+ * hsh.value?(value) -> true or false
1919
+ *
1920
+ * Returns `true` if the given value is present for some key
1921
+ * in `hsh`.
1922
+ *
1923
+ * h = { "a" => 100, "b" => 200 }
1924
+ * h.has_value?(100) #=> true
1925
+ * h.has_value?(999) #=> false
1926
+ */
1927
+
1928
+ static mrb_value
1929
+ mrb_hash_has_value(mrb_state *mrb, mrb_value hash)
1930
+ {
1931
+ mrb_value val = mrb_get_arg1(mrb);
1932
+ struct RHash *h = mrb_hash_ptr(hash);
1933
+ H_EACH(h, entry) {
1934
+ H_CHECK_MODIFIED(mrb, h) {
1935
+ if (mrb_equal(mrb, val, entry->val)) return mrb_true_value();
1936
+ }
1937
+ }
1938
+ return mrb_false_value();
1939
+ }
1940
+
1941
+ /**
1942
+ * Merges the contents of `hash2` into `hash1`.
1943
+ *
1944
+ * Iterates over `hash2` and for each key-value pair, sets it in `hash1`.
1945
+ * If a key from `hash2` already exists in `hash1`, its value in `hash1`
1946
+ * will be overwritten. `hash1` is modified in place.
1947
+ *
1948
+ * - `hash1` must not be frozen.
1949
+ * - `hash2` must be a hash.
1950
+ * - If `hash1` and `hash2` are the same object, or if `hash2` is empty,
1951
+ * the function returns without doing anything.
1952
+ * - Write barriers are triggered for keys and values from `hash2` as they
1953
+ * are inserted into `hash1`.
1954
+ *
1955
+ * @param mrb The mruby state.
1956
+ * @param hash1 The hash object (mrb_value) to be modified.
1957
+ * @param hash2 The hash object (mrb_value) whose contents will be merged into `hash1`.
1958
+ */
1959
+ MRB_API void
1960
+ mrb_hash_merge(mrb_state *mrb, mrb_value hash1, mrb_value hash2)
1961
+ {
1962
+ struct RHash *h1, *h2;
1963
+
1964
+ hash_modify(mrb, hash1);
1965
+ mrb_ensure_hash_type(mrb, hash2);
1966
+ h1 = mrb_hash_ptr(hash1);
1967
+ h2 = mrb_hash_ptr(hash2);
1968
+
1969
+ if (h1 == h2) return;
1970
+ if (h_size(h2) == 0) return;
1971
+ H_EACH(h2, entry) {
1972
+ H_CHECK_MODIFIED(mrb, h2) {h_set(mrb, h1, entry->key, entry->val);}
1973
+ mrb_field_write_barrier_value(mrb, (struct RBasic*)h1, entry->key);
1974
+ mrb_field_write_barrier_value(mrb, (struct RBasic*)h1, entry->val);
1975
+ }
1976
+ }
1977
+
1978
+ static mrb_value
1979
+ mrb_hash_merge_m(mrb_state *mrb, mrb_value hash)
1980
+ {
1981
+ mrb_int argc;
1982
+ mrb_value *argv;
1983
+
1984
+ mrb_get_args(mrb, "*", &argv, &argc);
1985
+ while (argc--) {
1986
+ mrb_hash_merge(mrb, hash, *argv++);
1987
+ }
1988
+ return hash;
1989
+ }
1990
+
1991
+ /*
1992
+ * call-seq:
1993
+ * hsh.rehash -> hsh
1994
+ *
1995
+ * Rebuilds the hash based on the current hash values for each key. If
1996
+ * values of key objects have changed since they were inserted, this
1997
+ * method will reindex `hsh`.
1998
+ *
1999
+ * keys = (1..17).map{|n| [n]}
2000
+ * k = keys[0]
2001
+ * h = {}
2002
+ * keys.each{|key| h[key] = key[0]}
2003
+ * h #=> { [1]=>1, [2]=>2, ... [16]=>16, [17]=>17}
2004
+ * h[k] #=> 1
2005
+ * k[0] = keys.size + 1
2006
+ * h #=> {[18]=>1, [2]=>2, ... [16]=>16, [17]=>17}
2007
+ * h[k] #=> nil
2008
+ * h.rehash
2009
+ * h[k] #=> 1
2010
+ */
2011
+ static mrb_value
2012
+ mrb_hash_rehash(mrb_state *mrb, mrb_value self)
2013
+ {
2014
+ hash_modify(mrb, self);
2015
+ h_rehash(mrb, mrb_hash_ptr(self));
2016
+ return self;
2017
+ }
2018
+
2019
+ static mrb_value
2020
+ mrb_hash_compact(mrb_state *mrb, mrb_value hash)
2021
+ {
2022
+ struct RHash *h = mrb_hash_ptr(hash);
2023
+ mrb_bool ht_p = h_ht_p(h);
2024
+ uint32_t size = ht_p ? ht_size(h) : ar_size(h);
2025
+ uint32_t dec = 0;
2026
+
2027
+ hash_modify(mrb, hash);
2028
+ H_EACH(h, entry) {
2029
+ if (mrb_nil_p(entry->val)) {
2030
+ entry_delete(entry);
2031
+ dec++;
2032
+ }
2033
+ }
2034
+ if (dec == 0) return mrb_nil_value();
2035
+ size -= dec;
2036
+ if (ht_p) {
2037
+ ht_set_size(h, size);
2038
+ }
2039
+ else {
2040
+ ar_set_size(h, size);
2041
+ }
2042
+ return hash;
2043
+ }
2044
+
2045
+ /*
2046
+ * Internal method for pattern matching key check + value extraction.
2047
+ * Returns an array of values if all keys exist, false otherwise.
2048
+ *
2049
+ * {a: 1, b: 2}.__pat_values([:a, :b]) #=> [1, 2]
2050
+ * {a: 1}.__pat_values([:a, :b]) #=> false
2051
+ */
2052
+ static mrb_value
2053
+ mrb_hash_pat_values(mrb_state *mrb, mrb_value hash)
2054
+ {
2055
+ mrb_value keys;
2056
+ mrb_get_args(mrb, "A", &keys);
2057
+
2058
+ const mrb_value *ary = RARRAY_PTR(keys);
2059
+ mrb_int klen = RARRAY_LEN(keys);
2060
+ struct RHash *h = mrb_hash_ptr(hash);
2061
+ mrb_value result = mrb_ary_new_capa(mrb, klen);
2062
+ int ai = mrb_gc_arena_save(mrb);
2063
+
2064
+ for (mrb_int i = 0; i < klen; i++) {
2065
+ mrb_value val;
2066
+ if (!h_get(mrb, h, ary[i], &val)) {
2067
+ return mrb_false_value();
2068
+ }
2069
+ mrb_ary_push(mrb, result, val);
2070
+ mrb_gc_arena_restore(mrb, ai);
2071
+ }
2072
+ return result;
2073
+ }
2074
+
2075
+ /*
2076
+ * Internal method for pattern matching **rest.
2077
+ * Returns a new hash excluding keys in the given array.
2078
+ *
2079
+ * {a: 1, b: 2, c: 3}.__except([:a, :c]) #=> {b: 2}
2080
+ */
2081
+ static mrb_value
2082
+ mrb_hash_except_keys(mrb_state *mrb, mrb_value hash)
2083
+ {
2084
+ mrb_value keys;
2085
+ mrb_get_args(mrb, "A", &keys);
2086
+
2087
+ const mrb_value *ary = RARRAY_PTR(keys);
2088
+ mrb_int klen = RARRAY_LEN(keys);
2089
+ mrb_value result = mrb_hash_new(mrb);
2090
+ struct RHash *h = mrb_hash_ptr(hash);
2091
+ int ai = mrb_gc_arena_save(mrb);
2092
+
2093
+ H_EACH(h, entry) {
2094
+ mrb_bool found = FALSE;
2095
+ for (mrb_int i = 0; i < klen; i++) {
2096
+ if (mrb_equal(mrb, entry->key, ary[i])) {
2097
+ found = TRUE;
2098
+ break;
2099
+ }
2100
+ }
2101
+ if (!found) {
2102
+ mrb_hash_set(mrb, result, entry->key, entry->val);
2103
+ }
2104
+ mrb_gc_arena_restore(mrb, ai);
2105
+ }
2106
+ return result;
2107
+ }
2108
+
2109
+ /*
2110
+ * call-seq:
2111
+ * hash.to_s -> string
2112
+ * hash.inspect -> string
2113
+ *
2114
+ * Return the contents of this hash as a string.
2115
+ */
2116
+ static mrb_value
2117
+ mrb_hash_to_s(mrb_state *mrb, mrb_value self)
2118
+ {
2119
+ mrb->c->ci->mid = MRB_SYM(inspect);
2120
+ mrb_value ret = mrb_str_new_lit(mrb, "{");
2121
+ int ai = mrb_gc_arena_save(mrb);
2122
+ if (MRB_RECURSIVE_UNARY_P(mrb, MRB_SYM(inspect), self)) {
2123
+ mrb_str_cat_lit(mrb, ret, "...}");
2124
+ return ret;
2125
+ }
2126
+
2127
+ mrb_int i = 0;
2128
+ struct RHash *h = mrb_hash_ptr(self);
2129
+ H_EACH(h, entry) {
2130
+ if (i++ > 0) mrb_str_cat_lit(mrb, ret, ", ");
2131
+ if (mrb_symbol_p(entry->key)) {
2132
+ mrb_str_cat_str(mrb, ret, mrb_obj_as_string(mrb, entry->key));
2133
+ mrb_gc_arena_restore(mrb, ai);
2134
+ mrb_str_cat_lit(mrb, ret, ": ");
2135
+ }
2136
+ else {
2137
+ H_CHECK_MODIFIED(mrb, h) {
2138
+ mrb_str_cat_str(mrb, ret, mrb_inspect(mrb, entry->key));
2139
+ }
2140
+ mrb_gc_arena_restore(mrb, ai);
2141
+ mrb_str_cat_lit(mrb, ret, " => ");
2142
+ }
2143
+ H_CHECK_MODIFIED(mrb, h) {
2144
+ mrb_str_cat_str(mrb, ret, mrb_inspect(mrb, entry->val));
2145
+ }
2146
+ mrb_gc_arena_restore(mrb, ai);
2147
+ }
2148
+ mrb_str_cat_lit(mrb, ret, "}");
2149
+
2150
+ return ret;
2151
+ }
2152
+
2153
+ /*
2154
+ * call-seq:
2155
+ * hash.to_hash -> self
2156
+ *
2157
+ * Returns self.
2158
+ */
2159
+ static mrb_value
2160
+ mrb_hash_to_hash(mrb_state *mrb, mrb_value self)
2161
+ {
2162
+ return self;
2163
+ }
2164
+
2165
+ /*
2166
+ * call-seq:
2167
+ * hash.assoc(key) -> new_array or nil
2168
+ *
2169
+ * If the given key is found, returns a 2-element Array containing that key
2170
+ * and its value:
2171
+ *
2172
+ * h = {foo: 0, bar: 1, baz: 2}
2173
+ * h.assoc(:bar) # => [:bar, 1]
2174
+ *
2175
+ * Returns nil if key key is not found.
2176
+ */
2177
+ static mrb_value
2178
+ mrb_hash_assoc(mrb_state *mrb, mrb_value hash)
2179
+ {
2180
+ mrb_value key = mrb_get_arg1(mrb);
2181
+ struct RHash *h = mrb_hash_ptr(hash);
2182
+ H_EACH(h, entry) {
2183
+ if (obj_eql(mrb, entry->key, key, h)) {
2184
+ return mrb_assoc_new(mrb, entry->key, entry->val);
2185
+ }
2186
+ }
2187
+ return mrb_nil_value();
2188
+ }
2189
+
2190
+ /*
2191
+ * call-seq:
2192
+ * hash.rassoc(value) -> new_array or nil
2193
+ *
2194
+ * Returns a new 2-element Array consisting of the key and value of the
2195
+ * first-found entry whose value is == to value.
2196
+ *
2197
+ * h = {foo: 0, bar: 1, baz: 1}
2198
+ * h.rassoc(1) # => [:bar, 1]
2199
+ *
2200
+ * Returns nil if no such value found.
2201
+ */
2202
+ static mrb_value
2203
+ mrb_hash_rassoc(mrb_state *mrb, mrb_value hash)
2204
+ {
2205
+ mrb_value value = mrb_get_arg1(mrb);
2206
+ struct RHash *h = mrb_hash_ptr(hash);
2207
+ H_EACH(h, entry) {
2208
+ if (obj_eql(mrb, entry->val, value, h)) {
2209
+ return mrb_assoc_new(mrb, entry->key, entry->val);
2210
+ }
2211
+ }
2212
+ return mrb_nil_value();
2213
+ }
2214
+
2215
+ /* 15.2.13.4.1 */
2216
+ static mrb_value
2217
+ mrb_hash_equal(mrb_state *mrb, mrb_value hash)
2218
+ {
2219
+ mrb_value hash2 = mrb_get_arg1(mrb);
2220
+
2221
+ if (mrb_obj_equal(mrb, hash, hash2)) return mrb_true_value();
2222
+ if (!mrb_hash_p(hash2)) {
2223
+ return mrb_false_value();
2224
+ }
2225
+ if (mrb_hash_size(mrb, hash) != mrb_hash_size(mrb, hash2)) {
2226
+ return mrb_false_value();
2227
+ }
2228
+
2229
+ /* Check for recursion */
2230
+ if (MRB_RECURSIVE_BINARY_FUNC_P(mrb, MRB_OPSYM(eq), hash, hash2)) {
2231
+ return mrb_false_value();
2232
+ }
2233
+
2234
+ struct RHash *h1 = mrb_hash_ptr(hash);
2235
+ struct RHash *h2 = mrb_hash_ptr(hash2);
2236
+
2237
+ H_EACH(h1, entry) {
2238
+ mrb_value val2;
2239
+ mrb_bool found;
2240
+
2241
+ H_CHECK_MODIFIED(mrb, h1) {
2242
+ found = h_get(mrb, h2, entry->key, &val2);
2243
+ }
2244
+ if (!found) {
2245
+ return mrb_false_value();
2246
+ }
2247
+ H_CHECK_MODIFIED(mrb, h1) {
2248
+ if (!mrb_equal(mrb, entry->val, val2)) {
2249
+ return mrb_false_value();
2250
+ }
2251
+ }
2252
+ }
2253
+
2254
+ return mrb_true_value();
2255
+ }
2256
+
2257
+ /*
2258
+ * call-seq:
2259
+ * hash.eql?(other) -> true or false
2260
+ *
2261
+ * Returns true if hash and other are both hashes with the same content
2262
+ * compared by eql?.
2263
+ */
2264
+ static mrb_value
2265
+ mrb_hash_eql(mrb_state *mrb, mrb_value hash)
2266
+ {
2267
+ mrb_value hash2 = mrb_get_arg1(mrb);
2268
+
2269
+ if (mrb_obj_equal(mrb, hash, hash2)) return mrb_true_value();
2270
+ if (!mrb_hash_p(hash2)) {
2271
+ return mrb_false_value();
2272
+ }
2273
+ if (mrb_hash_size(mrb, hash) != mrb_hash_size(mrb, hash2)) {
2274
+ return mrb_false_value();
2275
+ }
2276
+
2277
+ /* Check for recursion */
2278
+ if (MRB_RECURSIVE_BINARY_FUNC_P(mrb, MRB_SYM_Q(eql), hash, hash2)) {
2279
+ return mrb_false_value();
2280
+ }
2281
+
2282
+ struct RHash *h1 = mrb_hash_ptr(hash);
2283
+ struct RHash *h2 = mrb_hash_ptr(hash2);
2284
+
2285
+ H_EACH(h1, entry) {
2286
+ mrb_value val2;
2287
+ mrb_bool found;
2288
+
2289
+ H_CHECK_MODIFIED(mrb, h1) {
2290
+ found = h_get(mrb, h2, entry->key, &val2);
2291
+ }
2292
+ if (!found) {
2293
+ return mrb_false_value();
2294
+ }
2295
+ H_CHECK_MODIFIED(mrb, h1) {
2296
+ if (!mrb_eql(mrb, entry->val, val2)) {
2297
+ return mrb_false_value();
2298
+ }
2299
+ }
2300
+ }
2301
+
2302
+ return mrb_true_value();
2303
+ }
2304
+
2305
+ /* ---------------------------*/
2306
+ static const mrb_mt_entry hash_rom_entries[] = {
2307
+ MRB_MT_ENTRY(mrb_hash_equal, MRB_OPSYM(eq), MRB_ARGS_REQ(1)), /* 15.2.13.4.1 */
2308
+ MRB_MT_ENTRY(mrb_hash_aget, MRB_OPSYM(aref), MRB_ARGS_REQ(1)), /* 15.2.13.4.2 */
2309
+ MRB_MT_ENTRY(mrb_hash_aset, MRB_OPSYM(aset), MRB_ARGS_REQ(2)), /* 15.2.13.4.3 */
2310
+ MRB_MT_ENTRY(mrb_hash_clear, MRB_SYM(clear), MRB_ARGS_NONE()), /* 15.2.13.4.4 */
2311
+ MRB_MT_ENTRY(mrb_hash_default, MRB_SYM(default), MRB_ARGS_OPT(1)), /* 15.2.13.4.5 */
2312
+ MRB_MT_ENTRY(mrb_hash_set_default, MRB_SYM_E(default), MRB_ARGS_REQ(1)), /* 15.2.13.4.6 */
2313
+ MRB_MT_ENTRY(mrb_hash_default_proc, MRB_SYM(default_proc), MRB_ARGS_NONE()), /* 15.2.13.4.7 */
2314
+ MRB_MT_ENTRY(mrb_hash_set_default_proc, MRB_SYM_E(default_proc), MRB_ARGS_REQ(1)), /* 15.2.13.4.7 */
2315
+ MRB_MT_ENTRY(mrb_hash_delete, MRB_SYM(__delete), MRB_ARGS_REQ(1)), /* core of 15.2.13.4.8 */
2316
+ MRB_MT_ENTRY(mrb_hash_eql, MRB_SYM_Q(eql), MRB_ARGS_REQ(1)), /* Hash#eql? */
2317
+ MRB_MT_ENTRY(mrb_hash_empty_m, MRB_SYM_Q(empty), MRB_ARGS_NONE()), /* 15.2.13.4.12 */
2318
+ MRB_MT_ENTRY(mrb_hash_has_key, MRB_SYM_Q(has_key), MRB_ARGS_REQ(1)), /* 15.2.13.4.13 */
2319
+ MRB_MT_ENTRY(mrb_hash_has_value, MRB_SYM_Q(has_value), MRB_ARGS_REQ(1)), /* 15.2.13.4.14 */
2320
+ MRB_MT_ENTRY(mrb_hash_has_key, MRB_SYM_Q(include), MRB_ARGS_REQ(1)), /* 15.2.13.4.15 */
2321
+ MRB_MT_ENTRY(mrb_hash_init, MRB_SYM(initialize), MRB_ARGS_OPT(1)|MRB_ARGS_BLOCK() | MRB_MT_PRIVATE), /* 15.2.13.4.16 */
2322
+ MRB_MT_ENTRY(mrb_hash_init_copy, MRB_SYM(initialize_copy), MRB_ARGS_REQ(1) | MRB_MT_PRIVATE), /* 15.2.13.4.17 */
2323
+ MRB_MT_ENTRY(mrb_hash_has_key, MRB_SYM_Q(key), MRB_ARGS_REQ(1)), /* 15.2.13.4.18 */
2324
+ MRB_MT_ENTRY(mrb_hash_keys, MRB_SYM(keys), MRB_ARGS_NONE()), /* 15.2.13.4.19 */
2325
+ MRB_MT_ENTRY(mrb_hash_size_m, MRB_SYM(length), MRB_ARGS_NONE()), /* 15.2.13.4.20 */
2326
+ MRB_MT_ENTRY(mrb_hash_has_key, MRB_SYM_Q(member), MRB_ARGS_REQ(1)), /* 15.2.13.4.21 */
2327
+ MRB_MT_ENTRY(mrb_hash_init_copy, MRB_SYM(replace), MRB_ARGS_REQ(1)), /* 15.2.13.4.23 */
2328
+ MRB_MT_ENTRY(mrb_hash_shift, MRB_SYM(shift), MRB_ARGS_NONE()), /* 15.2.13.4.24 */
2329
+ MRB_MT_ENTRY(mrb_hash_size_m, MRB_SYM(size), MRB_ARGS_NONE()), /* 15.2.13.4.25 */
2330
+ MRB_MT_ENTRY(mrb_hash_aset, MRB_SYM(store), MRB_ARGS_REQ(2)), /* 15.2.13.4.26 */
2331
+ MRB_MT_ENTRY(mrb_hash_has_value, MRB_SYM_Q(value), MRB_ARGS_REQ(1)), /* 15.2.13.4.27 */
2332
+ MRB_MT_ENTRY(mrb_hash_values, MRB_SYM(values), MRB_ARGS_NONE()), /* 15.2.13.4.28 */
2333
+ MRB_MT_ENTRY(mrb_hash_to_s, MRB_SYM(to_s), MRB_ARGS_NONE()),
2334
+ MRB_MT_ENTRY(mrb_hash_to_s, MRB_SYM(inspect), MRB_ARGS_NONE()),
2335
+ MRB_MT_ENTRY(mrb_hash_rehash, MRB_SYM(rehash), MRB_ARGS_NONE()),
2336
+ MRB_MT_ENTRY(mrb_hash_to_hash, MRB_SYM(to_hash), MRB_ARGS_NONE()),
2337
+ MRB_MT_ENTRY(mrb_hash_assoc, MRB_SYM(assoc), MRB_ARGS_REQ(1)),
2338
+ MRB_MT_ENTRY(mrb_hash_rassoc, MRB_SYM(rassoc), MRB_ARGS_REQ(1)),
2339
+ MRB_MT_ENTRY(mrb_hash_merge_m, MRB_SYM(__merge), MRB_ARGS_ANY()),
2340
+ MRB_MT_ENTRY(mrb_hash_compact, MRB_SYM(__compact), MRB_ARGS_NONE()), /* implementation of Hash#compact! */
2341
+ MRB_MT_ENTRY(mrb_hash_pat_values, MRB_SYM(__pat_values), MRB_ARGS_REQ(1)), /* for pattern matching keys */
2342
+ MRB_MT_ENTRY(mrb_hash_except_keys, MRB_SYM(__except), MRB_ARGS_REQ(1)), /* for pattern matching **rest */
2343
+ };
2344
+
2345
+ void
2346
+ mrb_init_hash(mrb_state *mrb)
2347
+ {
2348
+ struct RClass *h;
2349
+
2350
+ mrb->hash_class = h = mrb_define_class_id(mrb, MRB_SYM(Hash), mrb->object_class); /* 15.2.13 */
2351
+ MRB_SET_INSTANCE_TT(h, MRB_TT_HASH);
2352
+
2353
+ MRB_MT_INIT_ROM(mrb, h, hash_rom_entries);
2354
+ }
2355
+ #undef lesser