script_core 0.2.7 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (283) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/Gemfile +2 -2
  4. data/ext/enterprise_script_service/Rakefile +1 -1
  5. data/ext/enterprise_script_service/mruby/.github/workflows/build.yml +117 -74
  6. data/ext/enterprise_script_service/mruby/.github/workflows/codeql-analysis.yml +41 -37
  7. data/ext/enterprise_script_service/mruby/.github/workflows/lint.yml +23 -0
  8. data/ext/enterprise_script_service/mruby/.github/workflows/oss-fuzz.yml +27 -0
  9. data/ext/enterprise_script_service/mruby/.github/workflows/spell-checker.yml +17 -0
  10. data/ext/enterprise_script_service/mruby/.gitlab-ci.yml +3 -3
  11. data/ext/enterprise_script_service/mruby/.markdownlint.yml +16 -0
  12. data/ext/enterprise_script_service/mruby/.travis.yml +2 -2
  13. data/ext/enterprise_script_service/mruby/.yamllint +8 -0
  14. data/ext/enterprise_script_service/mruby/AUTHORS +3 -0
  15. data/ext/enterprise_script_service/mruby/CODEOWNERS +1 -0
  16. data/ext/enterprise_script_service/mruby/CONTRIBUTING.md +6 -13
  17. data/ext/enterprise_script_service/mruby/Doxyfile +4 -4
  18. data/ext/enterprise_script_service/mruby/LICENSE +1 -1
  19. data/ext/enterprise_script_service/mruby/Makefile +1 -1
  20. data/ext/enterprise_script_service/mruby/README.md +4 -14
  21. data/ext/enterprise_script_service/mruby/Rakefile +18 -108
  22. data/ext/enterprise_script_service/mruby/TODO.md +17 -0
  23. data/ext/enterprise_script_service/mruby/appveyor.yml +31 -25
  24. data/ext/enterprise_script_service/mruby/benchmark/bm_ao_render.rb +1 -1
  25. data/ext/enterprise_script_service/mruby/build_config.rb +9 -152
  26. data/ext/enterprise_script_service/mruby/{examples/targets/build_config_ArduinoDue.rb → build_config/ArduinoDue.rb} +2 -19
  27. data/ext/enterprise_script_service/mruby/{examples/targets/build_config_IntelEdison.rb → build_config/IntelEdison.rb} +2 -2
  28. data/ext/enterprise_script_service/mruby/{examples/targets/build_config_IntelGalileo.rb → build_config/IntelGalileo.rb} +1 -18
  29. data/ext/enterprise_script_service/mruby/{examples/targets/build_config_RX630.rb → build_config/RX630.rb} +2 -19
  30. data/ext/enterprise_script_service/mruby/build_config/android_arm64-v8a.rb +11 -0
  31. data/ext/enterprise_script_service/mruby/build_config/android_armeabi.rb +11 -0
  32. data/ext/enterprise_script_service/mruby/{examples/targets/build_config_android_armeabi_v7a_neon_hard.rb → build_config/android_armeabi_v7a_neon_hard.rb} +0 -15
  33. data/ext/enterprise_script_service/mruby/build_config/bench.rb +11 -0
  34. data/ext/enterprise_script_service/mruby/build_config/boxing.rb +21 -0
  35. data/ext/enterprise_script_service/mruby/{examples/targets/build_config_chipKITMax32.rb → build_config/chipKITMax32.rb} +2 -19
  36. data/ext/enterprise_script_service/mruby/{travis_config.rb → build_config/ci/gcc-clang.rb} +10 -10
  37. data/ext/enterprise_script_service/mruby/build_config/ci/msvc.rb +20 -0
  38. data/ext/enterprise_script_service/mruby/build_config/clang-asan.rb +11 -0
  39. data/ext/enterprise_script_service/mruby/build_config/cross-32bit.rb +14 -0
  40. data/ext/enterprise_script_service/mruby/build_config/default.rb +80 -0
  41. data/ext/enterprise_script_service/mruby/{examples/targets/build_config_dreamcast_shelf.rb → build_config/dreamcast_shelf.rb} +5 -19
  42. data/ext/enterprise_script_service/mruby/build_config/gameboyadvance.rb +73 -0
  43. data/ext/enterprise_script_service/mruby/build_config/host-cxx.rb +12 -0
  44. data/ext/enterprise_script_service/mruby/build_config/host-debug.rb +20 -0
  45. data/ext/enterprise_script_service/mruby/build_config/host-gprof.rb +14 -0
  46. data/ext/enterprise_script_service/mruby/build_config/host-m32.rb +15 -0
  47. data/ext/enterprise_script_service/mruby/build_config/host-shared.rb +36 -0
  48. data/ext/enterprise_script_service/mruby/build_config/mrbc.rb +11 -0
  49. data/ext/enterprise_script_service/mruby/build_config/no-float.rb +17 -0
  50. data/ext/enterprise_script_service/mruby/doc/guides/compile.md +138 -49
  51. data/ext/enterprise_script_service/mruby/doc/guides/debugger.md +5 -4
  52. data/ext/enterprise_script_service/mruby/doc/guides/gc-arena-howto.md +1 -1
  53. data/ext/enterprise_script_service/mruby/doc/guides/mrbconf.md +49 -22
  54. data/ext/enterprise_script_service/mruby/doc/guides/mrbgems.md +31 -14
  55. data/ext/enterprise_script_service/mruby/doc/guides/symbol.md +83 -0
  56. data/ext/enterprise_script_service/mruby/doc/limitations.md +35 -36
  57. data/ext/enterprise_script_service/mruby/doc/mruby3.md +163 -0
  58. data/ext/enterprise_script_service/mruby/doc/opcode.md +93 -107
  59. data/ext/enterprise_script_service/mruby/examples/mrbgems/c_and_ruby_extension_example/mrblib/example.rb +1 -1
  60. data/ext/enterprise_script_service/mruby/examples/mrbgems/c_and_ruby_extension_example/src/example.c +5 -1
  61. data/ext/enterprise_script_service/mruby/examples/mrbgems/c_extension_example/src/example.c +5 -1
  62. data/ext/enterprise_script_service/mruby/examples/mrbgems/ruby_extension_example/mrblib/example.rb +1 -1
  63. data/ext/enterprise_script_service/mruby/include/mrbconf.h +81 -62
  64. data/ext/enterprise_script_service/mruby/include/mruby.h +137 -96
  65. data/ext/enterprise_script_service/mruby/include/mruby/array.h +23 -6
  66. data/ext/enterprise_script_service/mruby/include/mruby/boxing_nan.h +73 -48
  67. data/ext/enterprise_script_service/mruby/include/mruby/boxing_no.h +8 -8
  68. data/ext/enterprise_script_service/mruby/include/mruby/boxing_word.h +79 -48
  69. data/ext/enterprise_script_service/mruby/include/mruby/class.h +10 -8
  70. data/ext/enterprise_script_service/mruby/include/mruby/common.h +4 -1
  71. data/ext/enterprise_script_service/mruby/include/mruby/compile.h +13 -7
  72. data/ext/enterprise_script_service/mruby/include/mruby/debug.h +2 -2
  73. data/ext/enterprise_script_service/mruby/include/mruby/dump.h +17 -35
  74. data/ext/enterprise_script_service/mruby/include/mruby/endian.h +44 -0
  75. data/ext/enterprise_script_service/mruby/include/mruby/error.h +39 -5
  76. data/ext/enterprise_script_service/mruby/include/mruby/gc.h +1 -0
  77. data/ext/enterprise_script_service/mruby/include/mruby/hash.h +33 -13
  78. data/ext/enterprise_script_service/mruby/include/mruby/irep.h +64 -14
  79. data/ext/enterprise_script_service/mruby/include/mruby/khash.h +6 -14
  80. data/ext/enterprise_script_service/mruby/include/mruby/numeric.h +36 -63
  81. data/ext/enterprise_script_service/mruby/include/mruby/opcode.h +1 -27
  82. data/ext/enterprise_script_service/mruby/include/mruby/ops.h +27 -23
  83. data/ext/enterprise_script_service/mruby/include/mruby/presym.h +40 -0
  84. data/ext/enterprise_script_service/mruby/include/mruby/presym/disable.h +70 -0
  85. data/ext/enterprise_script_service/mruby/include/mruby/presym/enable.h +37 -0
  86. data/ext/enterprise_script_service/mruby/include/mruby/presym/scanning.h +73 -0
  87. data/ext/enterprise_script_service/mruby/include/mruby/proc.h +80 -13
  88. data/ext/enterprise_script_service/mruby/include/mruby/string.h +10 -15
  89. data/ext/enterprise_script_service/mruby/include/mruby/throw.h +14 -3
  90. data/ext/enterprise_script_service/mruby/include/mruby/value.h +29 -19
  91. data/ext/enterprise_script_service/mruby/include/mruby/variable.h +1 -0
  92. data/ext/enterprise_script_service/mruby/include/mruby/version.h +26 -7
  93. data/ext/enterprise_script_service/mruby/lib/mruby/build.rb +198 -44
  94. data/ext/enterprise_script_service/mruby/lib/mruby/build/command.rb +55 -37
  95. data/ext/enterprise_script_service/mruby/lib/mruby/build/load_gems.rb +12 -10
  96. data/ext/enterprise_script_service/mruby/lib/{mruby-core-ext.rb → mruby/core_ext.rb} +10 -3
  97. data/ext/enterprise_script_service/mruby/lib/mruby/gem.rb +75 -32
  98. data/ext/enterprise_script_service/mruby/lib/mruby/lockfile.rb +1 -1
  99. data/ext/enterprise_script_service/mruby/lib/mruby/presym.rb +132 -0
  100. data/ext/enterprise_script_service/mruby/mrbgems/default-no-fpu.gembox +3 -0
  101. data/ext/enterprise_script_service/mruby/mrbgems/default-no-stdio.gembox +4 -0
  102. data/ext/enterprise_script_service/mruby/mrbgems/default.gembox +9 -88
  103. data/ext/enterprise_script_service/mruby/mrbgems/full-core.gembox +1 -4
  104. data/ext/enterprise_script_service/mruby/mrbgems/math.gembox +10 -0
  105. data/ext/enterprise_script_service/mruby/mrbgems/metaprog.gembox +15 -0
  106. data/ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb +1 -1
  107. data/ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/src/array.c +5 -4
  108. data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-config/mrbgem.rake +28 -19
  109. data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-config/mruby-config +18 -8
  110. data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-debugger/bintest/mrdb.rb +3 -6
  111. data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-debugger/bintest/print.rb +10 -10
  112. data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c +14 -9
  113. data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.c +3 -2
  114. data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c +4 -3
  115. data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.h +2 -6
  116. data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdbconf.h +4 -4
  117. data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-mirb/bintest/mirb.rb +23 -5
  118. data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-mirb/mrbgem.rake +11 -2
  119. data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c +41 -34
  120. data/ext/enterprise_script_service/mruby/mrbgems/{mruby-compiler → mruby-bin-mrbc}/bintest/mrbc.rb +0 -0
  121. data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-mrbc/mrbgem.rake +3 -4
  122. data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c +19 -9
  123. data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-mruby/bintest/mruby.rb +25 -4
  124. data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-mruby/mrbgem.rake +1 -1
  125. data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c +22 -6
  126. data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-strip/bintest/mruby-strip.rb +1 -1
  127. data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c +2 -2
  128. data/ext/enterprise_script_service/mruby/mrbgems/mruby-catch/mrbgem.rake +5 -0
  129. data/ext/enterprise_script_service/mruby/mrbgems/mruby-catch/mrblib/catch.rb +27 -0
  130. data/ext/enterprise_script_service/mruby/mrbgems/mruby-class-ext/src/class.c +2 -1
  131. data/ext/enterprise_script_service/mruby/mrbgems/mruby-compiler/core/codegen.c +430 -399
  132. data/ext/enterprise_script_service/mruby/mrbgems/mruby-compiler/core/keywords +5 -0
  133. data/ext/enterprise_script_service/mruby/mrbgems/mruby-compiler/core/lex.def +49 -44
  134. data/ext/enterprise_script_service/mruby/mrbgems/mruby-compiler/core/parse.y +559 -217
  135. data/ext/enterprise_script_service/mruby/mrbgems/mruby-compiler/core/y.tab.c +4774 -4193
  136. data/ext/enterprise_script_service/mruby/mrbgems/mruby-compiler/mrbgem.rake +18 -19
  137. data/ext/enterprise_script_service/mruby/mrbgems/mruby-complex/mrblib/complex.rb +1 -1
  138. data/ext/enterprise_script_service/mruby/mrbgems/mruby-complex/src/complex.c +8 -7
  139. data/ext/enterprise_script_service/mruby/mrbgems/mruby-complex/test/complex.rb +4 -4
  140. data/ext/enterprise_script_service/mruby/mrbgems/mruby-enumerator/mrblib/enumerator.rb +1 -0
  141. data/ext/enterprise_script_service/mruby/mrbgems/mruby-enumerator/test/enumerator.rb +2 -2
  142. data/ext/enterprise_script_service/mruby/mrbgems/mruby-error/mrbgem.rake +2 -2
  143. data/ext/enterprise_script_service/mruby/mrbgems/mruby-eval/src/eval.c +17 -25
  144. data/ext/enterprise_script_service/mruby/mrbgems/mruby-fiber/src/fiber.c +18 -13
  145. data/ext/enterprise_script_service/mruby/mrbgems/mruby-hash-ext/src/hash-ext.c +30 -2
  146. data/ext/enterprise_script_service/mruby/mrbgems/mruby-hash-ext/test/hash.rb +7 -0
  147. data/ext/enterprise_script_service/mruby/mrbgems/mruby-inline-struct/test/inline.c +2 -2
  148. data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/README.md +18 -16
  149. data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/include/mruby/ext/io.h +2 -2
  150. data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/mrblib/file.rb +9 -4
  151. data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/mrblib/io.rb +2 -2
  152. data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/src/file.c +55 -52
  153. data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/src/file_test.c +4 -2
  154. data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/src/io.c +99 -87
  155. data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/test/file.rb +2 -0
  156. data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/test/io.rb +2 -3
  157. data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/test/mruby_io_test.c +1 -1
  158. data/ext/enterprise_script_service/mruby/mrbgems/mruby-kernel-ext/src/kernel.c +7 -6
  159. data/ext/enterprise_script_service/mruby/mrbgems/mruby-math/src/math.c +13 -12
  160. data/ext/enterprise_script_service/mruby/mrbgems/mruby-math/test/math.rb +5 -4
  161. data/ext/enterprise_script_service/mruby/mrbgems/mruby-metaprog/src/metaprog.c +43 -58
  162. data/ext/enterprise_script_service/mruby/mrbgems/mruby-metaprog/test/metaprog.rb +4 -4
  163. data/ext/enterprise_script_service/mruby/mrbgems/mruby-method/README.md +4 -3
  164. data/ext/enterprise_script_service/mruby/mrbgems/mruby-method/src/method.c +77 -74
  165. data/ext/enterprise_script_service/mruby/mrbgems/mruby-method/test/method.rb +4 -4
  166. data/ext/enterprise_script_service/mruby/mrbgems/mruby-numeric-ext/src/numeric_ext.c +14 -13
  167. data/ext/enterprise_script_service/mruby/mrbgems/mruby-object-ext/src/object.c +5 -4
  168. data/ext/enterprise_script_service/mruby/mrbgems/mruby-objectspace/src/mruby_objectspace.c +18 -12
  169. data/ext/enterprise_script_service/mruby/mrbgems/mruby-os-memsize/mrbgem.rake +10 -0
  170. data/ext/enterprise_script_service/mruby/mrbgems/mruby-os-memsize/src/memsize.c +231 -0
  171. data/ext/enterprise_script_service/mruby/mrbgems/mruby-os-memsize/test/memsize.rb +63 -0
  172. data/ext/enterprise_script_service/mruby/mrbgems/mruby-pack/README.md +15 -18
  173. data/ext/enterprise_script_service/mruby/mrbgems/mruby-pack/src/pack.c +38 -88
  174. data/ext/enterprise_script_service/mruby/mrbgems/mruby-print/mrblib/print.rb +1 -30
  175. data/ext/enterprise_script_service/mruby/mrbgems/mruby-print/src/print.c +62 -26
  176. data/ext/enterprise_script_service/mruby/mrbgems/mruby-proc-ext/src/proc.c +32 -19
  177. data/ext/enterprise_script_service/mruby/mrbgems/mruby-proc-ext/test/proc.c +1 -1
  178. data/ext/enterprise_script_service/mruby/mrbgems/mruby-random/src/random.c +98 -43
  179. data/ext/enterprise_script_service/mruby/mrbgems/mruby-random/test/random.rb +2 -2
  180. data/ext/enterprise_script_service/mruby/mrbgems/mruby-range-ext/mrblib/range.rb +39 -6
  181. data/ext/enterprise_script_service/mruby/mrbgems/mruby-range-ext/src/range.c +20 -40
  182. data/ext/enterprise_script_service/mruby/mrbgems/mruby-range-ext/test/range.rb +27 -3
  183. data/ext/enterprise_script_service/mruby/mrbgems/mruby-rational/mrblib/rational.rb +11 -17
  184. data/ext/enterprise_script_service/mruby/mrbgems/mruby-rational/src/rational.c +216 -38
  185. data/ext/enterprise_script_service/mruby/mrbgems/mruby-rational/test/rational.rb +6 -6
  186. data/ext/enterprise_script_service/mruby/mrbgems/mruby-sleep/README.md +6 -4
  187. data/ext/enterprise_script_service/mruby/mrbgems/mruby-sleep/src/mrb_sleep.c +4 -4
  188. data/ext/enterprise_script_service/mruby/mrbgems/mruby-socket/README.md +3 -2
  189. data/ext/enterprise_script_service/mruby/mrbgems/mruby-socket/src/socket.c +47 -45
  190. data/ext/enterprise_script_service/mruby/mrbgems/mruby-sprintf/src/sprintf.c +102 -71
  191. data/ext/enterprise_script_service/mruby/mrbgems/mruby-sprintf/test/sprintf.rb +4 -2
  192. data/ext/enterprise_script_service/mruby/mrbgems/mruby-string-ext/mrblib/string.rb +23 -1
  193. data/ext/enterprise_script_service/mruby/mrbgems/mruby-string-ext/src/string.c +13 -9
  194. data/ext/enterprise_script_service/mruby/mrbgems/mruby-struct/mrblib/struct.rb +1 -1
  195. data/ext/enterprise_script_service/mruby/mrbgems/mruby-struct/src/struct.c +18 -25
  196. data/ext/enterprise_script_service/mruby/mrbgems/mruby-symbol-ext/src/symbol.c +6 -5
  197. data/ext/enterprise_script_service/mruby/mrbgems/mruby-symbol-ext/test/symbol.rb +1 -1
  198. data/ext/enterprise_script_service/mruby/mrbgems/mruby-test/README.md +0 -1
  199. data/ext/enterprise_script_service/mruby/mrbgems/mruby-test/driver.c +5 -5
  200. data/ext/enterprise_script_service/mruby/mrbgems/mruby-test/mrbgem.rake +16 -44
  201. data/ext/enterprise_script_service/mruby/mrbgems/mruby-test/vformat.c +4 -4
  202. data/ext/enterprise_script_service/mruby/mrbgems/mruby-time/src/time.c +27 -27
  203. data/ext/enterprise_script_service/mruby/mrbgems/stdlib-ext.gembox +18 -0
  204. data/ext/enterprise_script_service/mruby/mrbgems/stdlib-io.gembox +12 -0
  205. data/ext/enterprise_script_service/mruby/mrbgems/stdlib.gembox +54 -0
  206. data/ext/enterprise_script_service/mruby/mrblib/10error.rb +4 -0
  207. data/ext/enterprise_script_service/mruby/mrblib/array.rb +17 -9
  208. data/ext/enterprise_script_service/mruby/mrblib/enum.rb +1 -1
  209. data/ext/enterprise_script_service/mruby/mrblib/hash.rb +0 -20
  210. data/ext/enterprise_script_service/mruby/mrblib/init_mrblib.c +0 -11
  211. data/ext/enterprise_script_service/mruby/mrblib/numeric.rb +36 -11
  212. data/ext/enterprise_script_service/mruby/mrblib/range.rb +25 -3
  213. data/ext/enterprise_script_service/mruby/oss-fuzz/mruby_proto_fuzzer.cpp +2 -2
  214. data/ext/enterprise_script_service/mruby/oss-fuzz/proto_to_ruby.h +1 -1
  215. data/ext/enterprise_script_service/mruby/src/array.c +43 -80
  216. data/ext/enterprise_script_service/mruby/src/backtrace.c +16 -17
  217. data/ext/enterprise_script_service/mruby/src/class.c +774 -182
  218. data/ext/enterprise_script_service/mruby/src/codedump.c +223 -198
  219. data/ext/enterprise_script_service/mruby/src/debug.c +6 -6
  220. data/ext/enterprise_script_service/mruby/src/dump.c +466 -141
  221. data/ext/enterprise_script_service/mruby/src/enum.c +1 -1
  222. data/ext/enterprise_script_service/mruby/src/error.c +36 -13
  223. data/ext/enterprise_script_service/mruby/src/etc.c +43 -34
  224. data/ext/enterprise_script_service/mruby/src/fmt_fp.c +5 -6
  225. data/ext/enterprise_script_service/mruby/src/gc.c +73 -71
  226. data/ext/enterprise_script_service/mruby/src/hash.c +1050 -707
  227. data/ext/enterprise_script_service/mruby/src/kernel.c +75 -220
  228. data/ext/enterprise_script_service/mruby/src/load.c +196 -166
  229. data/ext/enterprise_script_service/mruby/src/numeric.c +352 -314
  230. data/ext/enterprise_script_service/mruby/src/object.c +97 -90
  231. data/ext/enterprise_script_service/mruby/src/print.c +4 -3
  232. data/ext/enterprise_script_service/mruby/src/proc.c +48 -56
  233. data/ext/enterprise_script_service/mruby/src/range.c +45 -21
  234. data/ext/enterprise_script_service/mruby/src/state.c +25 -32
  235. data/ext/enterprise_script_service/mruby/src/string.c +59 -101
  236. data/ext/enterprise_script_service/mruby/src/symbol.c +121 -56
  237. data/ext/enterprise_script_service/mruby/src/value_array.h +1 -0
  238. data/ext/enterprise_script_service/mruby/src/variable.c +158 -158
  239. data/ext/enterprise_script_service/mruby/src/vm.c +617 -602
  240. data/ext/enterprise_script_service/mruby/tasks/benchmark.rake +6 -6
  241. data/ext/enterprise_script_service/mruby/tasks/bin.rake +23 -0
  242. data/ext/enterprise_script_service/mruby/tasks/core.rake +12 -0
  243. data/ext/enterprise_script_service/mruby/tasks/doc.rake +50 -38
  244. data/ext/enterprise_script_service/mruby/tasks/gitlab.rake +83 -77
  245. data/ext/enterprise_script_service/mruby/tasks/libmruby.rake +10 -1
  246. data/ext/enterprise_script_service/mruby/tasks/mrbgems.rake +13 -1
  247. data/ext/enterprise_script_service/mruby/tasks/mrblib.rake +40 -0
  248. data/ext/enterprise_script_service/mruby/tasks/presym.rake +44 -0
  249. data/ext/enterprise_script_service/mruby/tasks/test.rake +68 -0
  250. data/ext/enterprise_script_service/mruby/tasks/toolchains/gcc.rake +6 -5
  251. data/ext/enterprise_script_service/mruby/tasks/toolchains/openwrt.rake +10 -14
  252. data/ext/enterprise_script_service/mruby/tasks/toolchains/visualcpp.rake +17 -21
  253. data/ext/enterprise_script_service/mruby/test/bintest.rb +5 -5
  254. data/ext/enterprise_script_service/mruby/test/t/argumenterror.rb +16 -0
  255. data/ext/enterprise_script_service/mruby/test/t/array.rb +7 -3
  256. data/ext/enterprise_script_service/mruby/test/t/bs_literal.rb +1 -1
  257. data/ext/enterprise_script_service/mruby/test/t/float.rb +18 -8
  258. data/ext/enterprise_script_service/mruby/test/t/hash.rb +903 -281
  259. data/ext/enterprise_script_service/mruby/test/t/integer.rb +10 -38
  260. data/ext/enterprise_script_service/mruby/test/t/kernel.rb +1 -1
  261. data/ext/enterprise_script_service/mruby/test/t/literals.rb +50 -0
  262. data/ext/enterprise_script_service/mruby/test/t/module.rb +2 -2
  263. data/ext/enterprise_script_service/mruby/test/t/numeric.rb +1 -1
  264. data/ext/enterprise_script_service/mruby/test/t/range.rb +83 -1
  265. data/ext/enterprise_script_service/mruby/test/t/string.rb +4 -0
  266. data/ext/enterprise_script_service/mruby/test/t/superclass.rb +10 -10
  267. data/ext/enterprise_script_service/mruby/test/t/syntax.rb +24 -0
  268. data/ext/enterprise_script_service/mruby/test/t/vformat.rb +3 -3
  269. data/ext/enterprise_script_service/mruby_config.rb +2 -5
  270. data/ext/enterprise_script_service/mruby_engine.cpp +1 -1
  271. data/lib/script_core/version.rb +1 -1
  272. data/spec/script_core_spec.rb +13 -0
  273. metadata +61 -23
  274. data/ext/enterprise_script_service/mruby/.github/workflows/main.yml +0 -24
  275. data/ext/enterprise_script_service/mruby/TODO +0 -8
  276. data/ext/enterprise_script_service/mruby/appveyor_config.rb +0 -46
  277. data/ext/enterprise_script_service/mruby/benchmark/build_config_boxing.rb +0 -28
  278. data/ext/enterprise_script_service/mruby/examples/targets/build_config_android_arm64-v8a.rb +0 -26
  279. data/ext/enterprise_script_service/mruby/examples/targets/build_config_android_armeabi.rb +0 -26
  280. data/ext/enterprise_script_service/mruby/mrbgems/mruby-sprintf/src/kernel.c +0 -30
  281. data/ext/enterprise_script_service/mruby/mrblib/mrblib.rake +0 -18
  282. data/ext/enterprise_script_service/mruby/src/crc.c +0 -39
  283. data/ext/enterprise_script_service/mruby/src/mruby_core.rake +0 -19
@@ -4,88 +4,320 @@
4
4
  ** See Copyright Notice in mruby.h
5
5
  */
6
6
 
7
+ #include <string.h>
7
8
  #include <mruby.h>
8
9
  #include <mruby/array.h>
9
10
  #include <mruby/class.h>
10
11
  #include <mruby/hash.h>
11
12
  #include <mruby/string.h>
12
13
  #include <mruby/variable.h>
14
+ #include <mruby/presym.h>
13
15
 
14
- #ifndef MRB_WITHOUT_FLOAT
15
- /* a function to get hash value of a float number */
16
- mrb_int mrb_float_id(mrb_float f);
16
+ /*
17
+ * === Glossary
18
+ *
19
+ * [EA]
20
+ * Entry Array. Store `Hash' entries in insertion order.
21
+ *
22
+ * [AR]
23
+ * Array Table Implementation. The structure of `Hash` that doesn't have a
24
+ * hash table and linearly searches EA. It is used when `Hash` size <= 16.
25
+ *
26
+ * [IB]
27
+ * Index Buckets. The buckets of hash table, where the bucket value is EA
28
+ * index. The index is represented by variable length bits according to
29
+ * the capacity.
30
+ *
31
+ * [HT]
32
+ * Hash Table Implementation. The structure of `Hash` that has IB and is
33
+ * searched by hash table algorithm. It is used when `Hash` size > 16.
34
+ * Collision resolution strategy is open addressing method.
35
+ *
36
+ * [size]
37
+ * The number of `Hash` entries (value of `Hash#size`).
38
+ *
39
+ * [slot]
40
+ * The generic term for EA or IB elements.
41
+ *
42
+ * [active]
43
+ * The state in which a slot is recognized as a `Hash` entry.
44
+ *
45
+ * [deleted]
46
+ * The state in which a slot is marked as deleted.
47
+ *
48
+ * [used]
49
+ * The state in which a slot is active or deleted.
50
+ *
51
+ * [empty]
52
+ * The state in which a slot is not used. Capacity is equal to the sum of
53
+ * the number of used slots and the number of empty slots.
54
+ */
55
+
56
+ #define EA_N_RESERVED_INDICES 2 /* empty and deleted */
57
+ #define EA_INCREASE_RATIO 6 / 5 + 6
58
+ #define EA_MAX_INCREASE UINT16_MAX
59
+ #define EA_MAX_CAPA U32(lesser(IB_MAX_CAPA - EA_N_RESERVED_INDICES, MRB_INT_MAX))
60
+ #define IB_MAX_CAPA (U32(1) << IB_MAX_BIT)
61
+ #define IB_TYPE_BIT 32
62
+ #define IB_INIT_BIT ( \
63
+ ib_upper_bound_for(32) <= AR_MAX_SIZE ? 6 : \
64
+ ib_upper_bound_for(16) <= AR_MAX_SIZE ? 5 : \
65
+ 4 \
66
+ )
67
+ #define IB_MAX_BIT (IB_TYPE_BIT - 1)
68
+ #define AR_DEFAULT_CAPA 4
69
+ #define AR_MAX_SIZE 16
70
+ #define H_MAX_SIZE EA_MAX_CAPA
71
+
72
+ mrb_static_assert1(offsetof(struct RHash, iv) == offsetof(struct RObject, iv));
73
+ mrb_static_assert1(AR_MAX_SIZE < (1 << MRB_HASH_AR_EA_CAPA_BIT));
74
+
75
+ typedef struct hash_entry {
76
+ mrb_value key;
77
+ mrb_value val;
78
+ } hash_entry;
79
+
80
+ typedef struct hash_table {
81
+ hash_entry *ea;
82
+ #ifdef MRB_32BIT
83
+ uint32_t ea_capa;
84
+ uint32_t ea_n_used;
85
+ #endif
86
+ uint32_t ib[];
87
+ } hash_table;
88
+
89
+ typedef struct index_buckets_iter {
90
+ struct RHash *h;
91
+ uint32_t bit;
92
+ uint32_t mask;
93
+ uint32_t pos;
94
+ uint32_t ary_index;
95
+ uint32_t ea_index;
96
+ uint32_t shift1;
97
+ uint32_t shift2;
98
+ uint32_t step;
99
+ } index_buckets_iter;
100
+
101
+ /*
102
+ * `c_` :: receiver class (category)
103
+ * `n_` :: attribute name
104
+ * `t_` :: attribute type
105
+ * `p_` :: struct member path
106
+ * `k_` :: macro key
107
+ */
108
+ #define DEFINE_GETTER(c_, n_, t_, p_) \
109
+ MRB_INLINE t_ c_##_##n_(const struct RHash *h) {return h->p_;}
110
+ #define DEFINE_SETTER(c_, n_, t_, p_) \
111
+ MRB_INLINE void c_##_set_##n_(struct RHash *h, t_ v) {h->p_ = v;}
112
+ #define DEFINE_ACCESSOR(c_, n_, t_, p_) \
113
+ DEFINE_GETTER(c_, n_, t_, p_) \
114
+ DEFINE_SETTER(c_, n_, t_, p_)
115
+ #define DEFINE_FLAG_GETTER(c_, n_, t_, k_) \
116
+ MRB_INLINE t_ c_##_##n_(const struct RHash *h) { \
117
+ return (t_)((h->flags & MRB_HASH_##k_##_MASK) >> MRB_HASH_##k_##_SHIFT); \
118
+ }
119
+ #define DEFINE_FLAG_SETTER(c_, n_, t_, k_) \
120
+ MRB_INLINE void c_##_set_##n_(struct RHash *h, t_ v) { \
121
+ h->flags &= ~MRB_HASH_##k_##_MASK; \
122
+ h->flags |= v << MRB_HASH_##k_##_SHIFT; \
123
+ }
124
+ #define DEFINE_FLAG_ACCESSOR(c_, n_, t_, k_) \
125
+ DEFINE_FLAG_GETTER(c_, n_, t_, k_) \
126
+ DEFINE_FLAG_SETTER(c_, n_, t_, k_)
127
+ #define DEFINE_INCREMENTER(c_, n_) \
128
+ MRB_INLINE void c_##_inc_##n_(struct RHash *h) { \
129
+ c_##_set_##n_(h, c_##_##n_(h) + 1); \
130
+ }
131
+ #define DEFINE_DECREMENTER(c_, n_) \
132
+ MRB_INLINE void c_##_dec_##n_(struct RHash *h) { \
133
+ c_##_set_##n_(h, c_##_##n_(h) - 1); \
134
+ }
135
+ #define DEFINE_SWITCHER(n_, k_) \
136
+ MRB_INLINE void h_##n_##_on(struct RHash *h) { \
137
+ h->flags |= MRB_HASH_##k_; \
138
+ } \
139
+ MRB_INLINE void h_##n_##_off(struct RHash *h) { \
140
+ h->flags &= ~MRB_HASH_##k_; \
141
+ } \
142
+ MRB_INLINE mrb_bool h_##n_##_p(const struct RHash *h) { \
143
+ return (h->flags & MRB_HASH_##k_) == MRB_HASH_##k_; \
144
+ }
145
+
146
+ #ifdef MRB_64BIT
147
+ DEFINE_ACCESSOR(ar, ea_capa, uint32_t, ea_capa)
148
+ DEFINE_ACCESSOR(ar, ea_n_used, uint32_t, ea_n_used)
149
+ DEFINE_ACCESSOR(ht, ea_capa, uint32_t, ea_capa)
150
+ DEFINE_ACCESSOR(ht, ea_n_used, uint32_t, ea_n_used)
151
+ #else
152
+ DEFINE_FLAG_ACCESSOR(ar, ea_capa, uint32_t, AR_EA_CAPA)
153
+ DEFINE_FLAG_ACCESSOR(ar, ea_n_used, uint32_t, AR_EA_N_USED)
154
+ DEFINE_ACCESSOR(ht, ea_capa, uint32_t, ht->ea_capa)
155
+ DEFINE_ACCESSOR(ht, ea_n_used, uint32_t, ht->ea_n_used)
17
156
  #endif
157
+ DEFINE_FLAG_ACCESSOR(ib, bit, uint32_t, IB_BIT)
158
+ DEFINE_ACCESSOR(ar, size, uint32_t, size)
159
+ DEFINE_ACCESSOR(ar, ea, hash_entry*, ea)
160
+ DEFINE_DECREMENTER(ar, size)
161
+ DEFINE_ACCESSOR(ht, size, uint32_t, size)
162
+ DEFINE_ACCESSOR(ht, ea, hash_entry*, ht->ea)
163
+ DEFINE_GETTER(ht, ib, uint32_t*, ht->ib)
164
+ DEFINE_INCREMENTER(ht, size)
165
+ DEFINE_DECREMENTER(ht, size)
166
+ DEFINE_GETTER(h, size, uint32_t, size)
167
+ DEFINE_ACCESSOR(h, ht, hash_table*, ht)
168
+ DEFINE_SWITCHER(ht, HT)
169
+
170
+ #define ea_each_used(ea, n_used, entry_var, code) do { \
171
+ hash_entry *entry_var = ea, *ea_end__ = entry_var + (n_used); \
172
+ for (; entry_var < ea_end__; ++entry_var) { \
173
+ code; \
174
+ } \
175
+ } while (0)
176
+
177
+ #define ea_each(ea, size, entry_var, code) do { \
178
+ hash_entry *entry_var = ea; \
179
+ uint32_t size__ = size; \
180
+ for (; 0 < size__; ++entry_var) { \
181
+ if (entry_deleted_p(entry_var)) continue; \
182
+ --size__; \
183
+ code; \
184
+ } \
185
+ } while (0)
186
+
187
+ #define ib_cycle_by_key(mrb, h, key, it_var, code) do { \
188
+ index_buckets_iter it_var[1]; \
189
+ ib_it_init(mrb, it_var, h, key); \
190
+ for (;;) { \
191
+ ib_it_next(it_var); \
192
+ code; \
193
+ } \
194
+ } while (0)
195
+
196
+ #define ib_find_by_key(mrb, h_, key_, it_var, code) do { \
197
+ mrb_value ib_fbk_key__ = key_; \
198
+ ib_cycle_by_key(mrb, h_, ib_fbk_key__, it_var, { \
199
+ if (ib_it_empty_p(it_var)) break; \
200
+ if (ib_it_deleted_p(it_var)) continue; \
201
+ if (obj_eql(mrb, ib_fbk_key__, ib_it_entry(it_var)->key, it_var->h)) { \
202
+ code; \
203
+ break; \
204
+ } \
205
+ }); \
206
+ } while (0)
207
+
208
+ #define h_each(h, entry_var, code) do { \
209
+ struct RHash *h__ = h; \
210
+ hash_entry *h_e_ea__; \
211
+ uint32_t h_e_size__; \
212
+ h_ar_p(h) ? (h_e_ea__ = ar_ea(h__), h_e_size__ = ar_size(h__)) : \
213
+ (h_e_ea__ = ht_ea(h__), h_e_size__ = ht_size(h__)); \
214
+ ea_each(h_e_ea__, h_e_size__, entry_var, code); \
215
+ } while (0)
18
216
 
19
- #ifndef MRB_HT_INIT_SIZE
20
- #define MRB_HT_INIT_SIZE 4
217
+ /*
218
+ * `h_check_modified` raises an exception when a dangerous modification is
219
+ * made to `h` by executing `code`.
220
+ *
221
+ * This macro is not called if `h->ht` (`h->ea`) is `NULL` (`Hash` size is
222
+ * zero). And because the `hash_entry` is rather large, `h->ht->ea` and
223
+ * `h->ht->ea_capa` are able to be safely accessed even in AR. This nature
224
+ * is used to eliminate branch of AR or HT.
225
+ *
226
+ * `HT_ASSERT_SAFE_READ` checks if members can be accessed according to its
227
+ * assumptions.
228
+ */
229
+ #define HT_ASSERT_SAFE_READ(attr_name) \
230
+ mrb_static_assert1( \
231
+ offsetof(hash_table, attr_name) + sizeof(((hash_table*)0)->attr_name) <= \
232
+ sizeof(hash_entry))
233
+ HT_ASSERT_SAFE_READ(ea);
234
+ #ifdef MRB_32BIT
235
+ HT_ASSERT_SAFE_READ(ea_capa);
21
236
  #endif
22
- #define HT_SEG_INCREASE_RATIO 6 / 5
237
+ #undef HT_ASSERT_SAFE_READ
238
+ #define h_check_modified(mrb, h, code) do { \
239
+ struct RHash *h__ = h; \
240
+ uint32_t mask = MRB_HASH_HT|MRB_HASH_IB_BIT_MASK|MRB_HASH_AR_EA_CAPA_MASK; \
241
+ uint32_t flags = h__->flags & mask; \
242
+ void* tbl__ = (mrb_assert(h__->ht), h__->ht); \
243
+ uint32_t ht_ea_capa__ = ht_ea_capa(h__); \
244
+ hash_entry *ht_ea__ = ht_ea(h__); \
245
+ code; \
246
+ if (flags != (h__->flags & mask) || \
247
+ tbl__ != h__->ht || \
248
+ ht_ea_capa__ != ht_ea_capa(h__) || \
249
+ ht_ea__ != ht_ea(h__)) { \
250
+ mrb_raise(mrb, E_RUNTIME_ERROR, "hash modified"); \
251
+ } \
252
+ } while (0)
23
253
 
24
- struct segkv {
25
- mrb_value key;
26
- mrb_value val;
27
- };
28
-
29
- typedef struct segment {
30
- uint16_t size;
31
- struct segment *next;
32
- struct segkv e[];
33
- } segment;
34
-
35
- typedef struct segindex {
36
- size_t size;
37
- size_t capa;
38
- struct segkv *table[];
39
- } segindex;
40
-
41
- /* hash table structure */
42
- typedef struct htable {
43
- segment *rootseg;
44
- segment *lastseg;
45
- mrb_int size;
46
- uint16_t last_len;
47
- segindex *index;
48
- } htable;
49
-
50
- static /* inline */ size_t
51
- ht_hash_func(mrb_state *mrb, htable *t, mrb_value key)
254
+ #define U32(v) ((uint32_t)(v))
255
+ #define h_ar_p(h) (!h_ht_p(h))
256
+ #define h_ar_on(h) h_ht_off(h)
257
+ #define lesser(a, b) ((a) < (b) ? (a) : (b))
258
+ #define RHASH_IFNONE(hash) mrb_iv_get(mrb, (hash), MRB_SYM(ifnone))
259
+ #define RHASH_PROCDEFAULT(hash) RHASH_IFNONE(hash)
260
+
261
+ static uint32_t ib_upper_bound_for(uint32_t capa);
262
+ static uint32_t ib_bit_to_capa(uint32_t bit);
263
+ static void ht_init(
264
+ mrb_state *mrb, struct RHash *h, uint32_t size,
265
+ hash_entry *ea, uint32_t ea_capa, hash_table *ht, uint32_t ib_bit);
266
+ static void ht_set_without_ib_adjustment(
267
+ mrb_state *mrb, struct RHash *h, mrb_value key, mrb_value val);
268
+
269
+ static uint32_t
270
+ next_power2(uint32_t v)
52
271
  {
53
- enum mrb_vtype tt = mrb_type(key);
54
- mrb_value hv;
55
- size_t h;
56
- segindex *index = t->index;
57
- size_t capa = index ? index->capa : 0;
272
+ mrb_assert(v != 0);
273
+ #ifdef __GNUC__
274
+ return U32(1) << ((sizeof(unsigned) * CHAR_BIT) - __builtin_clz(v));
275
+ #else
276
+ v |= v >> 1;
277
+ v |= v >> 2;
278
+ v |= v >> 4;
279
+ v |= v >> 8;
280
+ v |= v >> 16;
281
+ ++v;
282
+ return v;
283
+ #endif
284
+ }
58
285
 
286
+ static uint32_t
287
+ obj_hash_code(mrb_state *mrb, mrb_value key, struct RHash *h)
288
+ {
289
+ enum mrb_vtype tt = mrb_type(key);
290
+ uint32_t hash_code;
291
+ mrb_value hash_code_obj;
59
292
  switch (tt) {
60
293
  case MRB_TT_STRING:
61
- h = mrb_str_hash(mrb, key);
294
+ hash_code = mrb_str_hash(mrb, key);
62
295
  break;
63
-
64
296
  case MRB_TT_TRUE:
65
297
  case MRB_TT_FALSE:
66
298
  case MRB_TT_SYMBOL:
67
- case MRB_TT_FIXNUM:
68
- #ifndef MRB_WITHOUT_FLOAT
299
+ case MRB_TT_INTEGER:
300
+ #ifndef MRB_NO_FLOAT
69
301
  case MRB_TT_FLOAT:
70
302
  #endif
71
- h = (size_t)mrb_obj_id(key);
303
+ hash_code = U32(mrb_obj_id(key));
72
304
  break;
73
-
74
305
  default:
75
- hv = mrb_funcall(mrb, key, "hash", 0);
76
- h = (size_t)tt ^ (size_t)mrb_fixnum(hv);
306
+ h_check_modified(mrb, h, {
307
+ hash_code_obj = mrb_funcall_argv(mrb, key, MRB_SYM(hash), 0, NULL);
308
+ });
309
+
310
+ hash_code = U32(tt) ^ U32(mrb_integer(hash_code_obj));
77
311
  break;
78
312
  }
79
- if (index && (index != t->index || capa != index->capa)) {
80
- mrb_raise(mrb, E_RUNTIME_ERROR, "hash modified");
81
- }
82
- return ((h)^((h)<<2)^((h)>>2));
313
+ return hash_code ^ (hash_code << 2) ^ (hash_code >> 2);
83
314
  }
84
315
 
85
- static inline mrb_bool
86
- ht_hash_equal(mrb_state *mrb, htable *t, mrb_value a, mrb_value b)
316
+ static mrb_bool
317
+ obj_eql(mrb_state *mrb, mrb_value a, mrb_value b, struct RHash *h)
87
318
  {
88
319
  enum mrb_vtype tt = mrb_type(a);
320
+ mrb_bool eql;
89
321
 
90
322
  switch (tt) {
91
323
  case MRB_TT_STRING:
@@ -95,609 +327,848 @@ ht_hash_equal(mrb_state *mrb, htable *t, mrb_value a, mrb_value b)
95
327
  if (!mrb_symbol_p(b)) return FALSE;
96
328
  return mrb_symbol(a) == mrb_symbol(b);
97
329
 
98
- case MRB_TT_FIXNUM:
99
- switch (mrb_type(b)) {
100
- case MRB_TT_FIXNUM:
101
- return mrb_fixnum(a) == mrb_fixnum(b);
102
- #ifndef MRB_WITHOUT_FLOAT
103
- case MRB_TT_FLOAT:
104
- return (mrb_float)mrb_fixnum(a) == mrb_float(b);
105
- #endif
106
- default:
107
- return FALSE;
108
- }
330
+ case MRB_TT_INTEGER:
331
+ if (!mrb_integer_p(b)) return FALSE;
332
+ return mrb_integer(a) == mrb_integer(b);
109
333
 
110
- #ifndef MRB_WITHOUT_FLOAT
334
+ #ifndef MRB_NO_FLOAT
111
335
  case MRB_TT_FLOAT:
112
- switch (mrb_type(b)) {
113
- case MRB_TT_FIXNUM:
114
- return mrb_float(a) == (mrb_float)mrb_fixnum(b);
115
- case MRB_TT_FLOAT:
116
- return mrb_float(a) == mrb_float(b);
117
- default:
118
- return FALSE;
119
- }
336
+ if (!mrb_float_p(b)) return FALSE;
337
+ return mrb_float(a) == mrb_float(b);
120
338
  #endif
121
339
 
122
340
  default:
123
- {
124
- segindex *index = t->index;
125
- size_t capa = index ? index->capa : 0;
126
- mrb_bool eql = mrb_eql(mrb, a, b);
127
- if (index && (index != t->index || capa != index->capa)) {
128
- mrb_raise(mrb, E_RUNTIME_ERROR, "hash modified");
129
- }
130
- return eql;
131
- }
132
- }
341
+ h_check_modified(mrb, h, {eql = mrb_eql(mrb, a, b);});
342
+ return eql;
343
+ }
133
344
  }
134
345
 
135
- /* Creates the hash table. */
136
- static htable*
137
- ht_new(mrb_state *mrb)
346
+ static mrb_bool
347
+ entry_deleted_p(const hash_entry* entry)
138
348
  {
139
- htable *t;
349
+ return mrb_undef_p(entry->key);
350
+ }
140
351
 
141
- t = (htable*)mrb_malloc(mrb, sizeof(htable));
142
- t->size = 0;
143
- t->rootseg = NULL;
144
- t->lastseg = NULL;
145
- t->last_len = 0;
146
- t->index = NULL;
352
+ static void
353
+ entry_delete(hash_entry* entry)
354
+ {
355
+ entry->key = mrb_undef_value();
356
+ }
147
357
 
148
- return t;
358
+ static uint32_t
359
+ ea_next_capa_for(uint32_t size, uint32_t max_capa)
360
+ {
361
+ if (size < AR_DEFAULT_CAPA) {
362
+ return AR_DEFAULT_CAPA;
363
+ }
364
+ else {
365
+ /*
366
+ * For 32-bit CPU, the theoretical value of maximum EA capacity is
367
+ * `UINT32_MAX / sizeof (hash_entry)`. At this time, if
368
+ * `EA_INCREASE_RATIO` is the current value, 32-bit range will not be
369
+ * exceeded during the calculation of `capa`, so `size_t` is used.
370
+ */
371
+ size_t capa = (size_t)size * EA_INCREASE_RATIO, inc = capa - size;
372
+ if (EA_MAX_INCREASE < inc) capa = size + EA_MAX_INCREASE;
373
+ return capa <= max_capa ? U32(capa) : max_capa;
374
+ }
149
375
  }
150
376
 
151
- #define power2(v) do { \
152
- v--;\
153
- v |= v >> 1;\
154
- v |= v >> 2;\
155
- v |= v >> 4;\
156
- v |= v >> 8;\
157
- v |= v >> 16;\
158
- v++;\
159
- } while (0)
377
+ static hash_entry*
378
+ ea_resize(mrb_state *mrb, hash_entry *ea, uint32_t capa)
379
+ {
380
+ return (hash_entry*)mrb_realloc(mrb, ea, sizeof(hash_entry) * capa);
381
+ }
160
382
 
161
- #ifndef UPPER_BOUND
162
- #define UPPER_BOUND(x) ((x)>>2|(x)>>1)
163
- #endif
383
+ static void
384
+ ea_compress(hash_entry *ea, uint32_t n_used)
385
+ {
386
+ hash_entry *w_entry = ea;
387
+ ea_each_used(ea, n_used, r_entry, {
388
+ if (entry_deleted_p(r_entry)) continue;
389
+ if (r_entry != w_entry) *w_entry = *r_entry;
390
+ ++w_entry;
391
+ });
392
+ }
164
393
 
165
- #define HT_MASK(index) ((index->capa)-1)
394
+ /*
395
+ * Increase or decrease capacity of `ea` to a standard size that can
396
+ * accommodate `*capap + 1` entries (but, not exceed `max_capa`). Set the
397
+ * changed capacity to `*capap` and return a pointer to `mrb_realloc`ed EA.
398
+ */
399
+ static hash_entry*
400
+ ea_adjust(mrb_state *mrb, hash_entry *ea, uint32_t *capap, uint32_t max_capa)
401
+ {
402
+ *capap = ea_next_capa_for(*capap, max_capa);
403
+ return ea_resize(mrb, ea, *capap);
404
+ }
405
+
406
+ static hash_entry*
407
+ ea_dup(mrb_state *mrb, const hash_entry *ea, uint32_t capa)
408
+ {
409
+ size_t byte_size = sizeof(hash_entry) * capa;
410
+ hash_entry *new_ea = (hash_entry*)mrb_malloc(mrb, byte_size);
411
+ return (hash_entry*)memcpy(new_ea, ea, byte_size);
412
+ }
413
+
414
+ static hash_entry*
415
+ ea_get_by_key(mrb_state *mrb, hash_entry *ea, uint32_t size, mrb_value key,
416
+ struct RHash *h)
417
+ {
418
+ ea_each(ea, size, entry, {
419
+ if (obj_eql(mrb, key, entry->key, h)) return entry;
420
+ });
421
+ return NULL;
422
+ }
423
+
424
+ static hash_entry*
425
+ ea_get(hash_entry *ea, uint32_t index)
426
+ {
427
+ return &ea[index];
428
+ }
166
429
 
167
- /* Build index for the hash table */
168
430
  static void
169
- ht_index(mrb_state *mrb, htable *t)
431
+ ea_set(hash_entry *ea, uint32_t index, mrb_value key, mrb_value val)
170
432
  {
171
- size_t size = (size_t)t->size;
172
- size_t mask;
173
- segindex *index = t->index;
174
- segment *seg;
175
- size_t i;
433
+ ea[index].key = key;
434
+ ea[index].val = val;
435
+ }
176
436
 
177
- /* allocate index table */
178
- if (index && index->size >= UPPER_BOUND(index->capa)) {
179
- size = index->capa+1;
180
- }
181
- power2(size);
182
- if (!index || index->capa < size) {
183
- index = (segindex*)mrb_realloc_simple(mrb, index, sizeof(segindex)+sizeof(struct segkv*)*size);
184
- if (index == NULL) {
185
- mrb_free(mrb, t->index);
186
- t->index = NULL;
187
- return;
188
- }
189
- t->index = index;
190
- }
191
- index->size = t->size;
192
- index->capa = size;
193
- for (i=0; i<size; i++) {
194
- index->table[i] = NULL;
195
- }
437
+ static void
438
+ ar_init(struct RHash *h, uint32_t size,
439
+ hash_entry *ea, uint32_t ea_capa, uint32_t ea_n_used)
440
+ {
441
+ h_ar_on(h);
442
+ ar_set_size(h, size);
443
+ ar_set_ea(h, ea);
444
+ ar_set_ea_capa(h, ea_capa);
445
+ ar_set_ea_n_used(h, ea_n_used);
446
+ }
196
447
 
197
- /* rebuld index */
198
- mask = HT_MASK(index);
199
- seg = t->rootseg;
200
- while (seg) {
201
- for (i=0; i<seg->size; i++) {
202
- mrb_value key;
203
- size_t k, step = 0;
448
+ static void
449
+ ar_free(mrb_state *mrb, struct RHash *h)
450
+ {
451
+ mrb_free(mrb, ar_ea(h));
452
+ }
204
453
 
205
- if (!seg->next && i >= (size_t)t->last_len) {
206
- return;
207
- }
208
- key = seg->e[i].key;
209
- if (mrb_undef_p(key)) continue;
210
- k = ht_hash_func(mrb, t, key) & mask;
211
- while (index->table[k]) {
212
- k = (k+(++step)) & mask;
213
- }
214
- index->table[k] = &seg->e[i];
215
- }
216
- seg = seg->next;
217
- }
454
+ static void
455
+ ar_adjust_ea(mrb_state *mrb, struct RHash *h, uint32_t size, uint32_t max_ea_capa)
456
+ {
457
+ uint32_t ea_capa = size;
458
+ hash_entry *ea = ea_adjust(mrb, ar_ea(h), &ea_capa, max_ea_capa);
459
+ ar_set_ea(h, ea);
460
+ ar_set_ea_capa(h, ea_capa);
218
461
  }
219
462
 
220
- /* Compacts the hash table removing deleted entries. */
221
463
  static void
222
- ht_compact(mrb_state *mrb, htable *t)
464
+ ar_compress(mrb_state *mrb, struct RHash *h)
223
465
  {
224
- segment *seg;
225
- uint16_t i, i2;
226
- segment *seg2 = NULL;
227
- mrb_int size = 0;
466
+ uint32_t size = ar_size(h);
467
+ ea_compress(ar_ea(h), ar_ea_n_used(h));
468
+ ar_set_ea_n_used(h, size);
469
+ ar_adjust_ea(mrb, h, size, lesser(ar_ea_capa(h), AR_MAX_SIZE));
470
+ }
228
471
 
229
- if (t == NULL) return;
230
- seg = t->rootseg;
231
- if (t->index && (size_t)t->size == t->index->size) {
232
- ht_index(mrb, t);
233
- return;
234
- }
235
- while (seg) {
236
- for (i=0; i<seg->size; i++) {
237
- mrb_value k = seg->e[i].key;
472
+ static mrb_bool
473
+ ar_get(mrb_state *mrb, struct RHash *h, mrb_value key, mrb_value *valp)
474
+ {
475
+ ea_each(ar_ea(h), ar_size(h), entry, {
476
+ if (!obj_eql(mrb, key, entry->key, h)) continue;
477
+ *valp = entry->val;
478
+ return TRUE;
479
+ });
480
+ return FALSE;
481
+ }
238
482
 
239
- if (!seg->next && i >= t->last_len) {
240
- goto exit;
241
- }
242
- if (mrb_undef_p(k)) { /* found deleted key */
243
- if (seg2 == NULL) {
244
- seg2 = seg;
245
- i2 = i;
483
+ static void
484
+ ar_set(mrb_state *mrb, struct RHash *h, mrb_value key, mrb_value val)
485
+ {
486
+ uint32_t size = ar_size(h);
487
+ hash_entry *entry;
488
+ if ((entry = ea_get_by_key(mrb, ar_ea(h), size, key, h))) {
489
+ entry->val = val;
490
+ }
491
+ else {
492
+ uint32_t ea_capa = ar_ea_capa(h), ea_n_used = ar_ea_n_used(h);
493
+ if (ea_capa == ea_n_used) {
494
+ if (size == ea_n_used) {
495
+ if (size == AR_MAX_SIZE) {
496
+ hash_entry *ea = ea_adjust(mrb, ar_ea(h), &ea_capa, EA_MAX_CAPA);
497
+ ea_set(ea, ea_n_used, key, val);
498
+ ht_init(mrb, h, ++size, ea, ea_capa, NULL, IB_INIT_BIT);
499
+ return;
500
+ }
501
+ else {
502
+ ar_adjust_ea(mrb, h, size, AR_MAX_SIZE);
246
503
  }
247
504
  }
248
505
  else {
249
- size++;
250
- if (seg2 != NULL) {
251
- seg2->e[i2++] = seg->e[i];
252
- if (i2 >= seg2->size) {
253
- seg2 = seg2->next;
254
- i2 = 0;
255
- }
256
- }
506
+ ar_compress(mrb, h);
507
+ ea_n_used = size;
257
508
  }
258
509
  }
259
- seg = seg->next;
510
+ ea_set(ar_ea(h), ea_n_used, key, val);
511
+ ar_set_size(h, ++size);
512
+ ar_set_ea_n_used(h, ++ea_n_used);
260
513
  }
261
- exit:
262
- /* reached at end */
263
- t->size = size;
264
- if (seg2) {
265
- seg = seg2->next;
266
- seg2->next = NULL;
267
- t->last_len = i2;
268
- t->lastseg = seg2;
269
- while (seg) {
270
- seg2 = seg->next;
271
- mrb_free(mrb, seg);
272
- seg = seg2;
514
+ }
515
+
516
+ static mrb_bool
517
+ ar_delete(mrb_state *mrb, struct RHash *h, mrb_value key, mrb_value *valp)
518
+ {
519
+ hash_entry *entry = ea_get_by_key(mrb, ar_ea(h), ar_size(h), key, h);
520
+ if (!entry) return FALSE;
521
+ *valp = entry->val;
522
+ entry_delete(entry);
523
+ ar_dec_size(h);
524
+ return TRUE;
525
+ }
526
+
527
+ static void
528
+ ar_shift(mrb_state *mrb, struct RHash *h, mrb_value *keyp, mrb_value *valp)
529
+ {
530
+ uint32_t size = ar_size(h);
531
+ ea_each(ar_ea(h), size, entry, {
532
+ *keyp = entry->key;
533
+ *valp = entry->val;
534
+ entry_delete(entry);
535
+ ar_set_size(h, --size);
536
+ return;
537
+ });
538
+ }
539
+
540
+ static void
541
+ ar_rehash(mrb_state *mrb, struct RHash *h)
542
+ {
543
+ /* see comments in `h_rehash` */
544
+ uint32_t size = ar_size(h), w_size = 0, ea_capa = ar_ea_capa(h);
545
+ hash_entry *ea = ar_ea(h), *w_entry;
546
+ ea_each(ea, size, r_entry, {
547
+ if ((w_entry = ea_get_by_key(mrb, ea, w_size, r_entry->key, h))) {
548
+ w_entry->val = r_entry->val;
549
+ ar_set_size(h, --size);
550
+ entry_delete(r_entry);
273
551
  }
274
- }
275
- if (t->index) {
276
- ht_index(mrb, t);
277
- }
552
+ else {
553
+ if (w_size != U32(r_entry - ea)) {
554
+ ea_set(ea, w_size, r_entry->key, r_entry->val);
555
+ entry_delete(r_entry);
556
+ }
557
+ ++w_size;
558
+ }
559
+ });
560
+ mrb_assert(size == w_size);
561
+ ar_set_ea_n_used(h, size);
562
+ ar_adjust_ea(mrb, h, size, ea_capa);
278
563
  }
279
564
 
280
- static segment*
281
- segment_alloc(mrb_state *mrb, segment *seg)
565
+ static uint32_t
566
+ ib_it_pos_for(index_buckets_iter *it, uint32_t v)
282
567
  {
283
- uint32_t size;
568
+ return v & it->mask;
569
+ }
284
570
 
285
- if (!seg) size = MRB_HT_INIT_SIZE;
286
- else {
287
- size = seg->size*HT_SEG_INCREASE_RATIO + 1;
288
- if (size > UINT16_MAX) size = UINT16_MAX;
289
- }
571
+ static uint32_t
572
+ ib_it_empty_value(const index_buckets_iter *it)
573
+ {
574
+ return it->mask;
575
+ }
576
+
577
+ static uint32_t
578
+ ib_it_deleted_value(const index_buckets_iter *it)
579
+ {
580
+ return it->mask - 1;
581
+ }
290
582
 
291
- seg = (segment*)mrb_malloc(mrb, sizeof(segment)+sizeof(struct segkv)*size);
292
- seg->size = size;
293
- seg->next = NULL;
583
+ static mrb_bool
584
+ ib_it_empty_p(const index_buckets_iter *it)
585
+ {
586
+ return it->ea_index == ib_it_empty_value(it);
587
+ }
294
588
 
295
- return seg;
589
+ static mrb_bool
590
+ ib_it_deleted_p(const index_buckets_iter *it)
591
+ {
592
+ return it->ea_index == ib_it_deleted_value(it);
593
+ }
594
+
595
+ static mrb_bool
596
+ ib_it_active_p(const index_buckets_iter *it)
597
+ {
598
+ return it->ea_index < ib_it_deleted_value(it);
296
599
  }
297
600
 
298
- /* Set the value for the key in the indexed table. */
299
601
  static void
300
- ht_index_put(mrb_state *mrb, htable *t, mrb_value key, mrb_value val)
602
+ ib_it_init(mrb_state *mrb, index_buckets_iter *it, struct RHash *h, mrb_value key)
301
603
  {
302
- segindex *index = t->index;
303
- size_t k, sp, step = 0, mask;
304
- segment *seg;
604
+ it->h = h;
605
+ it->bit = ib_bit(h);
606
+ it->mask = ib_bit_to_capa(it->bit) - 1;
607
+ it->pos = ib_it_pos_for(it, obj_hash_code(mrb, key, h));
608
+ it->step = 0;
609
+ }
305
610
 
306
- if (index->size >= UPPER_BOUND(index->capa)) {
307
- /* need to expand table */
308
- ht_compact(mrb, t);
309
- index = t->index;
310
- }
311
- mask = HT_MASK(index);
312
- sp = index->capa;
313
- k = ht_hash_func(mrb, t, key) & mask;
314
- while (index->table[k]) {
315
- mrb_value key2 = index->table[k]->key;
316
- if (mrb_undef_p(key2)) {
317
- if (sp == index->capa) sp = k;
318
- }
319
- else if (ht_hash_equal(mrb, t, key, key2)) {
320
- index->table[k]->val = val;
321
- return;
322
- }
323
- k = (k+(++step)) & mask;
611
+ static void
612
+ ib_it_next(index_buckets_iter *it)
613
+ {
614
+ /*
615
+ * [IB image]
616
+ *
617
+ * ary_index(1) --.
618
+ * \ .-- shift1(3) .-- shift2(29)
619
+ * pos(6) --. \ / /
620
+ * View | \ \ <-o-> <----------o---------->
621
+ * -------- +---------------------\----\--+-----------------------------+-----
622
+ * array | 0 `--. `-|--- o 1 | ...
623
+ * +---------+---------+-----+\--+-----+---------+---------+---+-----
624
+ * buckets | 0 | 1 | ... | o 6 | 7 | 8 | ...
625
+ * +---------+---------+-----+=========+---------+---------+---------
626
+ * 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| ...
627
+ * +---------+---------+-----+========*+---------+---------+---------
628
+ * <---o---> \
629
+ * \ `-- bit_pos(34)
630
+ * `-- bit(5)
631
+ */
632
+
633
+ /* Slide to handle as `capa == 32` to avoid 64-bit operations */
634
+ uint32_t slid_pos = it->pos & (IB_TYPE_BIT - 1);
635
+ uint32_t slid_bit_pos = it->bit * (slid_pos + 1) - 1;
636
+ uint32_t slid_ary_index = slid_bit_pos / IB_TYPE_BIT;
637
+ it->ary_index = slid_ary_index + it->pos / IB_TYPE_BIT * it->bit;
638
+ it->shift2 = (slid_ary_index + 1) * IB_TYPE_BIT - slid_bit_pos - 1;
639
+ it->ea_index = (ht_ib(it->h)[it->ary_index] >> it->shift2) & it->mask;
640
+ if (IB_TYPE_BIT - it->bit < it->shift2) {
641
+ it->shift1 = IB_TYPE_BIT - it->shift2;
642
+ it->ea_index |= (ht_ib(it->h)[it->ary_index - 1] << it->shift1) & it->mask;
324
643
  }
325
- if (sp < index->capa) {
326
- k = sp;
644
+ else {
645
+ it->shift1 = 0;
327
646
  }
647
+ it->pos = ib_it_pos_for(it, it->pos + (++it->step));
648
+ }
328
649
 
329
- /* put the value at the last */
330
- seg = t->lastseg;
331
- if (t->last_len < seg->size) {
332
- index->table[k] = &seg->e[t->last_len++];
333
- }
334
- else { /* append a new segment */
335
- seg->next = segment_alloc(mrb, seg);
336
- seg = seg->next;
337
- seg->next = NULL;
338
- t->lastseg = seg;
339
- t->last_len = 1;
340
- index->table[k] = &seg->e[0];
650
+ static uint32_t
651
+ ib_it_get(const index_buckets_iter *it)
652
+ {
653
+ return it->ea_index;
654
+ }
655
+
656
+ static void
657
+ ib_it_set(index_buckets_iter *it, uint32_t ea_index)
658
+ {
659
+ uint32_t mask, i;
660
+ it->ea_index = ea_index;
661
+ if (it->shift1) {
662
+ i = it->ary_index - 1;
663
+ mask = it->mask >> it->shift1;
664
+ ht_ib(it->h)[i] = (ht_ib(it->h)[i] & ~mask) | (ea_index >> it->shift1);
341
665
  }
342
- index->table[k]->key = key;
343
- index->table[k]->val = val;
344
- index->size++;
345
- t->size++;
666
+ i = it->ary_index;
667
+ mask = it->mask << it->shift2;
668
+ ht_ib(it->h)[i] = (ht_ib(it->h)[i] & ~mask) | (ea_index << it->shift2);
346
669
  }
347
670
 
348
- /* Set the value for the key in the hash table. */
349
671
  static void
350
- ht_put(mrb_state *mrb, htable *t, mrb_value key, mrb_value val)
672
+ ib_it_delete(index_buckets_iter *it)
351
673
  {
352
- segment *seg;
353
- mrb_int i, deleted = 0;
674
+ ib_it_set(it, ib_it_deleted_value(it));
675
+ }
354
676
 
355
- if (t == NULL) return;
356
- if (t->index) {
357
- ht_index_put(mrb, t, key, val);
358
- return;
359
- }
360
- seg = t->rootseg;
361
- while (seg) {
362
- for (i=0; i<seg->size; i++) {
363
- mrb_value k = seg->e[i].key;
364
- /* Found room in last segment after last_len */
365
- if (!seg->next && i >= t->last_len) {
366
- seg->e[i].key = key;
367
- seg->e[i].val = val;
368
- t->last_len = (uint16_t)i+1;
369
- t->size++;
370
- return;
371
- }
372
- if (mrb_undef_p(k)) {
373
- deleted++;
374
- continue;
375
- }
376
- if (ht_hash_equal(mrb, t, key, k)) {
377
- seg->e[i].val = val;
378
- return;
379
- }
380
- }
381
- seg = seg->next;
382
- }
383
- /* Not found */
677
+ static hash_entry*
678
+ ib_it_entry(index_buckets_iter *it)
679
+ {
680
+ return ea_get(ht_ea(it->h), it->ea_index);
681
+ }
384
682
 
385
- /* Compact if last segment has room */
386
- if (deleted > 0 && deleted > MRB_HT_INIT_SIZE) {
387
- ht_compact(mrb, t);
388
- }
389
- t->size++;
683
+ static uint32_t
684
+ ib_capa_to_bit(uint32_t capa)
685
+ {
686
+ #ifdef __GNUC__
687
+ return U32(__builtin_ctz(capa));
688
+ #else
689
+ /* http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn */
690
+ static const uint32_t MultiplyDeBruijnBitPosition2[] = {
691
+ 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
692
+ 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
693
+ };
694
+ return MultiplyDeBruijnBitPosition2[U32(capa * 0x077CB531U) >> 27];
695
+ #endif
696
+ }
390
697
 
391
- /* check if thre's room after compaction */
392
- if (t->lastseg && t->last_len < t->lastseg->size) {
393
- seg = t->lastseg;
394
- i = t->last_len;
395
- }
396
- else {
397
- /* append new segment */
398
- seg = segment_alloc(mrb, t->lastseg);
399
- i = 0;
400
- if (t->rootseg == NULL) {
401
- t->rootseg = seg;
402
- }
403
- else {
404
- t->lastseg->next = seg;
405
- }
406
- t->lastseg = seg;
407
- }
408
- seg->e[i].key = key;
409
- seg->e[i].val = val;
410
- t->last_len = (uint16_t)i+1;
411
- if (t->index == NULL && t->size > MRB_HT_INIT_SIZE*4) {
412
- ht_index(mrb, t);
413
- }
698
+ static uint32_t
699
+ ib_bit_to_capa(uint32_t bit)
700
+ {
701
+ return U32(1) << bit;
414
702
  }
415
703
 
416
- /* Get a value for a key from the indexed table. */
417
- static mrb_bool
418
- ht_index_get(mrb_state *mrb, htable *t, mrb_value key, mrb_value *vp)
419
- {
420
- segindex *index = t->index;
421
- size_t mask = HT_MASK(index);
422
- size_t k = ht_hash_func(mrb, t, key) & mask;
423
- size_t step = 0;
424
-
425
- while (index->table[k]) {
426
- mrb_value key2 = index->table[k]->key;
427
- if (!mrb_undef_p(key2) && ht_hash_equal(mrb, t, key, key2)) {
428
- if (vp) *vp = index->table[k]->val;
429
- return TRUE;
430
- }
431
- k = (k+(++step)) & mask;
432
- }
433
- return FALSE;
704
+ static uint32_t
705
+ ib_upper_bound_for(uint32_t capa)
706
+ {
707
+ return (capa >> 2) | (capa >> 1); /* 3/4 */
434
708
  }
435
709
 
436
- /* Get a value for a key from the hash table. */
437
- static mrb_bool
438
- ht_get(mrb_state *mrb, htable *t, mrb_value key, mrb_value *vp)
710
+ static uint32_t
711
+ ib_bit_for(uint32_t size)
439
712
  {
440
- segment *seg;
441
- mrb_int i;
713
+ uint32_t capa = next_power2(size);
714
+ if (capa != IB_MAX_CAPA && ib_upper_bound_for(capa) < size) capa *= 2;
715
+ return ib_capa_to_bit(capa);
716
+ }
442
717
 
443
- if (t == NULL) return FALSE;
444
- if (t->index) {
445
- return ht_index_get(mrb, t, key, vp);
446
- }
718
+ static uint32_t
719
+ ib_byte_size_for(uint32_t ib_bit)
720
+ {
721
+ uint32_t ary_size = IB_INIT_BIT == 4 ?
722
+ ib_bit_to_capa(ib_bit) * 2 / IB_TYPE_BIT * ib_bit / 2 :
723
+ ib_bit_to_capa(ib_bit) / IB_TYPE_BIT * ib_bit;
724
+ return U32(sizeof(uint32_t) * ary_size);
725
+ }
447
726
 
448
- seg = t->rootseg;
449
- while (seg) {
450
- for (i=0; i<seg->size; i++) {
451
- mrb_value k = seg->e[i].key;
727
+ static void
728
+ ib_init(mrb_state *mrb, struct RHash *h, uint32_t ib_bit, size_t ib_byte_size)
729
+ {
730
+ hash_entry *ea = ht_ea(h);
731
+ memset(ht_ib(h), 0xff, ib_byte_size);
732
+ ib_set_bit(h, ib_bit);
733
+ ea_each_used(ea, ht_ea_n_used(h), entry, {
734
+ ib_cycle_by_key(mrb, h, entry->key, it, {
735
+ if (!ib_it_empty_p(it)) continue;
736
+ ib_it_set(it, U32(entry - ea));
737
+ break;
738
+ });
739
+ });
740
+ }
452
741
 
453
- if (!seg->next && i >= t->last_len) {
454
- return FALSE;
455
- }
456
- if (mrb_undef_p(k)) continue;
457
- if (ht_hash_equal(mrb, t, key, k)) {
458
- if (vp) *vp = seg->e[i].val;
459
- return TRUE;
460
- }
461
- }
462
- seg = seg->next;
463
- }
464
- return FALSE;
742
+ static void
743
+ ht_init(mrb_state *mrb, struct RHash *h, uint32_t size,
744
+ hash_entry *ea, uint32_t ea_capa, hash_table *ht, uint32_t ib_bit)
745
+ {
746
+ size_t ib_byte_size = ib_byte_size_for(ib_bit);
747
+ size_t ht_byte_size = sizeof(hash_table) + ib_byte_size;
748
+ h_ht_on(h);
749
+ h_set_ht(h, (hash_table*)mrb_realloc(mrb, ht, ht_byte_size));
750
+ ht_set_size(h, size);
751
+ ht_set_ea(h, ea);
752
+ ht_set_ea_capa(h, ea_capa);
753
+ ht_set_ea_n_used(h, size);
754
+ ib_init(mrb, h, ib_bit, ib_byte_size);
755
+ }
756
+
757
+ static void
758
+ ht_free(mrb_state *mrb, struct RHash *h)
759
+ {
760
+ mrb_free(mrb, ht_ea(h));
761
+ mrb_free(mrb, h_ht(h));
762
+ }
763
+
764
+ static hash_table*
765
+ ht_dup(mrb_state *mrb, const struct RHash *h)
766
+ {
767
+ size_t ib_byte_size = ib_byte_size_for(ib_bit(h));
768
+ size_t ht_byte_size = sizeof(hash_table) + ib_byte_size;
769
+ hash_table *new_ht = (hash_table*)mrb_malloc(mrb, ht_byte_size);
770
+ return (hash_table*)memcpy(new_ht, h_ht(h), ht_byte_size);
771
+ }
772
+
773
+ static void
774
+ ht_adjust_ea(mrb_state *mrb, struct RHash *h, uint32_t size, uint32_t max_ea_capa)
775
+ {
776
+ uint32_t ea_capa = size;
777
+ hash_entry *ea = ea_adjust(mrb, ht_ea(h), &ea_capa, max_ea_capa);
778
+ ht_set_ea(h, ea);
779
+ ht_set_ea_capa(h, ea_capa);
780
+ }
781
+
782
+ static void
783
+ ht_to_ar(mrb_state *mrb, struct RHash *h)
784
+ {
785
+ uint32_t size = ht_size(h), ea_capa = size;
786
+ hash_entry *ea = ht_ea(h);
787
+ ea_compress(ea, ht_ea_n_used(h));
788
+ ea = ea_adjust(mrb, ea, &ea_capa, AR_MAX_SIZE);
789
+ mrb_free(mrb, h_ht(h));
790
+ ar_init(h, size, ea, ea_capa, size);
465
791
  }
466
792
 
467
- /* Deletes the value for the symbol from the hash table. */
468
- /* Deletion is done by overwriting keys by `undef`. */
469
793
  static mrb_bool
470
- ht_del(mrb_state *mrb, htable *t, mrb_value key, mrb_value *vp)
794
+ ht_get(mrb_state *mrb, struct RHash *h, mrb_value key, mrb_value *valp)
471
795
  {
472
- segment *seg;
473
- mrb_int i;
796
+ ib_find_by_key(mrb, h, key, it, {
797
+ *valp = ib_it_entry(it)->val;
798
+ return TRUE;
799
+ });
800
+ return FALSE;
801
+ }
474
802
 
475
- if (t == NULL) return FALSE;
476
- seg = t->rootseg;
477
- while (seg) {
478
- for (i=0; i<seg->size; i++) {
479
- mrb_value key2;
803
+ static void
804
+ ht_set_as_ar(mrb_state *mrb, struct RHash *h, mrb_value key, mrb_value val)
805
+ {
806
+ ht_to_ar(mrb, h);
807
+ ar_set(mrb, h, key, val);
808
+ }
480
809
 
481
- if (!seg->next && i >= t->last_len) {
482
- /* not found */
483
- return FALSE;
810
+ static void
811
+ ht_set_without_ib_adjustment(mrb_state *mrb, struct RHash *h,
812
+ mrb_value key, mrb_value val)
813
+ {
814
+ mrb_assert(ht_size(h) < ib_bit_to_capa(ib_bit(h)));
815
+ ib_cycle_by_key(mrb, h, key, it, {
816
+ if (ib_it_active_p(it)) {
817
+ if (!obj_eql(mrb, key, ib_it_entry(it)->key, h)) continue;
818
+ ib_it_entry(it)->val = val;
819
+ }
820
+ else {
821
+ uint32_t ea_n_used = ht_ea_n_used(h);
822
+ if (ea_n_used == H_MAX_SIZE) {
823
+ mrb_assert(ht_size(h) == ea_n_used);
824
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "hash too big");
484
825
  }
485
- key2 = seg->e[i].key;
486
- if (!mrb_undef_p(key2) && ht_hash_equal(mrb, t, key, key2)) {
487
- if (vp) *vp = seg->e[i].val;
488
- seg->e[i].key = mrb_undef_value();
489
- t->size--;
490
- return TRUE;
826
+ if (ea_n_used == ht_ea_capa(h)) ht_adjust_ea(mrb, h, ea_n_used, EA_MAX_CAPA);
827
+ ib_it_set(it, ea_n_used);
828
+ ea_set(ht_ea(h), ea_n_used, key, val);
829
+ ht_inc_size(h);
830
+ ht_set_ea_n_used(h, ++ea_n_used);
831
+ }
832
+ return;
833
+ });
834
+ }
835
+
836
+ static void
837
+ ht_set(mrb_state *mrb, struct RHash *h, mrb_value key, mrb_value val)
838
+ {
839
+ uint32_t size = ht_size(h);
840
+ uint32_t ib_bit_width = ib_bit(h), ib_capa = ib_bit_to_capa(ib_bit_width);
841
+ if (ib_upper_bound_for(ib_capa) <= size) {
842
+ if (size != ht_ea_n_used(h)) ea_compress(ht_ea(h), ht_ea_n_used(h));
843
+ ht_init(mrb, h, size, ht_ea(h), ht_ea_capa(h), h_ht(h), ++ib_bit_width);
844
+ }
845
+ else if (size != ht_ea_n_used(h)) {
846
+ if (ib_capa - EA_N_RESERVED_INDICES <= ht_ea_n_used(h)) goto compress;
847
+ if (ht_ea_capa(h) == ht_ea_n_used(h)) {
848
+ if (size <= AR_MAX_SIZE) {ht_set_as_ar(mrb, h, key, val); return;}
849
+ if (ea_next_capa_for(size, EA_MAX_CAPA) <= ht_ea_capa(h)) {
850
+ compress:
851
+ ea_compress(ht_ea(h), ht_ea_n_used(h));
852
+ ht_adjust_ea(mrb, h, size, ht_ea_capa(h));
853
+ ht_init(mrb, h, size, ht_ea(h), ht_ea_capa(h), h_ht(h), ib_bit_width);
491
854
  }
492
855
  }
493
- seg = seg->next;
494
856
  }
857
+ ht_set_without_ib_adjustment(mrb, h, key, val);
858
+ }
859
+
860
+ static mrb_bool
861
+ ht_delete(mrb_state *mrb, struct RHash *h, mrb_value key, mrb_value *valp)
862
+ {
863
+ ib_find_by_key(mrb, h, key, it, {
864
+ hash_entry *entry = ib_it_entry(it);
865
+ *valp = entry->val;
866
+ ib_it_delete(it);
867
+ entry_delete(entry);
868
+ ht_dec_size(h);
869
+ return TRUE;
870
+ });
495
871
  return FALSE;
496
872
  }
497
873
 
498
- /* Iterates over the hash table. */
499
874
  static void
500
- ht_foreach(mrb_state *mrb, htable *t, mrb_hash_foreach_func *func, void *p)
501
- {
502
- segment *seg;
503
- mrb_int i;
504
-
505
- if (t == NULL) return;
506
- seg = t->rootseg;
507
- while (seg) {
508
- for (i=0; i<seg->size; i++) {
509
- /* no value in last segment after last_len */
510
- if (!seg->next && i >= t->last_len) {
511
- return;
875
+ ht_shift(mrb_state *mrb, struct RHash *h, mrb_value *keyp, mrb_value *valp)
876
+ {
877
+ hash_entry *ea = ht_ea(h);
878
+ ea_each(ea, ht_size(h), entry, {
879
+ ib_cycle_by_key(mrb, h, entry->key, it, {
880
+ if (ib_it_get(it) != U32(entry - ea)) continue;
881
+ *keyp = entry->key;
882
+ *valp = entry->val;
883
+ ib_it_delete(it);
884
+ entry_delete(entry);
885
+ ht_dec_size(h);
886
+ return;
887
+ });
888
+ });
889
+ }
890
+
891
+ static void
892
+ ht_rehash(mrb_state *mrb, struct RHash *h)
893
+ {
894
+ /* see comments in `h_rehash` */
895
+ uint32_t size = ht_size(h), w_size = 0, ea_capa = ht_ea_capa(h);
896
+ hash_entry *ea = ht_ea(h);
897
+ ht_init(mrb, h, 0, ea, ea_capa, h_ht(h), ib_bit_for(size));
898
+ ht_set_size(h, size);
899
+ ht_set_ea_n_used(h, ht_ea_n_used(h));
900
+ ea_each(ea, size, r_entry, {
901
+ ib_cycle_by_key(mrb, h, r_entry->key, it, {
902
+ if (ib_it_active_p(it)) {
903
+ if (!obj_eql(mrb, r_entry->key, ib_it_entry(it)->key, h)) continue;
904
+ ib_it_entry(it)->val = r_entry->val;
905
+ ht_set_size(h, --size);
906
+ entry_delete(r_entry);
512
907
  }
513
- if (mrb_undef_p(seg->e[i].key)) continue;
514
- if ((*func)(mrb, seg->e[i].key, seg->e[i].val, p) != 0)
515
- return;
516
- }
517
- seg = seg->next;
908
+ else {
909
+ if (w_size != U32(r_entry - ea)) {
910
+ ea_set(ea, w_size, r_entry->key, r_entry->val);
911
+ entry_delete(r_entry);
912
+ }
913
+ ib_it_set(it, w_size++);
914
+ }
915
+ break;
916
+ });
917
+ });
918
+ mrb_assert(size == w_size);
919
+ ht_set_ea_n_used(h, size);
920
+ size <= AR_MAX_SIZE ? ht_to_ar(mrb, h) : ht_adjust_ea(mrb, h, size, ea_capa);
921
+ }
922
+
923
+ static mrb_value
924
+ h_key_for(mrb_state *mrb, mrb_value key)
925
+ {
926
+ if (mrb_string_p(key) && !MRB_FROZEN_P(mrb_str_ptr(key))) {
927
+ key = mrb_str_dup(mrb, key);
928
+ MRB_SET_FROZEN_FLAG(mrb_str_ptr(key));
518
929
  }
930
+ return key;
519
931
  }
520
932
 
521
- /* Iterates over the hash table. */
522
- MRB_API void
523
- mrb_hash_foreach(mrb_state *mrb, struct RHash *hash, mrb_hash_foreach_func *func, void *p)
933
+ static struct RHash*
934
+ h_alloc(mrb_state *mrb)
524
935
  {
525
- ht_foreach(mrb, hash->ht, func, p);
936
+ return (struct RHash*)mrb_obj_alloc(mrb, MRB_TT_HASH, mrb->hash_class);
526
937
  }
527
938
 
528
- /* Copy the hash table. */
529
- static htable*
530
- ht_copy(mrb_state *mrb, htable *t)
939
+ static void
940
+ h_init(struct RHash *h)
531
941
  {
532
- segment *seg;
533
- htable *t2;
534
- mrb_int i;
942
+ ar_init(h, 0, NULL, 0, 0);
943
+ }
535
944
 
536
- seg = t->rootseg;
537
- t2 = ht_new(mrb);
538
- if (t->size == 0) return t2;
945
+ static void
946
+ h_free_table(mrb_state *mrb, struct RHash *h)
947
+ {
948
+ (h_ar_p(h) ? ar_free : ht_free)(mrb, h);
949
+ }
539
950
 
540
- while (seg) {
541
- for (i=0; i<seg->size; i++) {
542
- mrb_value key = seg->e[i].key;
543
- mrb_value val = seg->e[i].val;
951
+ static void
952
+ h_clear(mrb_state *mrb, struct RHash *h)
953
+ {
954
+ h_free_table(mrb, h);
955
+ h_init(h);
956
+ }
544
957
 
545
- if ((seg->next == NULL) && (i >= t->last_len)) {
546
- return t2;
547
- }
548
- if (mrb_undef_p(key)) continue; /* skip deleted key */
549
- ht_put(mrb, t2, key, val);
550
- }
551
- seg = seg->next;
552
- }
553
- return t2;
958
+ static mrb_bool
959
+ h_get(mrb_state *mrb, struct RHash *h, mrb_value key, mrb_value *valp)
960
+ {
961
+ return (h_ar_p(h) ? ar_get : ht_get)(mrb, h, key, valp);
554
962
  }
555
963
 
556
- /* Free memory of the hash table. */
557
964
  static void
558
- ht_free(mrb_state *mrb, htable *t)
965
+ h_set(mrb_state *mrb, struct RHash *h, mrb_value key, mrb_value val)
559
966
  {
560
- segment *seg;
967
+ (h_ar_p(h) ? ar_set : ht_set)(mrb, h, key, val);
968
+ }
561
969
 
562
- if (!t) return;
563
- seg = t->rootseg;
564
- while (seg) {
565
- segment *p = seg;
566
- seg = seg->next;
567
- mrb_free(mrb, p);
568
- }
569
- if (t->index) mrb_free(mrb, t->index);
570
- mrb_free(mrb, t);
970
+ static mrb_bool
971
+ h_delete(mrb_state *mrb, struct RHash *h, mrb_value key, mrb_value *valp)
972
+ {
973
+ return (h_ar_p(h) ? ar_delete : ht_delete)(mrb, h, key, valp);
571
974
  }
572
975
 
573
- static void mrb_hash_modify(mrb_state *mrb, mrb_value hash);
976
+ /* find first element in the table, and remove it. */
977
+ static void
978
+ h_shift(mrb_state *mrb, struct RHash *h, mrb_value *keyp, mrb_value *valp)
979
+ {
980
+ (h_ar_p(h) ? ar_shift : ht_shift)(mrb, h, keyp, valp);
981
+ }
574
982
 
575
- static inline mrb_value
576
- ht_key(mrb_state *mrb, mrb_value key)
983
+ static void
984
+ h_rehash(mrb_state *mrb, struct RHash *h)
577
985
  {
578
- if (mrb_string_p(key) && !mrb_frozen_p(mrb_str_ptr(key))) {
579
- key = mrb_str_dup(mrb, key);
580
- MRB_SET_FROZEN_FLAG(mrb_str_ptr(key));
986
+ /*
987
+ * ==== Comments common to `ar_rehash` and `ht_rehash`
988
+ *
989
+ * - Because reindex (such as elimination of duplicate keys) must be
990
+ * guaranteed, it is necessary to set one by one.
991
+ *
992
+ * - To prevent EA from breaking if an exception occurs in the middle,
993
+ * delete the slot before moving when moving the entry, and update size
994
+ * at any time when overwriting.
995
+ */
996
+ (h_size(h) == 0 ? h_clear : h_ar_p(h) ? ar_rehash : ht_rehash)(mrb, h);
997
+ }
998
+
999
+ static void
1000
+ h_replace(mrb_state *mrb, struct RHash *h, struct RHash *orig_h)
1001
+ {
1002
+ uint32_t size = h_size(orig_h);
1003
+ if (size == 0) {
1004
+ h_clear(mrb, h);
1005
+ }
1006
+ else if (h_ar_p(orig_h)) {
1007
+ uint32_t ea_capa = ar_ea_capa(orig_h);
1008
+ hash_entry *ea = ea_dup(mrb, ar_ea(orig_h), ea_capa);
1009
+ h_free_table(mrb, h);
1010
+ ar_init(h, size, ea, ea_capa, ar_ea_n_used(orig_h));
1011
+ }
1012
+ else { /* HT */
1013
+ uint32_t ea_capa = ht_ea_capa(orig_h);
1014
+ hash_entry *ea = ea_dup(mrb, ht_ea(orig_h), ea_capa);
1015
+ hash_table *ht = ht_dup(mrb, orig_h);
1016
+ h_free_table(mrb, h);
1017
+ h_ht_on(h);
1018
+ h_set_ht(h, ht);
1019
+ ht_set_size(h, size);
1020
+ ht_set_ea(h, ea);
1021
+ #ifdef MRB_64BIT
1022
+ ht_set_ea_capa(h, ea_capa);
1023
+ ht_set_ea_n_used(h, ht_ea_n_used(orig_h));
1024
+ #endif
1025
+ ib_set_bit(h, ib_bit(orig_h));
581
1026
  }
582
- return key;
583
1027
  }
584
1028
 
585
- #define KEY(key) ht_key(mrb, key)
1029
+ void
1030
+ mrb_gc_mark_hash(mrb_state *mrb, struct RHash *h)
1031
+ {
1032
+ h_each(h, entry, {
1033
+ mrb_gc_mark_value(mrb, entry->key);
1034
+ mrb_gc_mark_value(mrb, entry->val);
1035
+ });
1036
+ }
586
1037
 
587
- static int
588
- hash_mark_i(mrb_state *mrb, mrb_value key, mrb_value val, void *p)
1038
+ size_t
1039
+ mrb_gc_mark_hash_size(mrb_state *mrb, struct RHash *h)
589
1040
  {
590
- mrb_gc_mark_value(mrb, key);
591
- mrb_gc_mark_value(mrb, val);
592
- return 0;
1041
+ return h_size(h) * 2;
593
1042
  }
594
1043
 
595
1044
  void
596
- mrb_gc_mark_hash(mrb_state *mrb, struct RHash *hash)
1045
+ mrb_gc_free_hash(mrb_state *mrb, struct RHash *h)
597
1046
  {
598
- ht_foreach(mrb, hash->ht, hash_mark_i, NULL);
1047
+ h_free_table(mrb, h);
599
1048
  }
600
1049
 
601
1050
  size_t
602
- mrb_gc_mark_hash_size(mrb_state *mrb, struct RHash *hash)
1051
+ mrb_hash_memsize(mrb_value self)
603
1052
  {
604
- if (!hash->ht) return 0;
605
- return hash->ht->size*2;
1053
+ struct RHash *h = mrb_hash_ptr(self);
1054
+ return mrb_obj_iv_tbl_memsize(self) +
1055
+ (h_ar_p(h) ? (ar_ea_capa(h) * sizeof(hash_entry)) :
1056
+ (ht_ea_capa(h) * sizeof(hash_entry) +
1057
+ sizeof(hash_table) +
1058
+ ib_byte_size_for(ib_bit(h))));
606
1059
  }
607
1060
 
608
- void
609
- mrb_gc_free_hash(mrb_state *mrb, struct RHash *hash)
1061
+ /* Iterates over the key/value pairs. */
1062
+ MRB_API void
1063
+ mrb_hash_foreach(mrb_state *mrb, struct RHash *h, mrb_hash_foreach_func *func, void *data)
610
1064
  {
611
- ht_free(mrb, hash->ht);
1065
+ h_each(h, entry, {
1066
+ if (func(mrb, entry->key, entry->val, data) != 0) return;
1067
+ });
612
1068
  }
613
1069
 
614
1070
  MRB_API mrb_value
615
1071
  mrb_hash_new(mrb_state *mrb)
616
1072
  {
617
- struct RHash *h;
618
-
619
- h = (struct RHash*)mrb_obj_alloc(mrb, MRB_TT_HASH, mrb->hash_class);
620
- h->ht = 0;
621
- h->iv = 0;
1073
+ struct RHash *h = h_alloc(mrb);
622
1074
  return mrb_obj_value(h);
623
1075
  }
624
1076
 
1077
+ /*
1078
+ * Set the capacity of EA and IB to minimum capacity (and appropriate load
1079
+ * factor) that does not cause expansion when inserting `capa` elements.
1080
+ */
625
1081
  MRB_API mrb_value
626
1082
  mrb_hash_new_capa(mrb_state *mrb, mrb_int capa)
627
1083
  {
628
- struct RHash *h;
629
-
630
- h = (struct RHash*)mrb_obj_alloc(mrb, MRB_TT_HASH, mrb->hash_class);
631
- /* preallocate hash table */
632
- h->ht = ht_new(mrb);
633
- /* capacity ignored */
634
- h->iv = 0;
635
- return mrb_obj_value(h);
1084
+ if (capa < 0 || EA_MAX_CAPA < capa) {
1085
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "hash too big");
1086
+ return mrb_nil_value(); /* not reached */
1087
+ }
1088
+ else if (capa == 0) {
1089
+ return mrb_hash_new(mrb);
1090
+ }
1091
+ else {
1092
+ uint32_t size = U32(capa);
1093
+ struct RHash *h = h_alloc(mrb);
1094
+ hash_entry *ea = ea_resize(mrb, NULL, size);
1095
+ if (size <= AR_MAX_SIZE) {
1096
+ ar_init(h, 0, ea, size, 0);
1097
+ }
1098
+ else {
1099
+ ht_init(mrb, h, 0, ea, size, NULL, ib_bit_for(size));
1100
+ }
1101
+ return mrb_obj_value(h);
1102
+ }
636
1103
  }
637
1104
 
638
1105
  static mrb_value mrb_hash_default(mrb_state *mrb, mrb_value hash);
639
- static mrb_value hash_default(mrb_state *mrb, mrb_value hash, mrb_value key);
640
1106
 
641
- static mrb_value
642
- mrb_hash_init_copy(mrb_state *mrb, mrb_value self)
1107
+ static void
1108
+ hash_modify(mrb_state *mrb, mrb_value hash)
643
1109
  {
644
- mrb_value orig = mrb_get_arg1(mrb);
645
- struct RHash* copy;
646
- htable *orig_h;
647
- mrb_value ifnone, vret;
1110
+ mrb_check_frozen(mrb, mrb_hash_ptr(hash));
1111
+ }
648
1112
 
649
- if (mrb_obj_equal(mrb, self, orig)) return self;
650
- if ((mrb_type(self) != mrb_type(orig)) || (mrb_obj_class(mrb, self) != mrb_obj_class(mrb, orig))) {
651
- mrb_raise(mrb, E_TYPE_ERROR, "initialize_copy should take same class object");
1113
+ static mrb_value
1114
+ hash_default(mrb_state *mrb, mrb_value hash, mrb_value key)
1115
+ {
1116
+ if (MRB_RHASH_DEFAULT_P(hash)) {
1117
+ if (MRB_RHASH_PROCDEFAULT_P(hash)) {
1118
+ return mrb_funcall_id(mrb, RHASH_PROCDEFAULT(hash), MRB_SYM(call), 2, hash, key);
1119
+ }
1120
+ else {
1121
+ return RHASH_IFNONE(hash);
1122
+ }
652
1123
  }
1124
+ return mrb_nil_value();
1125
+ }
653
1126
 
654
- orig_h = RHASH_TBL(self);
655
- copy = (struct RHash*)mrb_obj_alloc(mrb, MRB_TT_HASH, mrb->hash_class);
656
- copy->ht = ht_copy(mrb, orig_h);
657
-
658
- if (MRB_RHASH_DEFAULT_P(self)) {
659
- copy->flags |= MRB_HASH_DEFAULT;
660
- }
661
- if (MRB_RHASH_PROCDEFAULT_P(self)) {
662
- copy->flags |= MRB_HASH_PROC_DEFAULT;
1127
+ static void
1128
+ hash_replace(mrb_state *mrb, mrb_value self, mrb_value orig)
1129
+ {
1130
+ struct RHash *h = mrb_hash_ptr(self), *orig_h = mrb_hash_ptr(orig);
1131
+ uint32_t mask = MRB_HASH_DEFAULT | MRB_HASH_PROC_DEFAULT;
1132
+ mrb_sym name;
1133
+ h_replace(mrb, h, orig_h);
1134
+ name = MRB_SYM(ifnone);
1135
+ if (orig_h->flags & MRB_HASH_DEFAULT) {
1136
+ mrb_iv_set(mrb, self, name, mrb_iv_get(mrb, orig, name));
663
1137
  }
664
- vret = mrb_obj_value(copy);
665
- ifnone = RHASH_IFNONE(self);
666
- if (!mrb_nil_p(ifnone)) {
667
- mrb_iv_set(mrb, vret, mrb_intern_lit(mrb, "ifnone"), ifnone);
1138
+ else {
1139
+ mrb_iv_remove(mrb, self, name);
668
1140
  }
669
- return vret;
1141
+ h->flags &= ~mask;
1142
+ h->flags |= orig_h->flags & mask;
670
1143
  }
671
1144
 
672
- static int
673
- check_kdict_i(mrb_state *mrb, mrb_value key, mrb_value val, void *data)
1145
+ static mrb_value
1146
+ mrb_hash_init_copy(mrb_state *mrb, mrb_value self)
674
1147
  {
675
- if (!mrb_symbol_p(key)) {
676
- mrb_raise(mrb, E_ARGUMENT_ERROR, "keyword argument hash with non symbol keys");
677
- }
678
- return 0;
1148
+ mrb_value orig;
1149
+ mrb_get_args(mrb, "H", &orig);
1150
+ hash_modify(mrb, self);
1151
+ if (mrb_hash_ptr(self) != mrb_hash_ptr(orig)) hash_replace(mrb, self, orig);
1152
+ return self;
679
1153
  }
680
1154
 
681
1155
  void
682
1156
  mrb_hash_check_kdict(mrb_state *mrb, mrb_value self)
683
1157
  {
684
- htable *t;
685
-
686
- t = RHASH_TBL(self);
687
- if (!t || t->size == 0) return;
688
- ht_foreach(mrb, t, check_kdict_i, NULL);
1158
+ h_each(mrb_hash_ptr(self), entry, {
1159
+ if (mrb_symbol_p(entry->key)) continue;
1160
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "keyword argument hash with non symbol keys");
1161
+ });
689
1162
  }
690
1163
 
691
1164
  MRB_API mrb_value
692
1165
  mrb_hash_dup(mrb_state *mrb, mrb_value self)
693
1166
  {
694
- struct RHash* copy;
695
- htable *orig_h;
696
-
697
- orig_h = RHASH_TBL(self);
698
- copy = (struct RHash*)mrb_obj_alloc(mrb, MRB_TT_HASH, mrb->hash_class);
699
- copy->ht = orig_h ? ht_copy(mrb, orig_h) : NULL;
700
- return mrb_obj_value(copy);
1167
+ struct RHash* copy_h = h_alloc(mrb);
1168
+ mrb_value copy = mrb_obj_value(copy_h);
1169
+ copy_h->c = mrb_hash_ptr(self)->c;
1170
+ hash_replace(mrb, copy, self);
1171
+ return copy;
701
1172
  }
702
1173
 
703
1174
  MRB_API mrb_value
@@ -706,11 +1177,11 @@ mrb_hash_get(mrb_state *mrb, mrb_value hash, mrb_value key)
706
1177
  mrb_value val;
707
1178
  mrb_sym mid;
708
1179
 
709
- if (ht_get(mrb, RHASH_TBL(hash), key, &val)) {
1180
+ if (h_get(mrb, mrb_hash_ptr(hash), key, &val)) {
710
1181
  return val;
711
1182
  }
712
1183
 
713
- mid = mrb_intern_lit(mrb, "default");
1184
+ mid = MRB_SYM(default);
714
1185
  if (mrb_func_basic_p(mrb, hash, mid, mrb_hash_default)) {
715
1186
  return hash_default(mrb, hash, key);
716
1187
  }
@@ -723,7 +1194,7 @@ mrb_hash_fetch(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value def)
723
1194
  {
724
1195
  mrb_value val;
725
1196
 
726
- if (ht_get(mrb, RHASH_TBL(hash), key, &val)) {
1197
+ if (h_get(mrb, mrb_hash_ptr(hash), key, &val)) {
727
1198
  return val;
728
1199
  }
729
1200
  /* not found */
@@ -733,22 +1204,11 @@ mrb_hash_fetch(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value def)
733
1204
  MRB_API void
734
1205
  mrb_hash_set(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value val)
735
1206
  {
736
- mrb_hash_modify(mrb, hash);
737
-
738
- key = KEY(key);
739
- ht_put(mrb, RHASH_TBL(hash), key, val);
740
- mrb_field_write_barrier_value(mrb, (struct RBasic*)RHASH(hash), key);
741
- mrb_field_write_barrier_value(mrb, (struct RBasic*)RHASH(hash), val);
742
- return;
743
- }
744
-
745
- static void
746
- mrb_hash_modify(mrb_state *mrb, mrb_value hash)
747
- {
748
- mrb_check_frozen(mrb, mrb_hash_ptr(hash));
749
- if (!RHASH_TBL(hash)) {
750
- RHASH_TBL(hash) = ht_new(mrb);
751
- }
1207
+ hash_modify(mrb, hash);
1208
+ key = h_key_for(mrb, key);
1209
+ h_set(mrb, mrb_hash_ptr(hash), key, val);
1210
+ mrb_field_write_barrier_value(mrb, mrb_basic_ptr(hash), key);
1211
+ mrb_field_write_barrier_value(mrb, mrb_basic_ptr(hash), val);
752
1212
  }
753
1213
 
754
1214
  /* 15.2.13.4.16 */
@@ -795,7 +1255,7 @@ mrb_hash_init(mrb_state *mrb, mrb_value hash)
795
1255
 
796
1256
  ifnone = mrb_nil_value();
797
1257
  mrb_get_args(mrb, "&|o?", &block, &ifnone, &ifnone_p);
798
- mrb_hash_modify(mrb, hash);
1258
+ hash_modify(mrb, hash);
799
1259
  if (!mrb_nil_p(block)) {
800
1260
  if (ifnone_p) {
801
1261
  mrb_argnum_error(mrb, 1, 0, 0);
@@ -805,7 +1265,7 @@ mrb_hash_init(mrb_state *mrb, mrb_value hash)
805
1265
  }
806
1266
  if (!mrb_nil_p(ifnone)) {
807
1267
  RHASH(hash)->flags |= MRB_HASH_DEFAULT;
808
- mrb_iv_set(mrb, hash, mrb_intern_lit(mrb, "ifnone"), ifnone);
1268
+ mrb_iv_set(mrb, hash, MRB_SYM(ifnone), ifnone);
809
1269
  }
810
1270
  return hash;
811
1271
  }
@@ -832,20 +1292,6 @@ mrb_hash_aget(mrb_state *mrb, mrb_value self)
832
1292
  return mrb_hash_get(mrb, self, key);
833
1293
  }
834
1294
 
835
- static mrb_value
836
- hash_default(mrb_state *mrb, mrb_value hash, mrb_value key)
837
- {
838
- if (MRB_RHASH_DEFAULT_P(hash)) {
839
- if (MRB_RHASH_PROCDEFAULT_P(hash)) {
840
- return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, key);
841
- }
842
- else {
843
- return RHASH_IFNONE(hash);
844
- }
845
- }
846
- return mrb_nil_value();
847
- }
848
-
849
1295
  /* 15.2.13.4.5 */
850
1296
  /*
851
1297
  * call-seq:
@@ -878,7 +1324,7 @@ mrb_hash_default(mrb_state *mrb, mrb_value hash)
878
1324
  if (MRB_RHASH_DEFAULT_P(hash)) {
879
1325
  if (MRB_RHASH_PROCDEFAULT_P(hash)) {
880
1326
  if (!given) return mrb_nil_value();
881
- return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, key);
1327
+ return mrb_funcall_id(mrb, RHASH_PROCDEFAULT(hash), MRB_SYM(call), 2, hash, key);
882
1328
  }
883
1329
  else {
884
1330
  return RHASH_IFNONE(hash);
@@ -913,8 +1359,8 @@ mrb_hash_set_default(mrb_state *mrb, mrb_value hash)
913
1359
  {
914
1360
  mrb_value ifnone = mrb_get_arg1(mrb);
915
1361
 
916
- mrb_hash_modify(mrb, hash);
917
- mrb_iv_set(mrb, hash, mrb_intern_lit(mrb, "ifnone"), ifnone);
1362
+ hash_modify(mrb, hash);
1363
+ mrb_iv_set(mrb, hash, MRB_SYM(ifnone), ifnone);
918
1364
  RHASH(hash)->flags &= ~MRB_HASH_PROC_DEFAULT;
919
1365
  if (!mrb_nil_p(ifnone)) {
920
1366
  RHASH(hash)->flags |= MRB_HASH_DEFAULT;
@@ -940,7 +1386,6 @@ mrb_hash_set_default(mrb_state *mrb, mrb_value hash)
940
1386
  * a #=> [nil, nil, 4]
941
1387
  */
942
1388
 
943
-
944
1389
  static mrb_value
945
1390
  mrb_hash_default_proc(mrb_state *mrb, mrb_value hash)
946
1391
  {
@@ -968,8 +1413,8 @@ mrb_hash_set_default_proc(mrb_state *mrb, mrb_value hash)
968
1413
  {
969
1414
  mrb_value ifnone = mrb_get_arg1(mrb);
970
1415
 
971
- mrb_hash_modify(mrb, hash);
972
- mrb_iv_set(mrb, hash, mrb_intern_lit(mrb, "ifnone"), ifnone);
1416
+ hash_modify(mrb, hash);
1417
+ mrb_iv_set(mrb, hash, MRB_SYM(ifnone), ifnone);
973
1418
  if (!mrb_nil_p(ifnone)) {
974
1419
  RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT;
975
1420
  RHASH(hash)->flags |= MRB_HASH_DEFAULT;
@@ -985,10 +1430,10 @@ mrb_hash_set_default_proc(mrb_state *mrb, mrb_value hash)
985
1430
  MRB_API mrb_value
986
1431
  mrb_hash_delete_key(mrb_state *mrb, mrb_value hash, mrb_value key)
987
1432
  {
988
- htable *t = RHASH_TBL(hash);
989
1433
  mrb_value del_val;
990
1434
 
991
- if (ht_del(mrb, t, key, &del_val)) {
1435
+ hash_modify(mrb, hash);
1436
+ if (h_delete(mrb, mrb_hash_ptr(hash), key, &del_val)) {
992
1437
  return del_val;
993
1438
  }
994
1439
 
@@ -1000,38 +1445,9 @@ static mrb_value
1000
1445
  mrb_hash_delete(mrb_state *mrb, mrb_value self)
1001
1446
  {
1002
1447
  mrb_value key = mrb_get_arg1(mrb);
1003
-
1004
- mrb_hash_modify(mrb, self);
1005
1448
  return mrb_hash_delete_key(mrb, self, key);
1006
1449
  }
1007
1450
 
1008
- /* find first element in the hash table, and remove it. */
1009
- static void
1010
- ht_shift(mrb_state *mrb, htable *t, mrb_value *kp, mrb_value *vp)
1011
- {
1012
- segment *seg = t->rootseg;
1013
- mrb_int i;
1014
-
1015
- while (seg) {
1016
- for (i=0; i<seg->size; i++) {
1017
- mrb_value key;
1018
-
1019
- if (!seg->next && i >= t->last_len) {
1020
- return;
1021
- }
1022
- key = seg->e[i].key;
1023
- if (mrb_undef_p(key)) continue;
1024
- *kp = key;
1025
- *vp = seg->e[i].val;
1026
- /* delete element */
1027
- seg->e[i].key = mrb_undef_value();
1028
- t->size--;
1029
- return;
1030
- }
1031
- seg = seg->next;
1032
- }
1033
- }
1034
-
1035
1451
  /* 15.2.13.4.24 */
1036
1452
  /*
1037
1453
  * call-seq:
@@ -1049,27 +1465,19 @@ ht_shift(mrb_state *mrb, htable *t, mrb_value *kp, mrb_value *vp)
1049
1465
  static mrb_value
1050
1466
  mrb_hash_shift(mrb_state *mrb, mrb_value hash)
1051
1467
  {
1052
- htable *t = RHASH_TBL(hash);
1468
+ struct RHash *h = mrb_hash_ptr(hash);
1053
1469
 
1054
- mrb_hash_modify(mrb, hash);
1055
- if (t && t->size > 0) {
1470
+ hash_modify(mrb, hash);
1471
+ if (h_size(h) == 0) {
1472
+ return hash_default(mrb, hash, mrb_nil_value());
1473
+ }
1474
+ else {
1056
1475
  mrb_value del_key, del_val;
1057
-
1058
- ht_shift(mrb, t, &del_key, &del_val);
1476
+ h_shift(mrb, h, &del_key, &del_val);
1059
1477
  mrb_gc_protect(mrb, del_key);
1060
1478
  mrb_gc_protect(mrb, del_val);
1061
1479
  return mrb_assoc_new(mrb, del_key, del_val);
1062
1480
  }
1063
-
1064
- if (MRB_RHASH_DEFAULT_P(hash)) {
1065
- if (MRB_RHASH_PROCDEFAULT_P(hash)) {
1066
- return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, mrb_nil_value());
1067
- }
1068
- else {
1069
- return RHASH_IFNONE(hash);
1070
- }
1071
- }
1072
- return mrb_nil_value();
1073
1481
  }
1074
1482
 
1075
1483
  /* 15.2.13.4.4 */
@@ -1087,13 +1495,8 @@ mrb_hash_shift(mrb_state *mrb, mrb_value hash)
1087
1495
  MRB_API mrb_value
1088
1496
  mrb_hash_clear(mrb_state *mrb, mrb_value hash)
1089
1497
  {
1090
- htable *t = RHASH_TBL(hash);
1091
-
1092
- mrb_hash_modify(mrb, hash);
1093
- if (t) {
1094
- ht_free(mrb, t);
1095
- RHASH_TBL(hash) = NULL;
1096
- }
1498
+ hash_modify(mrb, hash);
1499
+ h_clear(mrb, mrb_hash_ptr(hash));
1097
1500
  return hash;
1098
1501
  }
1099
1502
 
@@ -1129,18 +1532,15 @@ mrb_hash_aset(mrb_state *mrb, mrb_value self)
1129
1532
  MRB_API mrb_int
1130
1533
  mrb_hash_size(mrb_state *mrb, mrb_value hash)
1131
1534
  {
1132
- htable *t = RHASH_TBL(hash);
1133
-
1134
- if (!t) return 0;
1135
- return t->size;
1535
+ return (mrb_int)h_size(mrb_hash_ptr(hash));
1136
1536
  }
1137
1537
 
1138
1538
  /* 15.2.13.4.20 */
1139
1539
  /* 15.2.13.4.25 */
1140
1540
  /*
1141
1541
  * call-seq:
1142
- * hsh.length -> fixnum
1143
- * hsh.size -> fixnum
1542
+ * hsh.length -> integer
1543
+ * hsh.size -> integer
1144
1544
  *
1145
1545
  * Returns the number of key-value pairs in the hash.
1146
1546
  *
@@ -1153,16 +1553,13 @@ static mrb_value
1153
1553
  mrb_hash_size_m(mrb_state *mrb, mrb_value self)
1154
1554
  {
1155
1555
  mrb_int size = mrb_hash_size(mrb, self);
1156
- return mrb_fixnum_value(size);
1556
+ return mrb_int_value(mrb, size);
1157
1557
  }
1158
1558
 
1159
1559
  MRB_API mrb_bool
1160
1560
  mrb_hash_empty_p(mrb_state *mrb, mrb_value self)
1161
1561
  {
1162
- htable *t = RHASH_TBL(self);
1163
-
1164
- if (!t) return TRUE;
1165
- return t->size == 0;
1562
+ return h_size(mrb_hash_ptr(self)) == 0;
1166
1563
  }
1167
1564
 
1168
1565
  /* 15.2.13.4.12 */
@@ -1181,13 +1578,6 @@ mrb_hash_empty_m(mrb_state *mrb, mrb_value self)
1181
1578
  return mrb_bool_value(mrb_hash_empty_p(mrb, self));
1182
1579
  }
1183
1580
 
1184
- static int
1185
- hash_keys_i(mrb_state *mrb, mrb_value key, mrb_value val, void *p)
1186
- {
1187
- mrb_ary_push(mrb, *(mrb_value*)p, key);
1188
- return 0;
1189
- }
1190
-
1191
1581
  /* 15.2.13.4.19 */
1192
1582
  /*
1193
1583
  * call-seq:
@@ -1204,24 +1594,14 @@ hash_keys_i(mrb_state *mrb, mrb_value key, mrb_value val, void *p)
1204
1594
  MRB_API mrb_value
1205
1595
  mrb_hash_keys(mrb_state *mrb, mrb_value hash)
1206
1596
  {
1207
- htable *t = RHASH_TBL(hash);
1208
- mrb_int size;
1209
- mrb_value ary;
1210
-
1211
- if (!t || (size = t->size) == 0)
1212
- return mrb_ary_new(mrb);
1213
- ary = mrb_ary_new_capa(mrb, size);
1214
- ht_foreach(mrb, t, hash_keys_i, (void*)&ary);
1597
+ struct RHash *h = mrb_hash_ptr(hash);
1598
+ mrb_value ary = mrb_ary_new_capa(mrb, (mrb_int)h_size(h));
1599
+ h_each(h, entry, {
1600
+ mrb_ary_push(mrb, ary, entry->key);
1601
+ });
1215
1602
  return ary;
1216
1603
  }
1217
1604
 
1218
- static int
1219
- hash_vals_i(mrb_state *mrb, mrb_value key, mrb_value val, void *p)
1220
- {
1221
- mrb_ary_push(mrb, *(mrb_value*)p, val);
1222
- return 0;
1223
- }
1224
-
1225
1605
  /* 15.2.13.4.28 */
1226
1606
  /*
1227
1607
  * call-seq:
@@ -1238,14 +1618,11 @@ hash_vals_i(mrb_state *mrb, mrb_value key, mrb_value val, void *p)
1238
1618
  MRB_API mrb_value
1239
1619
  mrb_hash_values(mrb_state *mrb, mrb_value hash)
1240
1620
  {
1241
- htable *t = RHASH_TBL(hash);
1242
- mrb_int size;
1243
- mrb_value ary;
1244
-
1245
- if (!t || (size = t->size) == 0)
1246
- return mrb_ary_new(mrb);
1247
- ary = mrb_ary_new_capa(mrb, size);
1248
- ht_foreach(mrb, t, hash_vals_i, (void*)&ary);
1621
+ struct RHash *h = mrb_hash_ptr(hash);
1622
+ mrb_value ary = mrb_ary_new_capa(mrb, (mrb_int)h_size(h));
1623
+ h_each(h, entry, {
1624
+ mrb_ary_push(mrb, ary, entry->val);
1625
+ });
1249
1626
  return ary;
1250
1627
  }
1251
1628
 
@@ -1271,13 +1648,8 @@ mrb_hash_values(mrb_state *mrb, mrb_value hash)
1271
1648
  MRB_API mrb_bool
1272
1649
  mrb_hash_key_p(mrb_state *mrb, mrb_value hash, mrb_value key)
1273
1650
  {
1274
- htable *t;
1275
-
1276
- t = RHASH_TBL(hash);
1277
- if (ht_get(mrb, t, key, NULL)) {
1278
- return TRUE;
1279
- }
1280
- return FALSE;
1651
+ mrb_value val;
1652
+ return h_get(mrb, mrb_hash_ptr(hash), key, &val);
1281
1653
  }
1282
1654
 
1283
1655
  static mrb_value
@@ -1290,23 +1662,6 @@ mrb_hash_has_key(mrb_state *mrb, mrb_value hash)
1290
1662
  return mrb_bool_value(key_p);
1291
1663
  }
1292
1664
 
1293
- struct has_v_arg {
1294
- mrb_bool found;
1295
- mrb_value val;
1296
- };
1297
-
1298
- static int
1299
- hash_has_value_i(mrb_state *mrb, mrb_value key, mrb_value val, void *p)
1300
- {
1301
- struct has_v_arg *arg = (struct has_v_arg*)p;
1302
-
1303
- if (mrb_equal(mrb, arg->val, val)) {
1304
- arg->found = TRUE;
1305
- return 1;
1306
- }
1307
- return 0;
1308
- }
1309
-
1310
1665
  /* 15.2.13.4.14 */
1311
1666
  /* 15.2.13.4.27 */
1312
1667
  /*
@@ -1326,41 +1681,32 @@ static mrb_value
1326
1681
  mrb_hash_has_value(mrb_state *mrb, mrb_value hash)
1327
1682
  {
1328
1683
  mrb_value val = mrb_get_arg1(mrb);
1329
- struct has_v_arg arg;
1330
-
1331
- arg.found = FALSE;
1332
- arg.val = val;
1333
- ht_foreach(mrb, RHASH_TBL(hash), hash_has_value_i, &arg);
1334
- return mrb_bool_value(arg.found);
1335
- }
1336
-
1337
- static int
1338
- merge_i(mrb_state *mrb, mrb_value key, mrb_value val, void *data)
1339
- {
1340
- htable *h1 = (htable*)data;
1341
-
1342
- ht_put(mrb, h1, key, val);
1343
- return 0;
1684
+ struct RHash *h = mrb_hash_ptr(hash);
1685
+ h_each(h, entry, {
1686
+ h_check_modified(mrb, h, {
1687
+ if (mrb_equal(mrb, val, entry->val)) return mrb_true_value();
1688
+ });
1689
+ });
1690
+ return mrb_false_value();
1344
1691
  }
1345
1692
 
1346
1693
  MRB_API void
1347
1694
  mrb_hash_merge(mrb_state *mrb, mrb_value hash1, mrb_value hash2)
1348
1695
  {
1349
- htable *h1, *h2;
1350
-
1351
- mrb_hash_modify(mrb, hash1);
1352
- hash2 = mrb_ensure_hash_type(mrb, hash2);
1353
- h1 = RHASH_TBL(hash1);
1354
- h2 = RHASH_TBL(hash2);
1355
-
1356
- if (!h2) return;
1357
- if (!h1) {
1358
- RHASH_TBL(hash1) = ht_copy(mrb, h2);
1359
- return;
1360
- }
1361
- ht_foreach(mrb, h2, merge_i, h1);
1362
- mrb_write_barrier(mrb, (struct RBasic*)RHASH(hash1));
1363
- return;
1696
+ struct RHash *h1, *h2;
1697
+
1698
+ hash_modify(mrb, hash1);
1699
+ mrb_ensure_hash_type(mrb, hash2);
1700
+ h1 = mrb_hash_ptr(hash1);
1701
+ h2 = mrb_hash_ptr(hash2);
1702
+
1703
+ if (h1 == h2) return;
1704
+ if (h_size(h2) == 0) return;
1705
+ h_each(h2, entry, {
1706
+ h_check_modified(mrb, h2, {h_set(mrb, h1, entry->key, entry->val);});
1707
+ mrb_field_write_barrier_value(mrb, (struct RBasic *)h1, entry->key);
1708
+ mrb_field_write_barrier_value(mrb, (struct RBasic *)h1, entry->val);
1709
+ });
1364
1710
  }
1365
1711
 
1366
1712
  /*
@@ -1375,14 +1721,10 @@ mrb_hash_merge(mrb_state *mrb, mrb_value hash1, mrb_value hash2)
1375
1721
  * k = keys[0]
1376
1722
  * h = {}
1377
1723
  * keys.each{|key| h[key] = key[0]}
1378
- * h #=> { [1]=> 1, [2]=> 2, [3]=> 3, [4]=> 4, [5]=> 5, [6]=> 6, [7]=> 7,
1379
- * [8]=> 8, [9]=> 9,[10]=>10,[11]=>11,[12]=>12,[13]=>13,[14]=>14,
1380
- * [15]=>15,[16]=>16,[17]=>17}
1724
+ * h #=> { [1]=>1, [2]=>2, ... [16]=>16, [17]=>17}
1381
1725
  * h[k] #=> 1
1382
1726
  * k[0] = keys.size + 1
1383
- * h #=> {[18]=> 1, [2]=> 2, [3]=> 3, [4]=> 4, [5]=> 5, [6]=> 6, [7]=> 7,
1384
- * [8]=> 8, [9]=> 9,[10]=>10,[11]=>11,[12]=>12,[13]=>13,[14]=>14,
1385
- * [15]=>15,[16]=>16,[17]=>17}
1727
+ * h #=> {[18]=>1, [2]=>2, ... [16]=>16, [17]=>17}
1386
1728
  * h[k] #=> nil
1387
1729
  * h.rehash
1388
1730
  * h[k] #=> 1
@@ -1390,7 +1732,7 @@ mrb_hash_merge(mrb_state *mrb, mrb_value hash1, mrb_value hash2)
1390
1732
  static mrb_value
1391
1733
  mrb_hash_rehash(mrb_state *mrb, mrb_value self)
1392
1734
  {
1393
- ht_compact(mrb, RHASH_TBL(self));
1735
+ h_rehash(mrb, mrb_hash_ptr(self));
1394
1736
  return self;
1395
1737
  }
1396
1738
 
@@ -1402,11 +1744,10 @@ mrb_init_hash(mrb_state *mrb)
1402
1744
  mrb->hash_class = h = mrb_define_class(mrb, "Hash", mrb->object_class); /* 15.2.13 */
1403
1745
  MRB_SET_INSTANCE_TT(h, MRB_TT_HASH);
1404
1746
 
1405
- mrb_define_method(mrb, h, "initialize_copy", mrb_hash_init_copy, MRB_ARGS_REQ(1));
1406
1747
  mrb_define_method(mrb, h, "[]", mrb_hash_aget, MRB_ARGS_REQ(1)); /* 15.2.13.4.2 */
1407
1748
  mrb_define_method(mrb, h, "[]=", mrb_hash_aset, MRB_ARGS_REQ(2)); /* 15.2.13.4.3 */
1408
1749
  mrb_define_method(mrb, h, "clear", mrb_hash_clear, MRB_ARGS_NONE()); /* 15.2.13.4.4 */
1409
- mrb_define_method(mrb, h, "default", mrb_hash_default, MRB_ARGS_OPT(1)); /* 15.2.13.4.5 */
1750
+ mrb_define_method(mrb, h, "default", mrb_hash_default, MRB_ARGS_OPT(1)); /* 15.2.13.4.5 */
1410
1751
  mrb_define_method(mrb, h, "default=", mrb_hash_set_default, MRB_ARGS_REQ(1)); /* 15.2.13.4.6 */
1411
1752
  mrb_define_method(mrb, h, "default_proc", mrb_hash_default_proc,MRB_ARGS_NONE()); /* 15.2.13.4.7 */
1412
1753
  mrb_define_method(mrb, h, "default_proc=", mrb_hash_set_default_proc,MRB_ARGS_REQ(1)); /* 15.2.13.4.7 */
@@ -1416,10 +1757,12 @@ mrb_init_hash(mrb_state *mrb)
1416
1757
  mrb_define_method(mrb, h, "has_value?", mrb_hash_has_value, MRB_ARGS_REQ(1)); /* 15.2.13.4.14 */
1417
1758
  mrb_define_method(mrb, h, "include?", mrb_hash_has_key, MRB_ARGS_REQ(1)); /* 15.2.13.4.15 */
1418
1759
  mrb_define_method(mrb, h, "initialize", mrb_hash_init, MRB_ARGS_OPT(1)|MRB_ARGS_BLOCK()); /* 15.2.13.4.16 */
1760
+ mrb_define_method(mrb, h, "initialize_copy", mrb_hash_init_copy, MRB_ARGS_REQ(1)); /* 15.2.13.4.17 */
1419
1761
  mrb_define_method(mrb, h, "key?", mrb_hash_has_key, MRB_ARGS_REQ(1)); /* 15.2.13.4.18 */
1420
1762
  mrb_define_method(mrb, h, "keys", mrb_hash_keys, MRB_ARGS_NONE()); /* 15.2.13.4.19 */
1421
1763
  mrb_define_method(mrb, h, "length", mrb_hash_size_m, MRB_ARGS_NONE()); /* 15.2.13.4.20 */
1422
1764
  mrb_define_method(mrb, h, "member?", mrb_hash_has_key, MRB_ARGS_REQ(1)); /* 15.2.13.4.21 */
1765
+ mrb_define_method(mrb, h, "replace", mrb_hash_init_copy, MRB_ARGS_REQ(1)); /* 15.2.13.4.23 */
1423
1766
  mrb_define_method(mrb, h, "shift", mrb_hash_shift, MRB_ARGS_NONE()); /* 15.2.13.4.24 */
1424
1767
  mrb_define_method(mrb, h, "size", mrb_hash_size_m, MRB_ARGS_NONE()); /* 15.2.13.4.25 */
1425
1768
  mrb_define_method(mrb, h, "store", mrb_hash_aset, MRB_ARGS_REQ(2)); /* 15.2.13.4.26 */