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.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/Gemfile +2 -2
- data/ext/enterprise_script_service/Rakefile +1 -1
- data/ext/enterprise_script_service/mruby/.github/workflows/build.yml +117 -74
- data/ext/enterprise_script_service/mruby/.github/workflows/codeql-analysis.yml +41 -37
- data/ext/enterprise_script_service/mruby/.github/workflows/lint.yml +23 -0
- data/ext/enterprise_script_service/mruby/.github/workflows/oss-fuzz.yml +27 -0
- data/ext/enterprise_script_service/mruby/.github/workflows/spell-checker.yml +17 -0
- data/ext/enterprise_script_service/mruby/.gitlab-ci.yml +3 -3
- data/ext/enterprise_script_service/mruby/.markdownlint.yml +16 -0
- data/ext/enterprise_script_service/mruby/.travis.yml +2 -2
- data/ext/enterprise_script_service/mruby/.yamllint +8 -0
- data/ext/enterprise_script_service/mruby/AUTHORS +3 -0
- data/ext/enterprise_script_service/mruby/CODEOWNERS +1 -0
- data/ext/enterprise_script_service/mruby/CONTRIBUTING.md +6 -13
- data/ext/enterprise_script_service/mruby/Doxyfile +4 -4
- data/ext/enterprise_script_service/mruby/LICENSE +1 -1
- data/ext/enterprise_script_service/mruby/Makefile +1 -1
- data/ext/enterprise_script_service/mruby/README.md +4 -14
- data/ext/enterprise_script_service/mruby/Rakefile +18 -108
- data/ext/enterprise_script_service/mruby/TODO.md +17 -0
- data/ext/enterprise_script_service/mruby/appveyor.yml +31 -25
- data/ext/enterprise_script_service/mruby/benchmark/bm_ao_render.rb +1 -1
- data/ext/enterprise_script_service/mruby/build_config.rb +9 -152
- data/ext/enterprise_script_service/mruby/{examples/targets/build_config_ArduinoDue.rb → build_config/ArduinoDue.rb} +2 -19
- data/ext/enterprise_script_service/mruby/{examples/targets/build_config_IntelEdison.rb → build_config/IntelEdison.rb} +2 -2
- data/ext/enterprise_script_service/mruby/{examples/targets/build_config_IntelGalileo.rb → build_config/IntelGalileo.rb} +1 -18
- data/ext/enterprise_script_service/mruby/{examples/targets/build_config_RX630.rb → build_config/RX630.rb} +2 -19
- data/ext/enterprise_script_service/mruby/build_config/android_arm64-v8a.rb +11 -0
- data/ext/enterprise_script_service/mruby/build_config/android_armeabi.rb +11 -0
- 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
- data/ext/enterprise_script_service/mruby/build_config/bench.rb +11 -0
- data/ext/enterprise_script_service/mruby/build_config/boxing.rb +21 -0
- data/ext/enterprise_script_service/mruby/{examples/targets/build_config_chipKITMax32.rb → build_config/chipKITMax32.rb} +2 -19
- data/ext/enterprise_script_service/mruby/{travis_config.rb → build_config/ci/gcc-clang.rb} +10 -10
- data/ext/enterprise_script_service/mruby/build_config/ci/msvc.rb +20 -0
- data/ext/enterprise_script_service/mruby/build_config/clang-asan.rb +11 -0
- data/ext/enterprise_script_service/mruby/build_config/cross-32bit.rb +14 -0
- data/ext/enterprise_script_service/mruby/build_config/default.rb +80 -0
- data/ext/enterprise_script_service/mruby/{examples/targets/build_config_dreamcast_shelf.rb → build_config/dreamcast_shelf.rb} +5 -19
- data/ext/enterprise_script_service/mruby/build_config/gameboyadvance.rb +73 -0
- data/ext/enterprise_script_service/mruby/build_config/host-cxx.rb +12 -0
- data/ext/enterprise_script_service/mruby/build_config/host-debug.rb +20 -0
- data/ext/enterprise_script_service/mruby/build_config/host-gprof.rb +14 -0
- data/ext/enterprise_script_service/mruby/build_config/host-m32.rb +15 -0
- data/ext/enterprise_script_service/mruby/build_config/host-shared.rb +36 -0
- data/ext/enterprise_script_service/mruby/build_config/mrbc.rb +11 -0
- data/ext/enterprise_script_service/mruby/build_config/no-float.rb +17 -0
- data/ext/enterprise_script_service/mruby/doc/guides/compile.md +138 -49
- data/ext/enterprise_script_service/mruby/doc/guides/debugger.md +5 -4
- data/ext/enterprise_script_service/mruby/doc/guides/gc-arena-howto.md +1 -1
- data/ext/enterprise_script_service/mruby/doc/guides/mrbconf.md +49 -22
- data/ext/enterprise_script_service/mruby/doc/guides/mrbgems.md +31 -14
- data/ext/enterprise_script_service/mruby/doc/guides/symbol.md +83 -0
- data/ext/enterprise_script_service/mruby/doc/limitations.md +35 -36
- data/ext/enterprise_script_service/mruby/doc/mruby3.md +163 -0
- data/ext/enterprise_script_service/mruby/doc/opcode.md +93 -107
- data/ext/enterprise_script_service/mruby/examples/mrbgems/c_and_ruby_extension_example/mrblib/example.rb +1 -1
- data/ext/enterprise_script_service/mruby/examples/mrbgems/c_and_ruby_extension_example/src/example.c +5 -1
- data/ext/enterprise_script_service/mruby/examples/mrbgems/c_extension_example/src/example.c +5 -1
- data/ext/enterprise_script_service/mruby/examples/mrbgems/ruby_extension_example/mrblib/example.rb +1 -1
- data/ext/enterprise_script_service/mruby/include/mrbconf.h +81 -62
- data/ext/enterprise_script_service/mruby/include/mruby.h +137 -96
- data/ext/enterprise_script_service/mruby/include/mruby/array.h +23 -6
- data/ext/enterprise_script_service/mruby/include/mruby/boxing_nan.h +73 -48
- data/ext/enterprise_script_service/mruby/include/mruby/boxing_no.h +8 -8
- data/ext/enterprise_script_service/mruby/include/mruby/boxing_word.h +79 -48
- data/ext/enterprise_script_service/mruby/include/mruby/class.h +10 -8
- data/ext/enterprise_script_service/mruby/include/mruby/common.h +4 -1
- data/ext/enterprise_script_service/mruby/include/mruby/compile.h +13 -7
- data/ext/enterprise_script_service/mruby/include/mruby/debug.h +2 -2
- data/ext/enterprise_script_service/mruby/include/mruby/dump.h +17 -35
- data/ext/enterprise_script_service/mruby/include/mruby/endian.h +44 -0
- data/ext/enterprise_script_service/mruby/include/mruby/error.h +39 -5
- data/ext/enterprise_script_service/mruby/include/mruby/gc.h +1 -0
- data/ext/enterprise_script_service/mruby/include/mruby/hash.h +33 -13
- data/ext/enterprise_script_service/mruby/include/mruby/irep.h +64 -14
- data/ext/enterprise_script_service/mruby/include/mruby/khash.h +6 -14
- data/ext/enterprise_script_service/mruby/include/mruby/numeric.h +36 -63
- data/ext/enterprise_script_service/mruby/include/mruby/opcode.h +1 -27
- data/ext/enterprise_script_service/mruby/include/mruby/ops.h +27 -23
- data/ext/enterprise_script_service/mruby/include/mruby/presym.h +40 -0
- data/ext/enterprise_script_service/mruby/include/mruby/presym/disable.h +70 -0
- data/ext/enterprise_script_service/mruby/include/mruby/presym/enable.h +37 -0
- data/ext/enterprise_script_service/mruby/include/mruby/presym/scanning.h +73 -0
- data/ext/enterprise_script_service/mruby/include/mruby/proc.h +80 -13
- data/ext/enterprise_script_service/mruby/include/mruby/string.h +10 -15
- data/ext/enterprise_script_service/mruby/include/mruby/throw.h +14 -3
- data/ext/enterprise_script_service/mruby/include/mruby/value.h +29 -19
- data/ext/enterprise_script_service/mruby/include/mruby/variable.h +1 -0
- data/ext/enterprise_script_service/mruby/include/mruby/version.h +26 -7
- data/ext/enterprise_script_service/mruby/lib/mruby/build.rb +198 -44
- data/ext/enterprise_script_service/mruby/lib/mruby/build/command.rb +55 -37
- data/ext/enterprise_script_service/mruby/lib/mruby/build/load_gems.rb +12 -10
- data/ext/enterprise_script_service/mruby/lib/{mruby-core-ext.rb → mruby/core_ext.rb} +10 -3
- data/ext/enterprise_script_service/mruby/lib/mruby/gem.rb +75 -32
- data/ext/enterprise_script_service/mruby/lib/mruby/lockfile.rb +1 -1
- data/ext/enterprise_script_service/mruby/lib/mruby/presym.rb +132 -0
- data/ext/enterprise_script_service/mruby/mrbgems/default-no-fpu.gembox +3 -0
- data/ext/enterprise_script_service/mruby/mrbgems/default-no-stdio.gembox +4 -0
- data/ext/enterprise_script_service/mruby/mrbgems/default.gembox +9 -88
- data/ext/enterprise_script_service/mruby/mrbgems/full-core.gembox +1 -4
- data/ext/enterprise_script_service/mruby/mrbgems/math.gembox +10 -0
- data/ext/enterprise_script_service/mruby/mrbgems/metaprog.gembox +15 -0
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb +1 -1
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/src/array.c +5 -4
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-config/mrbgem.rake +28 -19
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-config/mruby-config +18 -8
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-debugger/bintest/mrdb.rb +3 -6
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-debugger/bintest/print.rb +10 -10
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c +14 -9
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.c +3 -2
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c +4 -3
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.h +2 -6
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdbconf.h +4 -4
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-mirb/bintest/mirb.rb +23 -5
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-mirb/mrbgem.rake +11 -2
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c +41 -34
- data/ext/enterprise_script_service/mruby/mrbgems/{mruby-compiler → mruby-bin-mrbc}/bintest/mrbc.rb +0 -0
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-mrbc/mrbgem.rake +3 -4
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c +19 -9
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-mruby/bintest/mruby.rb +25 -4
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-mruby/mrbgem.rake +1 -1
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c +22 -6
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-strip/bintest/mruby-strip.rb +1 -1
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c +2 -2
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-catch/mrbgem.rake +5 -0
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-catch/mrblib/catch.rb +27 -0
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-class-ext/src/class.c +2 -1
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-compiler/core/codegen.c +430 -399
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-compiler/core/keywords +5 -0
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-compiler/core/lex.def +49 -44
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-compiler/core/parse.y +559 -217
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-compiler/core/y.tab.c +4774 -4193
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-compiler/mrbgem.rake +18 -19
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-complex/mrblib/complex.rb +1 -1
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-complex/src/complex.c +8 -7
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-complex/test/complex.rb +4 -4
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-enumerator/mrblib/enumerator.rb +1 -0
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-enumerator/test/enumerator.rb +2 -2
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-error/mrbgem.rake +2 -2
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-eval/src/eval.c +17 -25
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-fiber/src/fiber.c +18 -13
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-hash-ext/src/hash-ext.c +30 -2
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-hash-ext/test/hash.rb +7 -0
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-inline-struct/test/inline.c +2 -2
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/README.md +18 -16
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/include/mruby/ext/io.h +2 -2
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/mrblib/file.rb +9 -4
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/mrblib/io.rb +2 -2
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/src/file.c +55 -52
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/src/file_test.c +4 -2
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/src/io.c +99 -87
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/test/file.rb +2 -0
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/test/io.rb +2 -3
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/test/mruby_io_test.c +1 -1
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-kernel-ext/src/kernel.c +7 -6
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-math/src/math.c +13 -12
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-math/test/math.rb +5 -4
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-metaprog/src/metaprog.c +43 -58
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-metaprog/test/metaprog.rb +4 -4
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-method/README.md +4 -3
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-method/src/method.c +77 -74
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-method/test/method.rb +4 -4
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-numeric-ext/src/numeric_ext.c +14 -13
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-object-ext/src/object.c +5 -4
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-objectspace/src/mruby_objectspace.c +18 -12
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-os-memsize/mrbgem.rake +10 -0
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-os-memsize/src/memsize.c +231 -0
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-os-memsize/test/memsize.rb +63 -0
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-pack/README.md +15 -18
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-pack/src/pack.c +38 -88
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-print/mrblib/print.rb +1 -30
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-print/src/print.c +62 -26
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-proc-ext/src/proc.c +32 -19
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-proc-ext/test/proc.c +1 -1
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-random/src/random.c +98 -43
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-random/test/random.rb +2 -2
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-range-ext/mrblib/range.rb +39 -6
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-range-ext/src/range.c +20 -40
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-range-ext/test/range.rb +27 -3
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-rational/mrblib/rational.rb +11 -17
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-rational/src/rational.c +216 -38
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-rational/test/rational.rb +6 -6
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-sleep/README.md +6 -4
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-sleep/src/mrb_sleep.c +4 -4
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-socket/README.md +3 -2
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-socket/src/socket.c +47 -45
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-sprintf/src/sprintf.c +102 -71
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-sprintf/test/sprintf.rb +4 -2
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-string-ext/mrblib/string.rb +23 -1
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-string-ext/src/string.c +13 -9
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-struct/mrblib/struct.rb +1 -1
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-struct/src/struct.c +18 -25
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-symbol-ext/src/symbol.c +6 -5
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-symbol-ext/test/symbol.rb +1 -1
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-test/README.md +0 -1
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-test/driver.c +5 -5
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-test/mrbgem.rake +16 -44
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-test/vformat.c +4 -4
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-time/src/time.c +27 -27
- data/ext/enterprise_script_service/mruby/mrbgems/stdlib-ext.gembox +18 -0
- data/ext/enterprise_script_service/mruby/mrbgems/stdlib-io.gembox +12 -0
- data/ext/enterprise_script_service/mruby/mrbgems/stdlib.gembox +54 -0
- data/ext/enterprise_script_service/mruby/mrblib/10error.rb +4 -0
- data/ext/enterprise_script_service/mruby/mrblib/array.rb +17 -9
- data/ext/enterprise_script_service/mruby/mrblib/enum.rb +1 -1
- data/ext/enterprise_script_service/mruby/mrblib/hash.rb +0 -20
- data/ext/enterprise_script_service/mruby/mrblib/init_mrblib.c +0 -11
- data/ext/enterprise_script_service/mruby/mrblib/numeric.rb +36 -11
- data/ext/enterprise_script_service/mruby/mrblib/range.rb +25 -3
- data/ext/enterprise_script_service/mruby/oss-fuzz/mruby_proto_fuzzer.cpp +2 -2
- data/ext/enterprise_script_service/mruby/oss-fuzz/proto_to_ruby.h +1 -1
- data/ext/enterprise_script_service/mruby/src/array.c +43 -80
- data/ext/enterprise_script_service/mruby/src/backtrace.c +16 -17
- data/ext/enterprise_script_service/mruby/src/class.c +774 -182
- data/ext/enterprise_script_service/mruby/src/codedump.c +223 -198
- data/ext/enterprise_script_service/mruby/src/debug.c +6 -6
- data/ext/enterprise_script_service/mruby/src/dump.c +466 -141
- data/ext/enterprise_script_service/mruby/src/enum.c +1 -1
- data/ext/enterprise_script_service/mruby/src/error.c +36 -13
- data/ext/enterprise_script_service/mruby/src/etc.c +43 -34
- data/ext/enterprise_script_service/mruby/src/fmt_fp.c +5 -6
- data/ext/enterprise_script_service/mruby/src/gc.c +73 -71
- data/ext/enterprise_script_service/mruby/src/hash.c +1050 -707
- data/ext/enterprise_script_service/mruby/src/kernel.c +75 -220
- data/ext/enterprise_script_service/mruby/src/load.c +196 -166
- data/ext/enterprise_script_service/mruby/src/numeric.c +352 -314
- data/ext/enterprise_script_service/mruby/src/object.c +97 -90
- data/ext/enterprise_script_service/mruby/src/print.c +4 -3
- data/ext/enterprise_script_service/mruby/src/proc.c +48 -56
- data/ext/enterprise_script_service/mruby/src/range.c +45 -21
- data/ext/enterprise_script_service/mruby/src/state.c +25 -32
- data/ext/enterprise_script_service/mruby/src/string.c +59 -101
- data/ext/enterprise_script_service/mruby/src/symbol.c +121 -56
- data/ext/enterprise_script_service/mruby/src/value_array.h +1 -0
- data/ext/enterprise_script_service/mruby/src/variable.c +158 -158
- data/ext/enterprise_script_service/mruby/src/vm.c +617 -602
- data/ext/enterprise_script_service/mruby/tasks/benchmark.rake +6 -6
- data/ext/enterprise_script_service/mruby/tasks/bin.rake +23 -0
- data/ext/enterprise_script_service/mruby/tasks/core.rake +12 -0
- data/ext/enterprise_script_service/mruby/tasks/doc.rake +50 -38
- data/ext/enterprise_script_service/mruby/tasks/gitlab.rake +83 -77
- data/ext/enterprise_script_service/mruby/tasks/libmruby.rake +10 -1
- data/ext/enterprise_script_service/mruby/tasks/mrbgems.rake +13 -1
- data/ext/enterprise_script_service/mruby/tasks/mrblib.rake +40 -0
- data/ext/enterprise_script_service/mruby/tasks/presym.rake +44 -0
- data/ext/enterprise_script_service/mruby/tasks/test.rake +68 -0
- data/ext/enterprise_script_service/mruby/tasks/toolchains/gcc.rake +6 -5
- data/ext/enterprise_script_service/mruby/tasks/toolchains/openwrt.rake +10 -14
- data/ext/enterprise_script_service/mruby/tasks/toolchains/visualcpp.rake +17 -21
- data/ext/enterprise_script_service/mruby/test/bintest.rb +5 -5
- data/ext/enterprise_script_service/mruby/test/t/argumenterror.rb +16 -0
- data/ext/enterprise_script_service/mruby/test/t/array.rb +7 -3
- data/ext/enterprise_script_service/mruby/test/t/bs_literal.rb +1 -1
- data/ext/enterprise_script_service/mruby/test/t/float.rb +18 -8
- data/ext/enterprise_script_service/mruby/test/t/hash.rb +903 -281
- data/ext/enterprise_script_service/mruby/test/t/integer.rb +10 -38
- data/ext/enterprise_script_service/mruby/test/t/kernel.rb +1 -1
- data/ext/enterprise_script_service/mruby/test/t/literals.rb +50 -0
- data/ext/enterprise_script_service/mruby/test/t/module.rb +2 -2
- data/ext/enterprise_script_service/mruby/test/t/numeric.rb +1 -1
- data/ext/enterprise_script_service/mruby/test/t/range.rb +83 -1
- data/ext/enterprise_script_service/mruby/test/t/string.rb +4 -0
- data/ext/enterprise_script_service/mruby/test/t/superclass.rb +10 -10
- data/ext/enterprise_script_service/mruby/test/t/syntax.rb +24 -0
- data/ext/enterprise_script_service/mruby/test/t/vformat.rb +3 -3
- data/ext/enterprise_script_service/mruby_config.rb +2 -5
- data/ext/enterprise_script_service/mruby_engine.cpp +1 -1
- data/lib/script_core/version.rb +1 -1
- data/spec/script_core_spec.rb +13 -0
- metadata +61 -23
- data/ext/enterprise_script_service/mruby/.github/workflows/main.yml +0 -24
- data/ext/enterprise_script_service/mruby/TODO +0 -8
- data/ext/enterprise_script_service/mruby/appveyor_config.rb +0 -46
- data/ext/enterprise_script_service/mruby/benchmark/build_config_boxing.rb +0 -28
- data/ext/enterprise_script_service/mruby/examples/targets/build_config_android_arm64-v8a.rb +0 -26
- data/ext/enterprise_script_service/mruby/examples/targets/build_config_android_armeabi.rb +0 -26
- data/ext/enterprise_script_service/mruby/mrbgems/mruby-sprintf/src/kernel.c +0 -30
- data/ext/enterprise_script_service/mruby/mrblib/mrblib.rake +0 -18
- data/ext/enterprise_script_service/mruby/src/crc.c +0 -39
- 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
|
-
|
15
|
-
|
16
|
-
|
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
|
-
|
20
|
-
|
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
|
-
#
|
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
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
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
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
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
|
-
|
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
|
68
|
-
#ifndef
|
299
|
+
case MRB_TT_INTEGER:
|
300
|
+
#ifndef MRB_NO_FLOAT
|
69
301
|
case MRB_TT_FLOAT:
|
70
302
|
#endif
|
71
|
-
|
303
|
+
hash_code = U32(mrb_obj_id(key));
|
72
304
|
break;
|
73
|
-
|
74
305
|
default:
|
75
|
-
|
76
|
-
|
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
|
-
|
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
|
86
|
-
|
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
|
99
|
-
|
100
|
-
|
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
|
334
|
+
#ifndef MRB_NO_FLOAT
|
111
335
|
case MRB_TT_FLOAT:
|
112
|
-
|
113
|
-
|
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
|
-
|
125
|
-
|
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
|
-
|
136
|
-
|
137
|
-
ht_new(mrb_state *mrb)
|
346
|
+
static mrb_bool
|
347
|
+
entry_deleted_p(const hash_entry* entry)
|
138
348
|
{
|
139
|
-
|
349
|
+
return mrb_undef_p(entry->key);
|
350
|
+
}
|
140
351
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
t->index = NULL;
|
352
|
+
static void
|
353
|
+
entry_delete(hash_entry* entry)
|
354
|
+
{
|
355
|
+
entry->key = mrb_undef_value();
|
356
|
+
}
|
147
357
|
|
148
|
-
|
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
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
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
|
-
|
162
|
-
|
163
|
-
|
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
|
-
|
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
|
-
|
431
|
+
ea_set(hash_entry *ea, uint32_t index, mrb_value key, mrb_value val)
|
170
432
|
{
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
segment *seg;
|
175
|
-
size_t i;
|
433
|
+
ea[index].key = key;
|
434
|
+
ea[index].val = val;
|
435
|
+
}
|
176
436
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
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
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
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
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
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
|
-
|
464
|
+
ar_compress(mrb_state *mrb, struct RHash *h)
|
223
465
|
{
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
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
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
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
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
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
|
-
|
250
|
-
|
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
|
-
|
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
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
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
|
-
|
276
|
-
|
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
|
281
|
-
|
565
|
+
static uint32_t
|
566
|
+
ib_it_pos_for(index_buckets_iter *it, uint32_t v)
|
282
567
|
{
|
283
|
-
|
568
|
+
return v & it->mask;
|
569
|
+
}
|
284
570
|
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
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
|
-
|
292
|
-
|
293
|
-
|
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
|
-
|
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
|
-
|
602
|
+
ib_it_init(mrb_state *mrb, index_buckets_iter *it, struct RHash *h, mrb_value key)
|
301
603
|
{
|
302
|
-
|
303
|
-
|
304
|
-
|
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
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
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
|
-
|
326
|
-
|
644
|
+
else {
|
645
|
+
it->shift1 = 0;
|
327
646
|
}
|
647
|
+
it->pos = ib_it_pos_for(it, it->pos + (++it->step));
|
648
|
+
}
|
328
649
|
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
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
|
-
|
343
|
-
|
344
|
-
|
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
|
-
|
672
|
+
ib_it_delete(index_buckets_iter *it)
|
351
673
|
{
|
352
|
-
|
353
|
-
|
674
|
+
ib_it_set(it, ib_it_deleted_value(it));
|
675
|
+
}
|
354
676
|
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
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
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
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
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
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
|
-
|
417
|
-
|
418
|
-
|
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
|
-
|
437
|
-
|
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
|
-
|
441
|
-
|
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
|
-
|
444
|
-
|
445
|
-
|
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
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
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
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
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
|
-
|
794
|
+
ht_get(mrb_state *mrb, struct RHash *h, mrb_value key, mrb_value *valp)
|
471
795
|
{
|
472
|
-
|
473
|
-
|
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
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
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
|
-
|
482
|
-
|
483
|
-
|
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
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
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
|
-
|
501
|
-
{
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
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
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
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
|
-
|
522
|
-
|
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
|
-
|
936
|
+
return (struct RHash*)mrb_obj_alloc(mrb, MRB_TT_HASH, mrb->hash_class);
|
526
937
|
}
|
527
938
|
|
528
|
-
|
529
|
-
|
530
|
-
ht_copy(mrb_state *mrb, htable *t)
|
939
|
+
static void
|
940
|
+
h_init(struct RHash *h)
|
531
941
|
{
|
532
|
-
|
533
|
-
|
534
|
-
mrb_int i;
|
942
|
+
ar_init(h, 0, NULL, 0, 0);
|
943
|
+
}
|
535
944
|
|
536
|
-
|
537
|
-
|
538
|
-
|
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
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
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
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
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
|
-
|
965
|
+
h_set(mrb_state *mrb, struct RHash *h, mrb_value key, mrb_value val)
|
559
966
|
{
|
560
|
-
|
967
|
+
(h_ar_p(h) ? ar_set : ht_set)(mrb, h, key, val);
|
968
|
+
}
|
561
969
|
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
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
|
-
|
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
|
576
|
-
|
983
|
+
static void
|
984
|
+
h_rehash(mrb_state *mrb, struct RHash *h)
|
577
985
|
{
|
578
|
-
|
579
|
-
|
580
|
-
|
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
|
-
|
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
|
-
|
588
|
-
|
1038
|
+
size_t
|
1039
|
+
mrb_gc_mark_hash_size(mrb_state *mrb, struct RHash *h)
|
589
1040
|
{
|
590
|
-
|
591
|
-
mrb_gc_mark_value(mrb, val);
|
592
|
-
return 0;
|
1041
|
+
return h_size(h) * 2;
|
593
1042
|
}
|
594
1043
|
|
595
1044
|
void
|
596
|
-
|
1045
|
+
mrb_gc_free_hash(mrb_state *mrb, struct RHash *h)
|
597
1046
|
{
|
598
|
-
|
1047
|
+
h_free_table(mrb, h);
|
599
1048
|
}
|
600
1049
|
|
601
1050
|
size_t
|
602
|
-
|
1051
|
+
mrb_hash_memsize(mrb_value self)
|
603
1052
|
{
|
604
|
-
|
605
|
-
return
|
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
|
-
|
609
|
-
|
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
|
-
|
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
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
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
|
642
|
-
|
1107
|
+
static void
|
1108
|
+
hash_modify(mrb_state *mrb, mrb_value hash)
|
643
1109
|
{
|
644
|
-
|
645
|
-
|
646
|
-
htable *orig_h;
|
647
|
-
mrb_value ifnone, vret;
|
1110
|
+
mrb_check_frozen(mrb, mrb_hash_ptr(hash));
|
1111
|
+
}
|
648
1112
|
|
649
|
-
|
650
|
-
|
651
|
-
|
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
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
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
|
-
|
665
|
-
|
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
|
-
|
1141
|
+
h->flags &= ~mask;
|
1142
|
+
h->flags |= orig_h->flags & mask;
|
670
1143
|
}
|
671
1144
|
|
672
|
-
static
|
673
|
-
|
1145
|
+
static mrb_value
|
1146
|
+
mrb_hash_init_copy(mrb_state *mrb, mrb_value self)
|
674
1147
|
{
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
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
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
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*
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
copy
|
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 (
|
1180
|
+
if (h_get(mrb, mrb_hash_ptr(hash), key, &val)) {
|
710
1181
|
return val;
|
711
1182
|
}
|
712
1183
|
|
713
|
-
mid =
|
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 (
|
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
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
mrb_field_write_barrier_value(mrb, (
|
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
|
-
|
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,
|
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
|
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
|
-
|
917
|
-
mrb_iv_set(mrb, hash,
|
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
|
-
|
972
|
-
mrb_iv_set(mrb, hash,
|
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
|
-
|
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
|
-
|
1468
|
+
struct RHash *h = mrb_hash_ptr(hash);
|
1053
1469
|
|
1054
|
-
|
1055
|
-
if (
|
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
|
-
|
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
|
-
|
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 ->
|
1143
|
-
* hsh.size ->
|
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
|
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
|
-
|
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
|
-
|
1208
|
-
mrb_int
|
1209
|
-
|
1210
|
-
|
1211
|
-
|
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
|
-
|
1242
|
-
mrb_int
|
1243
|
-
|
1244
|
-
|
1245
|
-
|
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
|
-
|
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
|
1330
|
-
|
1331
|
-
|
1332
|
-
|
1333
|
-
|
1334
|
-
|
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
|
-
|
1350
|
-
|
1351
|
-
|
1352
|
-
|
1353
|
-
h1 =
|
1354
|
-
h2 =
|
1355
|
-
|
1356
|
-
if (
|
1357
|
-
if (
|
1358
|
-
|
1359
|
-
|
1360
|
-
|
1361
|
-
|
1362
|
-
|
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]=>
|
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]=>
|
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
|
-
|
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));
|
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 */
|