script_core 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (381) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rubocop.yml +8 -6
  4. data/.ruby-version +1 -1
  5. data/Gemfile +2 -1
  6. data/bin/sandbox +1 -1
  7. data/ext/enterprise_script_service/Rakefile +1 -1
  8. data/ext/enterprise_script_service/flags.rb +5 -0
  9. data/ext/enterprise_script_service/libseccomp/CHANGELOG +15 -0
  10. data/ext/enterprise_script_service/libseccomp/CREDITS +3 -0
  11. data/ext/enterprise_script_service/libseccomp/Makefile.am +1 -1
  12. data/ext/enterprise_script_service/libseccomp/README.md +1 -1
  13. data/ext/enterprise_script_service/libseccomp/SECURITY.md +45 -0
  14. data/ext/enterprise_script_service/libseccomp/configure.ac +3 -3
  15. data/ext/enterprise_script_service/libseccomp/doc/admin/MAINTAINER_PROCESS.md +95 -0
  16. data/ext/enterprise_script_service/libseccomp/{RELEASE_PROCESS.md → doc/admin/RELEASE_PROCESS.md} +9 -1
  17. data/ext/enterprise_script_service/libseccomp/include/Makefile.am +1 -1
  18. data/ext/enterprise_script_service/libseccomp/include/seccomp-syscalls.h +2292 -0
  19. data/ext/enterprise_script_service/libseccomp/include/seccomp.h.in +3 -1065
  20. data/ext/enterprise_script_service/libseccomp/src/arch-aarch64-syscalls.c +35 -3
  21. data/ext/enterprise_script_service/libseccomp/src/arch-arm-syscalls.c +35 -3
  22. data/ext/enterprise_script_service/libseccomp/src/arch-mips-syscalls.c +43 -11
  23. data/ext/enterprise_script_service/libseccomp/src/arch-mips64-syscalls.c +33 -1
  24. data/ext/enterprise_script_service/libseccomp/src/arch-mips64n32-syscalls.c +33 -1
  25. data/ext/enterprise_script_service/libseccomp/src/arch-parisc-syscalls.c +34 -2
  26. data/ext/enterprise_script_service/libseccomp/src/arch-ppc-syscalls.c +43 -11
  27. data/ext/enterprise_script_service/libseccomp/src/arch-ppc64-syscalls.c +44 -12
  28. data/ext/enterprise_script_service/libseccomp/src/arch-s390-syscalls.c +46 -14
  29. data/ext/enterprise_script_service/libseccomp/src/arch-s390.c +142 -18
  30. data/ext/enterprise_script_service/libseccomp/src/arch-s390x-syscalls.c +47 -15
  31. data/ext/enterprise_script_service/libseccomp/src/arch-s390x.c +143 -17
  32. data/ext/enterprise_script_service/libseccomp/src/arch-x32-syscalls.c +33 -1
  33. data/ext/enterprise_script_service/libseccomp/src/arch-x86-syscalls.c +94 -12
  34. data/ext/enterprise_script_service/libseccomp/src/arch-x86.c +142 -19
  35. data/ext/enterprise_script_service/libseccomp/src/arch-x86_64-syscalls.c +33 -1
  36. data/ext/enterprise_script_service/libseccomp/src/db.c +1 -0
  37. data/ext/enterprise_script_service/libseccomp/src/gen_bpf.c +10 -3
  38. data/ext/enterprise_script_service/libseccomp/src/python/Makefile.am +4 -4
  39. data/ext/enterprise_script_service/libseccomp/src/python/seccomp.pyx +2 -0
  40. data/ext/enterprise_script_service/libseccomp/tests/.gitignore +1 -0
  41. data/ext/enterprise_script_service/libseccomp/tests/50-sim-hash_collision.c +98 -0
  42. data/ext/enterprise_script_service/libseccomp/tests/50-sim-hash_collision.py +61 -0
  43. data/ext/enterprise_script_service/libseccomp/tests/50-sim-hash_collision.tests +18 -0
  44. data/ext/enterprise_script_service/libseccomp/tests/Makefile.am +6 -3
  45. data/ext/enterprise_script_service/libseccomp/tools/Makefile.am +0 -2
  46. data/ext/enterprise_script_service/libseccomp/tools/check-syntax +1 -0
  47. data/ext/enterprise_script_service/libseccomp/tools/scmp_bpf_sim.c +2 -0
  48. data/ext/enterprise_script_service/mruby-mpdecimal/src/ext.c +1 -1
  49. data/ext/enterprise_script_service/mruby/.gitignore +2 -2
  50. data/ext/enterprise_script_service/mruby/CONTRIBUTING.md +10 -3
  51. data/ext/enterprise_script_service/mruby/Doxyfile +2408 -0
  52. data/ext/enterprise_script_service/mruby/README.md +21 -8
  53. data/ext/enterprise_script_service/mruby/Rakefile +4 -13
  54. data/ext/enterprise_script_service/mruby/appveyor_config.rb +1 -1
  55. data/ext/enterprise_script_service/mruby/build_config.rb +3 -3
  56. data/ext/enterprise_script_service/mruby/doc/guides/compile.md +42 -42
  57. data/ext/enterprise_script_service/mruby/doc/guides/debugger.md +1 -1
  58. data/ext/enterprise_script_service/mruby/doc/guides/mrbconf.md +45 -6
  59. data/ext/enterprise_script_service/mruby/doc/guides/mrbgems.md +5 -0
  60. data/ext/enterprise_script_service/mruby/doc/limitations.md +88 -38
  61. data/ext/enterprise_script_service/mruby/doc/mruby_logo_red_icon.png +0 -0
  62. data/ext/enterprise_script_service/mruby/doc/opcode.md +94 -94
  63. data/ext/enterprise_script_service/mruby/include/mrbconf.h +74 -11
  64. data/ext/enterprise_script_service/mruby/include/mruby.h +242 -146
  65. data/ext/enterprise_script_service/mruby/include/mruby/array.h +7 -7
  66. data/ext/enterprise_script_service/mruby/include/mruby/boxing_nan.h +2 -9
  67. data/ext/enterprise_script_service/mruby/include/mruby/boxing_no.h +11 -10
  68. data/ext/enterprise_script_service/mruby/include/mruby/boxing_word.h +104 -69
  69. data/ext/enterprise_script_service/mruby/include/mruby/class.h +7 -5
  70. data/ext/enterprise_script_service/mruby/include/mruby/common.h +9 -7
  71. data/ext/enterprise_script_service/mruby/include/mruby/compile.h +6 -6
  72. data/ext/enterprise_script_service/mruby/include/mruby/data.h +5 -5
  73. data/ext/enterprise_script_service/mruby/include/mruby/debug.h +2 -2
  74. data/ext/enterprise_script_service/mruby/include/mruby/dump.h +3 -7
  75. data/ext/enterprise_script_service/mruby/include/mruby/error.h +34 -6
  76. data/ext/enterprise_script_service/mruby/include/mruby/gc.h +2 -2
  77. data/ext/enterprise_script_service/mruby/include/mruby/hash.h +4 -11
  78. data/ext/enterprise_script_service/mruby/include/mruby/irep.h +16 -4
  79. data/ext/enterprise_script_service/mruby/include/mruby/istruct.h +4 -4
  80. data/ext/enterprise_script_service/mruby/include/mruby/khash.h +2 -2
  81. data/ext/enterprise_script_service/mruby/include/mruby/numeric.h +41 -7
  82. data/ext/enterprise_script_service/mruby/include/mruby/object.h +8 -9
  83. data/ext/enterprise_script_service/mruby/include/mruby/opcode.h +2 -2
  84. data/ext/enterprise_script_service/mruby/include/mruby/ops.h +6 -6
  85. data/ext/enterprise_script_service/mruby/include/mruby/proc.h +19 -13
  86. data/ext/enterprise_script_service/mruby/include/mruby/range.h +10 -4
  87. data/ext/enterprise_script_service/mruby/include/mruby/re.h +2 -2
  88. data/ext/enterprise_script_service/mruby/include/mruby/string.h +130 -107
  89. data/ext/enterprise_script_service/mruby/include/mruby/throw.h +2 -2
  90. data/ext/enterprise_script_service/mruby/include/mruby/value.h +137 -49
  91. data/ext/enterprise_script_service/mruby/include/mruby/variable.h +3 -5
  92. data/ext/enterprise_script_service/mruby/include/mruby/version.h +24 -10
  93. data/ext/enterprise_script_service/mruby/lib/mruby-core-ext.rb +2 -39
  94. data/ext/enterprise_script_service/mruby/lib/mruby/build.rb +32 -15
  95. data/ext/enterprise_script_service/mruby/lib/mruby/build/command.rb +63 -17
  96. data/ext/enterprise_script_service/mruby/lib/mruby/build/load_gems.rb +24 -10
  97. data/ext/enterprise_script_service/mruby/lib/mruby/gem.rb +11 -7
  98. data/ext/enterprise_script_service/mruby/lib/mruby/lockfile.rb +81 -0
  99. data/ext/enterprise_script_service/mruby/minirake +27 -11
  100. data/ext/enterprise_script_service/mruby/mrbgems/default.gembox +3 -0
  101. data/ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrbgem.rake +0 -1
  102. data/ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/mrblib/array.rb +47 -9
  103. data/ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/src/array.c +3 -3
  104. data/ext/enterprise_script_service/mruby/mrbgems/mruby-array-ext/test/array.rb +50 -29
  105. data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c +3 -3
  106. data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.c +2 -2
  107. data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdprint.c +3 -3
  108. data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c +2 -2
  109. data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.h +1 -1
  110. data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdbconf.h +4 -0
  111. data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c +28 -1
  112. data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c +1 -2
  113. data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-mruby/bintest/mruby.rb +75 -8
  114. data/ext/enterprise_script_service/mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c +134 -90
  115. data/ext/enterprise_script_service/mruby/mrbgems/mruby-class-ext/src/class.c +7 -8
  116. data/ext/enterprise_script_service/mruby/mrbgems/mruby-compiler/core/codegen.c +69 -46
  117. data/ext/enterprise_script_service/mruby/mrbgems/mruby-compiler/core/keywords +0 -3
  118. data/ext/enterprise_script_service/mruby/mrbgems/mruby-compiler/core/lex.def +51 -59
  119. data/ext/enterprise_script_service/mruby/mrbgems/mruby-compiler/core/parse.y +430 -241
  120. data/ext/enterprise_script_service/mruby/mrbgems/mruby-complex/mrbgem.rake +10 -0
  121. data/ext/enterprise_script_service/mruby/mrbgems/mruby-complex/mrblib/complex.rb +122 -0
  122. data/ext/enterprise_script_service/mruby/mrbgems/mruby-complex/src/complex.c +249 -0
  123. data/ext/enterprise_script_service/mruby/mrbgems/mruby-complex/test/complex.rb +153 -0
  124. data/ext/enterprise_script_service/mruby/mrbgems/mruby-enum-chain/mrblib/chain.rb +19 -17
  125. data/ext/enterprise_script_service/mruby/mrbgems/mruby-enum-chain/test/enum_chain.rb +41 -9
  126. data/ext/enterprise_script_service/mruby/mrbgems/mruby-enum-ext/mrblib/enum.rb +30 -4
  127. data/ext/enterprise_script_service/mruby/mrbgems/mruby-enum-ext/test/enum.rb +8 -3
  128. data/ext/enterprise_script_service/mruby/mrbgems/mruby-enumerator/mrbgem.rake +0 -1
  129. data/ext/enterprise_script_service/mruby/mrbgems/mruby-enumerator/mrblib/enumerator.rb +46 -14
  130. data/ext/enterprise_script_service/mruby/mrbgems/mruby-enumerator/test/enumerator.rb +51 -2
  131. data/ext/enterprise_script_service/mruby/mrbgems/mruby-error/src/exception.c +10 -0
  132. data/ext/enterprise_script_service/mruby/mrbgems/mruby-eval/src/eval.c +47 -44
  133. data/ext/enterprise_script_service/mruby/mrbgems/mruby-eval/test/eval.rb +2 -2
  134. data/ext/enterprise_script_service/mruby/mrbgems/mruby-exit/src/mruby-exit.c +9 -4
  135. data/ext/enterprise_script_service/mruby/mrbgems/mruby-fiber/src/fiber.c +16 -12
  136. data/ext/enterprise_script_service/mruby/mrbgems/mruby-fiber/test/fiber.rb +1 -1
  137. data/ext/enterprise_script_service/mruby/mrbgems/mruby-hash-ext/mrbgem.rake +0 -2
  138. data/ext/enterprise_script_service/mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb +3 -0
  139. data/ext/enterprise_script_service/mruby/mrbgems/mruby-hash-ext/test/hash.rb +3 -7
  140. data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/README.md +1 -3
  141. data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/mrbgem.rake +1 -1
  142. data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/mrblib/file.rb +0 -5
  143. data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/mrblib/io.rb +24 -38
  144. data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/mrblib/kernel.rb +16 -0
  145. data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/src/file.c +19 -18
  146. data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/src/file_test.c +5 -16
  147. data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/src/io.c +54 -42
  148. data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/test/file.rb +24 -20
  149. data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/test/file_test.rb +4 -9
  150. data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/test/io.rb +41 -35
  151. data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/test/mruby_io_test.c +9 -36
  152. data/ext/enterprise_script_service/mruby/mrbgems/mruby-kernel-ext/mrbgem.rake +1 -1
  153. data/ext/enterprise_script_service/mruby/mrbgems/mruby-kernel-ext/src/kernel.c +9 -27
  154. data/ext/enterprise_script_service/mruby/mrbgems/mruby-kernel-ext/test/kernel.rb +2 -0
  155. data/ext/enterprise_script_service/mruby/mrbgems/mruby-math/src/math.c +5 -2
  156. data/ext/enterprise_script_service/mruby/mrbgems/mruby-metaprog/src/metaprog.c +39 -24
  157. data/ext/enterprise_script_service/mruby/mrbgems/mruby-metaprog/test/metaprog.rb +48 -17
  158. data/ext/enterprise_script_service/mruby/mrbgems/mruby-method/mrblib/method.rb +0 -12
  159. data/ext/enterprise_script_service/mruby/mrbgems/mruby-method/src/method.c +134 -101
  160. data/ext/enterprise_script_service/mruby/mrbgems/mruby-method/test/method.rb +9 -1
  161. data/ext/enterprise_script_service/mruby/mrbgems/mruby-numeric-ext/mrblib/numeric_ext.rb +1 -5
  162. data/ext/enterprise_script_service/mruby/mrbgems/mruby-numeric-ext/src/numeric_ext.c +17 -37
  163. data/ext/enterprise_script_service/mruby/mrbgems/mruby-numeric-ext/test/numeric.rb +0 -8
  164. data/ext/enterprise_script_service/mruby/mrbgems/mruby-object-ext/mrbgem.rake +1 -1
  165. data/ext/enterprise_script_service/mruby/mrbgems/mruby-object-ext/mrblib/object.rb +15 -1
  166. data/ext/enterprise_script_service/mruby/mrbgems/mruby-object-ext/src/object.c +35 -6
  167. data/ext/enterprise_script_service/mruby/mrbgems/mruby-object-ext/test/nil.rb +4 -0
  168. data/ext/enterprise_script_service/mruby/mrbgems/mruby-objectspace/src/mruby_objectspace.c +1 -5
  169. data/ext/enterprise_script_service/mruby/mrbgems/mruby-objectspace/test/objectspace.rb +1 -1
  170. data/ext/enterprise_script_service/mruby/mrbgems/mruby-pack/src/pack.c +28 -23
  171. data/ext/enterprise_script_service/mruby/mrbgems/mruby-pack/test/pack.rb +43 -49
  172. data/ext/enterprise_script_service/mruby/mrbgems/mruby-print/mrblib/print.rb +3 -9
  173. data/ext/enterprise_script_service/mruby/mrbgems/mruby-proc-ext/src/proc.c +6 -9
  174. data/ext/enterprise_script_service/mruby/mrbgems/mruby-proc-ext/test/proc.rb +21 -5
  175. data/ext/enterprise_script_service/mruby/mrbgems/mruby-random/src/random.c +157 -124
  176. data/ext/enterprise_script_service/mruby/mrbgems/mruby-random/test/random.rb +72 -26
  177. data/ext/enterprise_script_service/mruby/mrbgems/mruby-range-ext/mrblib/range.rb +38 -0
  178. data/ext/enterprise_script_service/mruby/mrbgems/mruby-range-ext/src/range.c +26 -11
  179. data/ext/enterprise_script_service/mruby/mrbgems/mruby-range-ext/test/range.rb +111 -1
  180. data/ext/enterprise_script_service/mruby/mrbgems/mruby-rational/mrbgem.rake +5 -0
  181. data/ext/enterprise_script_service/mruby/mrbgems/mruby-rational/mrblib/rational.rb +117 -0
  182. data/ext/enterprise_script_service/mruby/mrbgems/mruby-rational/src/rational.c +209 -0
  183. data/ext/enterprise_script_service/mruby/mrbgems/mruby-rational/test/rational.rb +308 -0
  184. data/ext/enterprise_script_service/mruby/mrbgems/mruby-socket/README.md +1 -1
  185. data/ext/enterprise_script_service/mruby/mrbgems/mruby-socket/src/socket.c +10 -9
  186. data/ext/enterprise_script_service/mruby/mrbgems/mruby-sprintf/src/kernel.c +2 -2
  187. data/ext/enterprise_script_service/mruby/mrbgems/mruby-sprintf/src/sprintf.c +22 -24
  188. data/ext/enterprise_script_service/mruby/mrbgems/mruby-string-ext/mrbgem.rake +0 -1
  189. data/ext/enterprise_script_service/mruby/mrbgems/mruby-string-ext/mrblib/string.rb +8 -4
  190. data/ext/enterprise_script_service/mruby/mrbgems/mruby-string-ext/src/string.c +116 -117
  191. data/ext/enterprise_script_service/mruby/mrbgems/mruby-string-ext/test/numeric.rb +29 -0
  192. data/ext/enterprise_script_service/mruby/mrbgems/mruby-string-ext/test/range.rb +26 -0
  193. data/ext/enterprise_script_service/mruby/mrbgems/mruby-string-ext/test/string.rb +32 -50
  194. data/ext/enterprise_script_service/mruby/mrbgems/mruby-struct/mrblib/struct.rb +5 -7
  195. data/ext/enterprise_script_service/mruby/mrbgems/mruby-struct/src/struct.c +43 -57
  196. data/ext/enterprise_script_service/mruby/mrbgems/mruby-struct/test/struct.rb +16 -11
  197. data/ext/enterprise_script_service/mruby/mrbgems/mruby-symbol-ext/src/symbol.c +2 -2
  198. data/ext/enterprise_script_service/mruby/mrbgems/mruby-symbol-ext/test/symbol.rb +1 -1
  199. data/ext/enterprise_script_service/mruby/mrbgems/mruby-test/driver.c +152 -1
  200. data/ext/enterprise_script_service/mruby/mrbgems/mruby-test/mrbgem.rake +4 -3
  201. data/ext/enterprise_script_service/mruby/mrbgems/mruby-test/vformat.c +200 -0
  202. data/ext/enterprise_script_service/mruby/mrbgems/mruby-time/include/mruby/time.h +2 -1
  203. data/ext/enterprise_script_service/mruby/mrbgems/mruby-time/src/time.c +199 -68
  204. data/ext/enterprise_script_service/mruby/mrbgems/mruby-time/test/time.rb +81 -46
  205. data/ext/enterprise_script_service/mruby/mrblib/array.rb +14 -16
  206. data/ext/enterprise_script_service/mruby/mrblib/enum.rb +13 -9
  207. data/ext/enterprise_script_service/mruby/mrblib/hash.rb +5 -7
  208. data/ext/enterprise_script_service/mruby/mrblib/kernel.rb +1 -1
  209. data/ext/enterprise_script_service/mruby/mrblib/numeric.rb +4 -4
  210. data/ext/enterprise_script_service/mruby/mrblib/range.rb +1 -1
  211. data/ext/enterprise_script_service/mruby/mrblib/string.rb +55 -112
  212. data/ext/enterprise_script_service/mruby/mruby-source.gemspec +1 -1
  213. data/ext/enterprise_script_service/mruby/oss-fuzz/config/mruby.dict +105 -0
  214. data/ext/enterprise_script_service/mruby/oss-fuzz/config/mruby_fuzzer.options +5 -0
  215. data/ext/enterprise_script_service/mruby/oss-fuzz/config/mruby_proto_fuzzer.options +4 -0
  216. data/ext/enterprise_script_service/mruby/oss-fuzz/mruby_fuzzer.c +18 -0
  217. data/ext/enterprise_script_service/mruby/oss-fuzz/mruby_proto_fuzzer.cpp +44 -0
  218. data/ext/enterprise_script_service/mruby/oss-fuzz/proto_to_ruby.cpp +455 -0
  219. data/ext/enterprise_script_service/mruby/oss-fuzz/proto_to_ruby.h +55 -0
  220. data/ext/enterprise_script_service/mruby/oss-fuzz/ruby.proto +201 -0
  221. data/ext/enterprise_script_service/mruby/src/array.c +95 -46
  222. data/ext/enterprise_script_service/mruby/src/backtrace.c +6 -8
  223. data/ext/enterprise_script_service/mruby/src/class.c +370 -278
  224. data/ext/enterprise_script_service/mruby/src/codedump.c +34 -34
  225. data/ext/enterprise_script_service/mruby/src/debug.c +2 -2
  226. data/ext/enterprise_script_service/mruby/src/dump.c +8 -6
  227. data/ext/enterprise_script_service/mruby/src/enum.c +1 -1
  228. data/ext/enterprise_script_service/mruby/src/error.c +157 -55
  229. data/ext/enterprise_script_service/mruby/src/etc.c +13 -46
  230. data/ext/enterprise_script_service/mruby/src/fmt_fp.c +2 -2
  231. data/ext/enterprise_script_service/mruby/src/gc.c +30 -11
  232. data/ext/enterprise_script_service/mruby/src/hash.c +23 -14
  233. data/ext/enterprise_script_service/mruby/src/kernel.c +16 -54
  234. data/ext/enterprise_script_service/mruby/src/load.c +40 -76
  235. data/ext/enterprise_script_service/mruby/src/numeric.c +164 -94
  236. data/ext/enterprise_script_service/mruby/src/object.c +16 -39
  237. data/ext/enterprise_script_service/mruby/src/pool.c +0 -2
  238. data/ext/enterprise_script_service/mruby/src/proc.c +47 -48
  239. data/ext/enterprise_script_service/mruby/src/range.c +22 -35
  240. data/ext/enterprise_script_service/mruby/src/state.c +5 -94
  241. data/ext/enterprise_script_service/mruby/src/string.c +874 -710
  242. data/ext/enterprise_script_service/mruby/src/symbol.c +73 -48
  243. data/ext/enterprise_script_service/mruby/src/variable.c +58 -38
  244. data/ext/enterprise_script_service/mruby/src/vm.c +133 -304
  245. data/ext/enterprise_script_service/mruby/tasks/doc.rake +48 -0
  246. data/ext/enterprise_script_service/mruby/tasks/toolchains/clang.rake +3 -4
  247. data/ext/enterprise_script_service/mruby/tasks/toolchains/gcc.rake +20 -19
  248. data/ext/enterprise_script_service/mruby/tasks/toolchains/visualcpp.rake +0 -12
  249. data/ext/enterprise_script_service/mruby/test/assert.rb +186 -25
  250. data/ext/enterprise_script_service/mruby/test/t/array.rb +34 -6
  251. data/ext/enterprise_script_service/mruby/test/t/class.rb +26 -0
  252. data/ext/enterprise_script_service/mruby/test/t/enumerable.rb +2 -2
  253. data/ext/enterprise_script_service/mruby/test/t/float.rb +17 -17
  254. data/ext/enterprise_script_service/mruby/test/t/hash.rb +2 -0
  255. data/ext/enterprise_script_service/mruby/test/t/integer.rb +14 -6
  256. data/ext/enterprise_script_service/mruby/test/t/kernel.rb +38 -19
  257. data/ext/enterprise_script_service/mruby/test/t/module.rb +87 -14
  258. data/ext/enterprise_script_service/mruby/test/t/numeric.rb +65 -23
  259. data/ext/enterprise_script_service/mruby/test/t/range.rb +4 -4
  260. data/ext/enterprise_script_service/mruby/test/t/string.rb +211 -49
  261. data/ext/enterprise_script_service/mruby/test/t/syntax.rb +19 -2
  262. data/ext/enterprise_script_service/mruby/test/t/vformat.rb +92 -0
  263. data/ext/enterprise_script_service/mruby/travis_config.rb +2 -2
  264. data/ext/enterprise_script_service/mruby_config.rb +10 -0
  265. data/ext/enterprise_script_service/mruby_engine.cpp +2 -2
  266. data/ext/enterprise_script_service/mruby_engine.gembox +1 -0
  267. data/ext/enterprise_script_service/msgpack/CHANGELOG.md +14 -0
  268. data/ext/enterprise_script_service/msgpack/Files.cmake +4 -0
  269. data/ext/enterprise_script_service/msgpack/README.md +1 -1
  270. data/ext/enterprise_script_service/msgpack/appveyor.yml +1 -1
  271. data/ext/enterprise_script_service/msgpack/erb/v1/cpp03_msgpack_tuple.hpp.erb +1 -1
  272. data/ext/enterprise_script_service/msgpack/erb/v1/cpp03_msgpack_tuple_decl.hpp.erb +1 -1
  273. data/ext/enterprise_script_service/msgpack/erb/v1/cpp03_zone.hpp.erb +3 -3
  274. data/ext/enterprise_script_service/msgpack/example/boost/asio_send_recv.cpp +1 -1
  275. data/ext/enterprise_script_service/msgpack/include/msgpack/adaptor/cpp11/timespec.hpp +16 -0
  276. data/ext/enterprise_script_service/msgpack/include/msgpack/adaptor/wstring.hpp +15 -0
  277. data/ext/enterprise_script_service/msgpack/include/msgpack/object.h +2 -0
  278. data/ext/enterprise_script_service/msgpack/include/msgpack/pack_template.h +17 -9
  279. data/ext/enterprise_script_service/msgpack/include/msgpack/sysdep.h +27 -16
  280. data/ext/enterprise_script_service/msgpack/include/msgpack/type.hpp +2 -0
  281. data/ext/enterprise_script_service/msgpack/include/msgpack/unpack_template.h +5 -0
  282. data/ext/enterprise_script_service/msgpack/include/msgpack/v1/adaptor/array_ref.hpp +0 -1
  283. data/ext/enterprise_script_service/msgpack/include/msgpack/v1/adaptor/check_container_size.hpp +1 -1
  284. data/ext/enterprise_script_service/msgpack/include/msgpack/v1/adaptor/cpp11/chrono.hpp +5 -5
  285. data/ext/enterprise_script_service/msgpack/include/msgpack/v1/adaptor/cpp11/timespec.hpp +140 -0
  286. data/ext/enterprise_script_service/msgpack/include/msgpack/v1/adaptor/detail/cpp03_msgpack_tuple.hpp +32 -32
  287. data/ext/enterprise_script_service/msgpack/include/msgpack/v1/adaptor/detail/cpp03_msgpack_tuple_decl.hpp +32 -32
  288. data/ext/enterprise_script_service/msgpack/include/msgpack/v1/adaptor/detail/cpp11_msgpack_tuple.hpp +6 -6
  289. data/ext/enterprise_script_service/msgpack/include/msgpack/v1/adaptor/detail/cpp11_msgpack_tuple_decl.hpp +10 -10
  290. data/ext/enterprise_script_service/msgpack/include/msgpack/v1/adaptor/ext.hpp +1 -1
  291. data/ext/enterprise_script_service/msgpack/include/msgpack/v1/adaptor/fixint.hpp +5 -4
  292. data/ext/enterprise_script_service/msgpack/include/msgpack/v1/adaptor/int.hpp +40 -13
  293. data/ext/enterprise_script_service/msgpack/include/msgpack/v1/adaptor/int_decl.hpp +3 -2
  294. data/ext/enterprise_script_service/msgpack/include/msgpack/v1/adaptor/wstring.hpp +121 -0
  295. data/ext/enterprise_script_service/msgpack/include/msgpack/v1/detail/cpp03_zone.hpp +3 -3
  296. data/ext/enterprise_script_service/msgpack/include/msgpack/v1/detail/cpp11_zone.hpp +3 -3
  297. data/ext/enterprise_script_service/msgpack/include/msgpack/v1/object.hpp +6 -6
  298. data/ext/enterprise_script_service/msgpack/include/msgpack/v1/object_fwd.hpp +1 -1
  299. data/ext/enterprise_script_service/msgpack/include/msgpack/v1/pack.hpp +40 -5
  300. data/ext/enterprise_script_service/msgpack/include/msgpack/v1/unpack.hpp +11 -11
  301. data/ext/enterprise_script_service/msgpack/include/msgpack/v1/vrefbuffer.hpp +7 -7
  302. data/ext/enterprise_script_service/msgpack/include/msgpack/v1/zbuffer.hpp +5 -5
  303. data/ext/enterprise_script_service/msgpack/include/msgpack/v2/adaptor/int_decl.hpp +1 -1
  304. data/ext/enterprise_script_service/msgpack/include/msgpack/v2/create_object_visitor.hpp +1 -1
  305. data/ext/enterprise_script_service/msgpack/include/msgpack/v2/parse.hpp +13 -13
  306. data/ext/enterprise_script_service/msgpack/include/msgpack/v2/x3_parse.hpp +28 -26
  307. data/ext/enterprise_script_service/msgpack/include/msgpack/v3/adaptor/int_decl.hpp +1 -1
  308. data/ext/enterprise_script_service/msgpack/include/msgpack/v3/parse.hpp +13 -13
  309. data/ext/enterprise_script_service/msgpack/include/msgpack/version_master.h +2 -2
  310. data/ext/enterprise_script_service/msgpack/include/msgpack/zbuffer.h +6 -6
  311. data/ext/enterprise_script_service/msgpack/include/msgpack/zone.h +1 -1
  312. data/ext/enterprise_script_service/msgpack/src/objectc.c +83 -148
  313. data/ext/enterprise_script_service/msgpack/src/unpack.c +73 -47
  314. data/ext/enterprise_script_service/msgpack/test/CMakeLists.txt +1 -1
  315. data/ext/enterprise_script_service/msgpack/test/array_ref.cpp +5 -0
  316. data/ext/enterprise_script_service/msgpack/test/boost_fusion.cpp +5 -0
  317. data/ext/enterprise_script_service/msgpack/test/boost_optional.cpp +7 -0
  318. data/ext/enterprise_script_service/msgpack/test/boost_string_ref.cpp +7 -0
  319. data/ext/enterprise_script_service/msgpack/test/boost_string_view.cpp +6 -0
  320. data/ext/enterprise_script_service/msgpack/test/boost_variant.cpp +15 -9
  321. data/ext/enterprise_script_service/msgpack/test/buffer.cpp +7 -0
  322. data/ext/enterprise_script_service/msgpack/test/carray.cpp +7 -0
  323. data/ext/enterprise_script_service/msgpack/test/cases.cpp +7 -1
  324. data/ext/enterprise_script_service/msgpack/test/convert.cpp +6 -0
  325. data/ext/enterprise_script_service/msgpack/test/fixint.cpp +7 -1
  326. data/ext/enterprise_script_service/msgpack/test/fixint_c.cpp +6 -1
  327. data/ext/enterprise_script_service/msgpack/test/fuzz_unpack_pack_fuzzer_cpp11.cpp +5 -0
  328. data/ext/enterprise_script_service/msgpack/test/iterator_cpp11.cpp +8 -2
  329. data/ext/enterprise_script_service/msgpack/test/json.cpp +6 -0
  330. data/ext/enterprise_script_service/msgpack/test/limit.cpp +7 -0
  331. data/ext/enterprise_script_service/msgpack/test/msgpack_basic.cpp +128 -6
  332. data/ext/enterprise_script_service/msgpack/test/msgpack_c.cpp +7 -2
  333. data/ext/enterprise_script_service/msgpack/test/msgpack_container.cpp +20 -3
  334. data/ext/enterprise_script_service/msgpack/test/msgpack_cpp11.cpp +159 -0
  335. data/ext/enterprise_script_service/msgpack/test/msgpack_cpp17.cpp +5 -0
  336. data/ext/enterprise_script_service/msgpack/test/msgpack_stream.cpp +8 -3
  337. data/ext/enterprise_script_service/msgpack/test/msgpack_tuple.cpp +6 -0
  338. data/ext/enterprise_script_service/msgpack/test/msgpack_vref.cpp +5 -0
  339. data/ext/enterprise_script_service/msgpack/test/msgpack_x3_parse.cpp +23 -18
  340. data/ext/enterprise_script_service/msgpack/test/object.cpp +77 -45
  341. data/ext/enterprise_script_service/msgpack/test/object_with_zone.cpp +28 -10
  342. data/ext/enterprise_script_service/msgpack/test/pack_unpack.cpp +25 -18
  343. data/ext/enterprise_script_service/msgpack/test/pack_unpack_c.cpp +7 -0
  344. data/ext/enterprise_script_service/msgpack/test/raw.cpp +17 -12
  345. data/ext/enterprise_script_service/msgpack/test/reference.cpp +6 -0
  346. data/ext/enterprise_script_service/msgpack/test/reference_cpp11.cpp +6 -0
  347. data/ext/enterprise_script_service/msgpack/test/reference_wrapper_cpp11.cpp +6 -0
  348. data/ext/enterprise_script_service/msgpack/test/shared_ptr_cpp11.cpp +6 -0
  349. data/ext/enterprise_script_service/msgpack/test/size_equal_only.cpp +6 -2
  350. data/ext/enterprise_script_service/msgpack/test/streaming.cpp +10 -3
  351. data/ext/enterprise_script_service/msgpack/test/streaming_c.cpp +7 -0
  352. data/ext/enterprise_script_service/msgpack/test/unique_ptr_cpp11.cpp +6 -0
  353. data/ext/enterprise_script_service/msgpack/test/user_class.cpp +5 -0
  354. data/ext/enterprise_script_service/msgpack/test/version.cpp +6 -0
  355. data/ext/enterprise_script_service/msgpack/test/visitor.cpp +7 -0
  356. data/ext/enterprise_script_service/msgpack/test/zone.cpp +6 -0
  357. data/lib/script_core/version.rb +1 -1
  358. data/lib/tasks/mruby/engine.gembox.example +1 -0
  359. data/lib/tasks/script_core.rake +21 -3
  360. data/spec/dummy/app/helpers/fields_helper.rb +2 -2
  361. data/spec/dummy/mruby/engine.gembox +1 -0
  362. data/spec/script_core_spec.rb +1 -1
  363. metadata +38 -22
  364. data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/.gitignore +0 -1
  365. data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/.travis.yml +0 -2
  366. data/ext/enterprise_script_service/mruby/mrbgems/mruby-io/run_test.rb +0 -26
  367. data/ext/enterprise_script_service/mruby/mrbgems/mruby-kernel-ext/mrblib/kernel.rb +0 -15
  368. data/ext/enterprise_script_service/mruby/mrbgems/mruby-method/mrblib/unbound_method.rb +0 -9
  369. data/ext/enterprise_script_service/mruby/mrbgems/mruby-pack/.gitignore +0 -5
  370. data/ext/enterprise_script_service/mruby/mrbgems/mruby-pack/.travis.yml +0 -2
  371. data/ext/enterprise_script_service/mruby/mrbgems/mruby-pack/packtest.rb +0 -157
  372. data/ext/enterprise_script_service/mruby/mrbgems/mruby-pack/run_test.rb +0 -26
  373. data/ext/enterprise_script_service/mruby/mrbgems/mruby-random/src/mt19937ar.c +0 -224
  374. data/ext/enterprise_script_service/mruby/mrbgems/mruby-random/src/mt19937ar.h +0 -80
  375. data/ext/enterprise_script_service/mruby/mrbgems/mruby-random/src/random.h +0 -12
  376. data/ext/enterprise_script_service/mruby/mrbgems/mruby-sleep/.gitignore +0 -4
  377. data/ext/enterprise_script_service/mruby/mrbgems/mruby-sleep/.travis.yml +0 -29
  378. data/ext/enterprise_script_service/mruby/mrbgems/mruby-sleep/.travis_build_config.rb +0 -6
  379. data/ext/enterprise_script_service/mruby/mrbgems/mruby-sleep/Rakefile +0 -29
  380. data/ext/enterprise_script_service/mruby/mrbgems/mruby-socket/.travis.yml +0 -4
  381. data/ext/enterprise_script_service/mruby/mrbgems/mruby-socket/run_test.rb +0 -28
@@ -42,10 +42,6 @@ mrb_open_core(mrb_allocf f, void *ud)
42
42
 
43
43
  mrb_init_core(mrb);
44
44
 
45
- #if !defined(MRB_DISABLE_STDIO) && defined(_MSC_VER) && _MSC_VER < 1900
46
- _set_output_format(_TWO_DIGIT_EXPONENT);
47
- #endif
48
-
49
45
  return mrb;
50
46
  }
51
47
 
@@ -61,38 +57,6 @@ mrb_default_allocf(mrb_state *mrb, void *p, size_t size, void *ud)
61
57
  }
62
58
  }
63
59
 
64
- struct alloca_header {
65
- struct alloca_header *next;
66
- char buf[1];
67
- };
68
-
69
- MRB_API void*
70
- mrb_alloca(mrb_state *mrb, size_t size)
71
- {
72
- struct alloca_header *p;
73
-
74
- p = (struct alloca_header*) mrb_malloc(mrb, sizeof(struct alloca_header)+size);
75
- p->next = mrb->mems;
76
- mrb->mems = p;
77
- return (void*)p->buf;
78
- }
79
-
80
- static void
81
- mrb_alloca_free(mrb_state *mrb)
82
- {
83
- struct alloca_header *p;
84
- struct alloca_header *tmp;
85
-
86
- if (mrb == NULL) return;
87
- p = mrb->mems;
88
-
89
- while (p) {
90
- tmp = p;
91
- p = p->next;
92
- mrb_free(mrb, tmp);
93
- }
94
- }
95
-
96
60
  MRB_API mrb_state*
97
61
  mrb_open(void)
98
62
  {
@@ -153,14 +117,14 @@ mrb_irep_free(mrb_state *mrb, mrb_irep *irep)
153
117
  int i;
154
118
 
155
119
  if (!(irep->flags & MRB_ISEQ_NO_FREE))
156
- mrb_free(mrb, irep->iseq);
120
+ mrb_free(mrb, (void*)irep->iseq);
157
121
  if (irep->pool) for (i=0; i<irep->plen; i++) {
158
- if (mrb_type(irep->pool[i]) == MRB_TT_STRING) {
122
+ if (mrb_string_p(irep->pool[i])) {
159
123
  mrb_gc_free_str(mrb, RSTRING(irep->pool[i]));
160
124
  mrb_free(mrb, mrb_obj_ptr(irep->pool[i]));
161
125
  }
162
126
  #if defined(MRB_WORD_BOXING) && !defined(MRB_WITHOUT_FLOAT)
163
- else if (mrb_type(irep->pool[i]) == MRB_TT_FLOAT) {
127
+ else if (mrb_float_p(irep->pool[i])) {
164
128
  mrb_free(mrb, mrb_obj_ptr(irep->pool[i]));
165
129
  }
166
130
  #endif
@@ -177,58 +141,6 @@ mrb_irep_free(mrb_state *mrb, mrb_irep *irep)
177
141
  mrb_free(mrb, irep);
178
142
  }
179
143
 
180
- mrb_value
181
- mrb_str_pool(mrb_state *mrb, mrb_value str)
182
- {
183
- struct RString *s = mrb_str_ptr(str);
184
- struct RString *ns;
185
- char *ptr;
186
- mrb_int len;
187
-
188
- ns = (struct RString *)mrb_malloc(mrb, sizeof(struct RString));
189
- ns->tt = MRB_TT_STRING;
190
- ns->c = mrb->string_class;
191
-
192
- if (RSTR_NOFREE_P(s)) {
193
- ns->flags = MRB_STR_NOFREE;
194
- ns->as.heap.ptr = s->as.heap.ptr;
195
- ns->as.heap.len = s->as.heap.len;
196
- ns->as.heap.aux.capa = 0;
197
- }
198
- else {
199
- ns->flags = 0;
200
- if (RSTR_EMBED_P(s)) {
201
- ptr = s->as.ary;
202
- len = RSTR_EMBED_LEN(s);
203
- }
204
- else {
205
- ptr = s->as.heap.ptr;
206
- len = s->as.heap.len;
207
- }
208
-
209
- if (len < RSTRING_EMBED_LEN_MAX) {
210
- RSTR_SET_EMBED_FLAG(ns);
211
- RSTR_SET_EMBED_LEN(ns, len);
212
- if (ptr) {
213
- memcpy(ns->as.ary, ptr, len);
214
- }
215
- ns->as.ary[len] = '\0';
216
- }
217
- else {
218
- ns->as.heap.ptr = (char *)mrb_malloc(mrb, (size_t)len+1);
219
- ns->as.heap.len = len;
220
- ns->as.heap.aux.capa = len;
221
- if (ptr) {
222
- memcpy(ns->as.heap.ptr, ptr, len);
223
- }
224
- ns->as.heap.ptr[len] = '\0';
225
- }
226
- }
227
- RSTR_SET_POOL_FLAG(ns);
228
- MRB_SET_FROZEN_FLAG(ns);
229
- return mrb_obj_value(ns);
230
- }
231
-
232
144
  void mrb_free_backtrace(mrb_state *mrb);
233
145
 
234
146
  MRB_API void
@@ -257,11 +169,10 @@ mrb_close(mrb_state *mrb)
257
169
  }
258
170
 
259
171
  /* free */
260
- mrb_gc_free_gv(mrb);
172
+ mrb_gc_destroy(mrb, &mrb->gc);
261
173
  mrb_free_context(mrb, mrb->root_c);
174
+ mrb_gc_free_gv(mrb);
262
175
  mrb_free_symtbl(mrb);
263
- mrb_alloca_free(mrb);
264
- mrb_gc_destroy(mrb, &mrb->gc);
265
176
  mrb_free(mrb, mrb);
266
177
  }
267
178
 
@@ -21,13 +21,11 @@
21
21
  #include <mruby/range.h>
22
22
  #include <mruby/string.h>
23
23
  #include <mruby/numeric.h>
24
- #include <mruby/re.h>
25
24
 
26
25
  typedef struct mrb_shared_string {
27
- mrb_bool nofree : 1;
28
26
  int refcnt;
27
+ mrb_ssize capa;
29
28
  char *ptr;
30
- mrb_int len;
31
29
  } mrb_shared_string;
32
30
 
33
31
  const char mrb_digitmap[] = "0123456789abcdefghijklmnopqrstuvwxyz";
@@ -35,55 +33,114 @@ const char mrb_digitmap[] = "0123456789abcdefghijklmnopqrstuvwxyz";
35
33
  #define mrb_obj_alloc_string(mrb) ((struct RString*)mrb_obj_alloc((mrb), MRB_TT_STRING, (mrb)->string_class))
36
34
 
37
35
  static struct RString*
38
- str_new_static(mrb_state *mrb, const char *p, size_t len)
36
+ str_init_normal_capa(mrb_state *mrb, struct RString *s,
37
+ const char *p, size_t len, size_t capa)
38
+ {
39
+ char *dst = (char *)mrb_malloc(mrb, capa + 1);
40
+ if (p) memcpy(dst, p, len);
41
+ dst[len] = '\0';
42
+ s->as.heap.ptr = dst;
43
+ s->as.heap.len = (mrb_ssize)len;
44
+ s->as.heap.aux.capa = (mrb_ssize)capa;
45
+ RSTR_UNSET_TYPE_FLAG(s);
46
+ return s;
47
+ }
48
+
49
+ static struct RString*
50
+ str_init_normal(mrb_state *mrb, struct RString *s, const char *p, size_t len)
39
51
  {
40
- struct RString *s;
52
+ return str_init_normal_capa(mrb, s, p, len, len);
53
+ }
41
54
 
42
- if (len >= MRB_INT_MAX) {
43
- mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
44
- }
45
- s = mrb_obj_alloc_string(mrb);
46
- s->as.heap.len = (mrb_int)len;
47
- s->as.heap.aux.capa = 0; /* nofree */
55
+ static struct RString*
56
+ str_init_embed(struct RString *s, const char *p, size_t len)
57
+ {
58
+ if (p) memcpy(RSTR_EMBED_PTR(s), p, len);
59
+ RSTR_EMBED_PTR(s)[len] = '\0';
60
+ RSTR_SET_TYPE_FLAG(s, EMBED);
61
+ RSTR_SET_EMBED_LEN(s, len);
62
+ return s;
63
+ }
64
+
65
+ static struct RString*
66
+ str_init_nofree(struct RString *s, const char *p, size_t len)
67
+ {
48
68
  s->as.heap.ptr = (char *)p;
49
- s->flags = MRB_STR_NOFREE;
69
+ s->as.heap.len = (mrb_ssize)len;
70
+ s->as.heap.aux.capa = 0; /* nofree */
71
+ RSTR_SET_TYPE_FLAG(s, NOFREE);
72
+ return s;
73
+ }
50
74
 
75
+ static struct RString*
76
+ str_init_shared(mrb_state *mrb, const struct RString *orig, struct RString *s, mrb_shared_string *shared)
77
+ {
78
+ if (shared) {
79
+ shared->refcnt++;
80
+ }
81
+ else {
82
+ shared = (mrb_shared_string *)mrb_malloc(mrb, sizeof(mrb_shared_string));
83
+ shared->refcnt = 1;
84
+ shared->ptr = orig->as.heap.ptr;
85
+ shared->capa = orig->as.heap.aux.capa;
86
+ }
87
+ s->as.heap.ptr = orig->as.heap.ptr;
88
+ s->as.heap.len = orig->as.heap.len;
89
+ s->as.heap.aux.shared = shared;
90
+ RSTR_SET_TYPE_FLAG(s, SHARED);
51
91
  return s;
52
92
  }
53
93
 
54
94
  static struct RString*
55
- str_new(mrb_state *mrb, const char *p, size_t len)
95
+ str_init_fshared(const struct RString *orig, struct RString *s, struct RString *fshared)
56
96
  {
57
- struct RString *s;
97
+ s->as.heap.ptr = orig->as.heap.ptr;
98
+ s->as.heap.len = orig->as.heap.len;
99
+ s->as.heap.aux.fshared = fshared;
100
+ RSTR_SET_TYPE_FLAG(s, FSHARED);
101
+ return s;
102
+ }
58
103
 
59
- if (p && mrb_ro_data_p(p)) {
60
- return str_new_static(mrb, p, len);
61
- }
62
- s = mrb_obj_alloc_string(mrb);
63
- if (len <= RSTRING_EMBED_LEN_MAX) {
64
- RSTR_SET_EMBED_FLAG(s);
65
- RSTR_SET_EMBED_LEN(s, len);
66
- if (p) {
67
- memcpy(s->as.ary, p, len);
68
- }
104
+ static struct RString*
105
+ str_init_modifiable(mrb_state *mrb, struct RString *s, const char *p, size_t len)
106
+ {
107
+ if (RSTR_EMBEDDABLE_P(len)) {
108
+ return str_init_embed(s, p, len);
69
109
  }
70
110
  else {
71
- if (len >= MRB_INT_MAX) {
72
- mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
73
- }
74
- s->as.heap.ptr = (char *)mrb_malloc(mrb, len+1);
75
- s->as.heap.len = (mrb_int)len;
76
- s->as.heap.aux.capa = (mrb_int)len;
77
- if (p) {
78
- memcpy(s->as.heap.ptr, p, len);
79
- }
111
+ return str_init_normal(mrb, s, p, len);
80
112
  }
81
- RSTR_PTR(s)[len] = '\0';
82
- return s;
113
+ }
114
+
115
+ static struct RString*
116
+ str_new_static(mrb_state *mrb, const char *p, size_t len)
117
+ {
118
+ if (RSTR_EMBEDDABLE_P(len)) {
119
+ return str_init_embed(mrb_obj_alloc_string(mrb), p, len);
120
+ }
121
+ if (len >= MRB_SSIZE_MAX) {
122
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
123
+ }
124
+ return str_init_nofree(mrb_obj_alloc_string(mrb), p, len);
125
+ }
126
+
127
+ static struct RString*
128
+ str_new(mrb_state *mrb, const char *p, size_t len)
129
+ {
130
+ if (RSTR_EMBEDDABLE_P(len)) {
131
+ return str_init_embed(mrb_obj_alloc_string(mrb), p, len);
132
+ }
133
+ if (len >= MRB_SSIZE_MAX) {
134
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
135
+ }
136
+ if (p && mrb_ro_data_p(p)) {
137
+ return str_init_nofree(mrb_obj_alloc_string(mrb), p, len);
138
+ }
139
+ return str_init_normal(mrb, mrb_obj_alloc_string(mrb), p, len);
83
140
  }
84
141
 
85
142
  static inline void
86
- str_with_class(mrb_state *mrb, struct RString *s, mrb_value obj)
143
+ str_with_class(struct RString *s, mrb_value obj)
87
144
  {
88
145
  s->c = mrb_str_ptr(obj)->c;
89
146
  }
@@ -93,7 +150,7 @@ mrb_str_new_empty(mrb_state *mrb, mrb_value str)
93
150
  {
94
151
  struct RString *s = str_new(mrb, 0, 0);
95
152
 
96
- str_with_class(mrb, s, str);
153
+ str_with_class(s, str);
97
154
  return mrb_obj_value(s);
98
155
  }
99
156
 
@@ -102,15 +159,17 @@ mrb_str_new_capa(mrb_state *mrb, size_t capa)
102
159
  {
103
160
  struct RString *s;
104
161
 
105
- s = mrb_obj_alloc_string(mrb);
106
-
107
- if (capa >= MRB_INT_MAX) {
162
+ if (RSTR_EMBEDDABLE_P(capa)) {
163
+ s = str_init_embed(mrb_obj_alloc_string(mrb), NULL, 0);
164
+ }
165
+ else if (capa >= MRB_SSIZE_MAX) {
108
166
  mrb_raise(mrb, E_ARGUMENT_ERROR, "string capacity size too big");
167
+ /* not reached */
168
+ s = NULL;
169
+ }
170
+ else {
171
+ s = str_init_normal_capa(mrb, mrb_obj_alloc_string(mrb), NULL, 0, capa);
109
172
  }
110
- s->as.heap.len = 0;
111
- s->as.heap.aux.capa = (mrb_int)capa;
112
- s->as.heap.ptr = (char *)mrb_malloc(mrb, capa+1);
113
- RSTR_PTR(s)[0] = '\0';
114
173
 
115
174
  return mrb_obj_value(s);
116
175
  }
@@ -131,23 +190,17 @@ mrb_str_buf_new(mrb_state *mrb, size_t capa)
131
190
  static void
132
191
  resize_capa(mrb_state *mrb, struct RString *s, size_t capacity)
133
192
  {
134
- #if SIZE_MAX > MRB_INT_MAX
135
- mrb_assert(capacity < MRB_INT_MAX);
193
+ #if SIZE_MAX > MRB_SSIZE_MAX
194
+ mrb_assert(capacity < MRB_SSIZE_MAX);
136
195
  #endif
137
196
  if (RSTR_EMBED_P(s)) {
138
- if (RSTRING_EMBED_LEN_MAX < capacity) {
139
- char *const tmp = (char *)mrb_malloc(mrb, capacity+1);
140
- const mrb_int len = RSTR_EMBED_LEN(s);
141
- memcpy(tmp, s->as.ary, len);
142
- RSTR_UNSET_EMBED_FLAG(s);
143
- s->as.heap.ptr = tmp;
144
- s->as.heap.len = len;
145
- s->as.heap.aux.capa = (mrb_int)capacity;
197
+ if (!RSTR_EMBEDDABLE_P(capacity)) {
198
+ str_init_normal_capa(mrb, s, RSTR_EMBED_PTR(s), RSTR_EMBED_LEN(s), capacity);
146
199
  }
147
200
  }
148
201
  else {
149
202
  s->as.heap.ptr = (char*)mrb_realloc(mrb, RSTR_PTR(s), capacity+1);
150
- s->as.heap.aux.capa = (mrb_int)capacity;
203
+ s->as.heap.aux.capa = (mrb_ssize)capacity;
151
204
  }
152
205
  }
153
206
 
@@ -187,13 +240,42 @@ str_decref(mrb_state *mrb, mrb_shared_string *shared)
187
240
  {
188
241
  shared->refcnt--;
189
242
  if (shared->refcnt == 0) {
190
- if (!shared->nofree) {
191
- mrb_free(mrb, shared->ptr);
192
- }
243
+ mrb_free(mrb, shared->ptr);
193
244
  mrb_free(mrb, shared);
194
245
  }
195
246
  }
196
247
 
248
+ static void
249
+ str_modify_keep_ascii(mrb_state *mrb, struct RString *s)
250
+ {
251
+ if (RSTR_SHARED_P(s)) {
252
+ mrb_shared_string *shared = s->as.heap.aux.shared;
253
+
254
+ if (shared->refcnt == 1 && s->as.heap.ptr == shared->ptr) {
255
+ s->as.heap.aux.capa = shared->capa;
256
+ s->as.heap.ptr[s->as.heap.len] = '\0';
257
+ RSTR_UNSET_SHARED_FLAG(s);
258
+ mrb_free(mrb, shared);
259
+ }
260
+ else {
261
+ str_init_modifiable(mrb, s, s->as.heap.ptr, (size_t)s->as.heap.len);
262
+ str_decref(mrb, shared);
263
+ }
264
+ }
265
+ else if (RSTR_NOFREE_P(s) || RSTR_FSHARED_P(s)) {
266
+ str_init_modifiable(mrb, s, s->as.heap.ptr, (size_t)s->as.heap.len);
267
+ }
268
+ }
269
+
270
+ static void
271
+ check_null_byte(mrb_state *mrb, mrb_value str)
272
+ {
273
+ mrb_to_str(mrb, str);
274
+ if (memchr(RSTRING_PTR(str), '\0', RSTRING_LEN(str))) {
275
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte");
276
+ }
277
+ }
278
+
197
279
  void
198
280
  mrb_gc_free_str(mrb_state *mrb, struct RString *str)
199
281
  {
@@ -224,8 +306,10 @@ utf8len(const char* p, const char* e)
224
306
  mrb_int len;
225
307
  mrb_int i;
226
308
 
309
+ if ((unsigned char)*p < 0x80) return 1;
227
310
  len = utf8len_codepage[(unsigned char)*p];
228
- if (p + len > e) return 1;
311
+ if (len == 1) return 1;
312
+ if (len > e - p) return 1;
229
313
  for (i = 1; i < len; ++i)
230
314
  if ((p[i] & 0xc0) != 0x80)
231
315
  return 1;
@@ -249,14 +333,15 @@ mrb_utf8_len(const char *str, mrb_int byte_len)
249
333
  static mrb_int
250
334
  utf8_strlen(mrb_value str)
251
335
  {
252
- mrb_int byte_len = RSTRING_LEN(str);
336
+ struct RString *s = mrb_str_ptr(str);
337
+ mrb_int byte_len = RSTR_LEN(s);
253
338
 
254
- if (RSTRING(str)->flags & MRB_STR_NO_UTF) {
339
+ if (RSTR_ASCII_P(s)) {
255
340
  return byte_len;
256
341
  }
257
342
  else {
258
- mrb_int utf8_len = mrb_utf8_len(RSTRING_PTR(str), byte_len);
259
- if (byte_len == utf8_len) RSTRING(str)->flags |= MRB_STR_NO_UTF;
343
+ mrb_int utf8_len = mrb_utf8_len(RSTR_PTR(s), byte_len);
344
+ if (byte_len == utf8_len) RSTR_SET_ASCII_FLAG(s);
260
345
  return utf8_len;
261
346
  }
262
347
  }
@@ -267,39 +352,155 @@ utf8_strlen(mrb_value str)
267
352
  static mrb_int
268
353
  chars2bytes(mrb_value s, mrb_int off, mrb_int idx)
269
354
  {
270
- mrb_int i, b, n;
271
- const char *p = RSTRING_PTR(s) + off;
272
- const char *e = RSTRING_END(s);
355
+ if (RSTR_ASCII_P(mrb_str_ptr(s))) {
356
+ return idx;
357
+ }
358
+ else {
359
+ mrb_int i, b, n;
360
+ const char *p = RSTRING_PTR(s) + off;
361
+ const char *e = RSTRING_END(s);
273
362
 
274
- for (b=i=0; p<e && i<idx; i++) {
275
- n = utf8len(p, e);
276
- b += n;
277
- p += n;
363
+ for (b=i=0; p<e && i<idx; i++) {
364
+ n = utf8len(p, e);
365
+ b += n;
366
+ p += n;
367
+ }
368
+ return b;
278
369
  }
279
- return b;
280
370
  }
281
371
 
282
372
  /* map byte offset to character index */
283
373
  static mrb_int
284
- bytes2chars(char *p, mrb_int bi)
374
+ bytes2chars(char *p, mrb_int len, mrb_int bi)
285
375
  {
286
- mrb_int i, b, n;
376
+ const char *e = p + (size_t)len;
377
+ const char *pivot = p + bi;
378
+ mrb_int i;
287
379
 
288
- for (b=i=0; b<bi; i++) {
289
- n = utf8len_codepage[(unsigned char)*p];
290
- b += n;
291
- p += n;
380
+ for (i = 0; p < pivot; i ++) {
381
+ p += utf8len(p, e);
292
382
  }
293
- if (b != bi) return -1;
383
+ if (p != pivot) return -1;
294
384
  return i;
295
385
  }
296
386
 
387
+ static const char *
388
+ char_adjust(const char *beg, const char *end, const char *ptr)
389
+ {
390
+ if ((ptr > beg || ptr < end) && (*ptr & 0xc0) == 0x80) {
391
+ const int utf8_adjust_max = 3;
392
+ const char *p;
393
+
394
+ if (ptr - beg > utf8_adjust_max) {
395
+ beg = ptr - utf8_adjust_max;
396
+ }
397
+
398
+ p = ptr;
399
+ while (p > beg) {
400
+ p --;
401
+ if ((*p & 0xc0) != 0x80) {
402
+ int clen = utf8len(p, end);
403
+ if (clen > ptr - p) return p;
404
+ break;
405
+ }
406
+ }
407
+ }
408
+
409
+ return ptr;
410
+ }
411
+
412
+ static const char *
413
+ char_backtrack(const char *ptr, const char *end)
414
+ {
415
+ if (ptr < end) {
416
+ const int utf8_bytelen_max = 4;
417
+ const char *p;
418
+
419
+ if (end - ptr > utf8_bytelen_max) {
420
+ ptr = end - utf8_bytelen_max;
421
+ }
422
+
423
+ p = end;
424
+ while (p > ptr) {
425
+ p --;
426
+ if ((*p & 0xc0) != 0x80) {
427
+ int clen = utf8len_codepage[(unsigned char)*p];
428
+ if (clen == end - p) { return p; }
429
+ break;
430
+ }
431
+ }
432
+ }
433
+
434
+ return end - 1;
435
+ }
436
+
437
+ static mrb_int
438
+ str_index_str_by_char_search(mrb_state *mrb, const char *p, const char *pend, const char *s, const mrb_int slen, mrb_int off)
439
+ {
440
+ /* Based on Quick Search algorithm (Boyer-Moore-Horspool algorithm) */
441
+
442
+ ptrdiff_t qstable[1 << CHAR_BIT];
443
+
444
+ /* Preprocessing */
445
+ {
446
+ mrb_int i;
447
+
448
+ for (i = 0; i < 1 << CHAR_BIT; i ++) {
449
+ qstable[i] = slen;
450
+ }
451
+ for (i = 0; i < slen; i ++) {
452
+ qstable[(unsigned char)s[i]] = slen - (i + 1);
453
+ }
454
+ }
455
+
456
+ /* Searching */
457
+ while (p < pend && pend - p >= slen) {
458
+ const char *pivot;
459
+
460
+ if (memcmp(p, s, slen) == 0) {
461
+ return off;
462
+ }
463
+
464
+ pivot = p + qstable[(unsigned char)p[slen - 1]];
465
+ if (pivot > pend || pivot < p /* overflowed */) { return -1; }
466
+
467
+ do {
468
+ p += utf8len(p, pend);
469
+ off ++;
470
+ } while (p < pivot);
471
+ }
472
+
473
+ return -1;
474
+ }
475
+
476
+ static mrb_int
477
+ str_index_str_by_char(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos)
478
+ {
479
+ const char *p = RSTRING_PTR(str);
480
+ const char *pend = p + RSTRING_LEN(str);
481
+ const char *s = RSTRING_PTR(sub);
482
+ const mrb_int slen = RSTRING_LEN(sub);
483
+ mrb_int off = pos;
484
+
485
+ for (; pos > 0; pos --) {
486
+ if (pend - p < 1) { return -1; }
487
+ p += utf8len(p, pend);
488
+ }
489
+
490
+ if (slen < 1) { return off; }
491
+
492
+ return str_index_str_by_char_search(mrb, p, pend, s, slen, off);
493
+ }
494
+
297
495
  #define BYTES_ALIGN_CHECK(pos) if (pos < 0) return mrb_nil_value();
298
496
  #else
299
497
  #define RSTRING_CHAR_LEN(s) RSTRING_LEN(s)
300
498
  #define chars2bytes(p, off, ci) (ci)
301
- #define bytes2chars(p, bi) (bi)
499
+ #define bytes2chars(p, end, bi) (bi)
500
+ #define char_adjust(beg, end, ptr) (ptr)
501
+ #define char_backtrack(ptr, end) ((end) - 1)
302
502
  #define BYTES_ALIGN_CHECK(pos)
503
+ #define str_index_str_by_char(mrb, str, sub, pos) str_index_str(mrb, str, sub, pos)
303
504
  #endif
304
505
 
305
506
  static inline mrb_int
@@ -347,113 +548,116 @@ mrb_memsearch(const void *x0, mrb_int m, const void *y0, mrb_int n)
347
548
  }
348
549
 
349
550
  static void
350
- str_make_shared(mrb_state *mrb, struct RString *orig, struct RString *s)
551
+ str_share(mrb_state *mrb, struct RString *orig, struct RString *s)
351
552
  {
352
- mrb_shared_string *shared;
353
- mrb_int len = RSTR_LEN(orig);
553
+ size_t len = (size_t)orig->as.heap.len;
354
554
 
355
555
  mrb_assert(!RSTR_EMBED_P(orig));
356
- if (RSTR_SHARED_P(orig)) {
357
- shared = orig->as.heap.aux.shared;
358
- shared->refcnt++;
359
- s->as.heap.ptr = orig->as.heap.ptr;
360
- s->as.heap.len = len;
361
- s->as.heap.aux.shared = shared;
362
- RSTR_SET_SHARED_FLAG(s);
363
- RSTR_UNSET_EMBED_FLAG(s);
556
+ if (RSTR_NOFREE_P(orig) || RSTR_POOL_P(orig)) {
557
+ str_init_nofree(s, orig->as.heap.ptr, len);
558
+ }
559
+ else if (RSTR_SHARED_P(orig)) {
560
+ str_init_shared(mrb, orig, s, orig->as.heap.aux.shared);
364
561
  }
365
562
  else if (RSTR_FSHARED_P(orig)) {
366
- struct RString *fs;
367
-
368
- fs = orig->as.heap.aux.fshared;
369
- s->as.heap.ptr = orig->as.heap.ptr;
370
- s->as.heap.len = len;
371
- s->as.heap.aux.fshared = fs;
372
- RSTR_SET_FSHARED_FLAG(s);
373
- RSTR_UNSET_EMBED_FLAG(s);
374
- }
375
- else if (MRB_FROZEN_P(orig) && !RSTR_POOL_P(orig)) {
376
- s->as.heap.ptr = orig->as.heap.ptr;
377
- s->as.heap.len = len;
378
- s->as.heap.aux.fshared = orig;
379
- RSTR_SET_FSHARED_FLAG(s);
380
- RSTR_UNSET_EMBED_FLAG(s);
563
+ str_init_fshared(orig, s, orig->as.heap.aux.fshared);
564
+ }
565
+ else if (mrb_frozen_p(orig)) {
566
+ str_init_fshared(orig, s, orig);
381
567
  }
382
568
  else {
383
- shared = (mrb_shared_string *)mrb_malloc(mrb, sizeof(mrb_shared_string));
384
- shared->refcnt = 2;
385
- shared->nofree = !!RSTR_NOFREE_P(orig);
386
- if (!shared->nofree && orig->as.heap.aux.capa > orig->as.heap.len) {
387
- shared->ptr = (char *)mrb_realloc(mrb, orig->as.heap.ptr, len+1);
388
- orig->as.heap.ptr = shared->ptr;
389
- }
390
- else {
391
- shared->ptr = orig->as.heap.ptr;
569
+ if (orig->as.heap.aux.capa > orig->as.heap.len) {
570
+ orig->as.heap.ptr = (char *)mrb_realloc(mrb, orig->as.heap.ptr, len+1);
571
+ orig->as.heap.aux.capa = (mrb_ssize)len;
392
572
  }
393
- orig->as.heap.aux.shared = shared;
394
- RSTR_SET_SHARED_FLAG(orig);
395
- shared->len = len;
396
- s->as.heap.aux.shared = shared;
397
- s->as.heap.ptr = shared->ptr;
398
- s->as.heap.len = len;
399
- RSTR_SET_SHARED_FLAG(s);
400
- RSTR_UNSET_EMBED_FLAG(s);
573
+ str_init_shared(mrb, orig, s, NULL);
574
+ str_init_shared(mrb, orig, orig, s->as.heap.aux.shared);
401
575
  }
402
576
  }
403
577
 
404
- static mrb_value
405
- byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len)
578
+ mrb_value
579
+ mrb_str_pool(mrb_state *mrb, mrb_value str)
580
+ {
581
+ struct RString *s = (struct RString *)mrb_malloc(mrb, sizeof(struct RString));
582
+ struct RString *orig = mrb_str_ptr(str);
583
+ const char *p = RSTR_PTR(orig);
584
+ size_t len = (size_t)RSTR_LEN(orig);
585
+
586
+ s->tt = MRB_TT_STRING;
587
+ s->c = mrb->string_class;
588
+ s->flags = 0;
589
+
590
+ if (RSTR_EMBEDDABLE_P(len)) {
591
+ str_init_embed(s, p, len);
592
+ }
593
+ else if (RSTR_NOFREE_P(orig)) {
594
+ str_init_nofree(s, p, len);
595
+ }
596
+ else {
597
+ str_init_normal(mrb, s, p, len);
598
+ }
599
+ RSTR_SET_POOL_FLAG(s);
600
+ MRB_SET_FROZEN_FLAG(s);
601
+ return mrb_obj_value(s);
602
+ }
603
+
604
+ mrb_value
605
+ mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len)
406
606
  {
407
607
  struct RString *orig, *s;
408
608
 
409
609
  orig = mrb_str_ptr(str);
410
- if (RSTR_EMBED_P(orig) || RSTR_LEN(orig) == 0 || len <= RSTRING_EMBED_LEN_MAX) {
411
- s = str_new(mrb, RSTR_PTR(orig)+beg, len);
610
+ s = mrb_obj_alloc_string(mrb);
611
+ if (RSTR_EMBEDDABLE_P(len)) {
612
+ str_init_embed(s, RSTR_PTR(orig)+beg, len);
412
613
  }
413
614
  else {
414
- s = mrb_obj_alloc_string(mrb);
415
- str_make_shared(mrb, orig, s);
416
- s->as.heap.ptr += beg;
417
- s->as.heap.len = len;
615
+ str_share(mrb, orig, s);
616
+ s->as.heap.ptr += (mrb_ssize)beg;
617
+ s->as.heap.len = (mrb_ssize)len;
418
618
  }
619
+ RSTR_COPY_ASCII_FLAG(s, orig);
419
620
  return mrb_obj_value(s);
420
621
  }
622
+
623
+ static void
624
+ str_range_to_bytes(mrb_value str, mrb_int *pos, mrb_int *len)
625
+ {
626
+ *pos = chars2bytes(str, 0, *pos);
627
+ *len = chars2bytes(str, *pos, *len);
628
+ }
421
629
  #ifdef MRB_UTF8_STRING
422
630
  static inline mrb_value
423
631
  str_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len)
424
632
  {
425
- beg = chars2bytes(str, 0, beg);
426
- len = chars2bytes(str, beg, len);
427
-
428
- return byte_subseq(mrb, str, beg, len);
633
+ str_range_to_bytes(str, &beg, &len);
634
+ return mrb_str_byte_subseq(mrb, str, beg, len);
429
635
  }
430
636
  #else
431
- #define str_subseq(mrb, str, beg, len) byte_subseq(mrb, str, beg, len)
637
+ #define str_subseq(mrb, str, beg, len) mrb_str_byte_subseq(mrb, str, beg, len)
432
638
  #endif
433
639
 
434
- static mrb_value
435
- str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len)
640
+ mrb_bool
641
+ mrb_str_beg_len(mrb_int str_len, mrb_int *begp, mrb_int *lenp)
436
642
  {
437
- mrb_int clen = RSTRING_CHAR_LEN(str);
438
-
439
- if (len < 0) return mrb_nil_value();
440
- if (clen == 0) {
441
- len = 0;
442
- }
443
- else if (beg < 0) {
444
- beg = clen + beg;
643
+ if (str_len < *begp || *lenp < 0) return FALSE;
644
+ if (*begp < 0) {
645
+ *begp += str_len;
646
+ if (*begp < 0) return FALSE;
445
647
  }
446
- if (beg > clen) return mrb_nil_value();
447
- if (beg < 0) {
448
- beg += clen;
449
- if (beg < 0) return mrb_nil_value();
648
+ if (*lenp > str_len - *begp)
649
+ *lenp = str_len - *begp;
650
+ if (*lenp <= 0) {
651
+ *lenp = 0;
450
652
  }
451
- if (len > clen - beg)
452
- len = clen - beg;
453
- if (len <= 0) {
454
- len = 0;
455
- }
456
- return str_subseq(mrb, str, beg, len);
653
+ return TRUE;
654
+ }
655
+
656
+ static mrb_value
657
+ str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len)
658
+ {
659
+ return mrb_str_beg_len(RSTRING_CHAR_LEN(str), &beg, &len) ?
660
+ str_subseq(mrb, str, beg, len) : mrb_nil_value();
457
661
  }
458
662
 
459
663
  MRB_API mrb_int
@@ -493,44 +697,28 @@ str_index_str(mrb_state *mrb, mrb_value str, mrb_value str2, mrb_int offset)
493
697
  return mrb_str_index(mrb, str, ptr, len, offset);
494
698
  }
495
699
 
496
- static void
497
- check_frozen(mrb_state *mrb, struct RString *s)
498
- {
499
- if (MRB_FROZEN_P(s)) {
500
- mrb_raise(mrb, E_FROZEN_ERROR, "can't modify frozen string");
501
- }
502
- }
503
-
504
700
  static mrb_value
505
701
  str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2)
506
702
  {
507
- mrb_int len;
703
+ size_t len;
508
704
 
509
- check_frozen(mrb, s1);
705
+ mrb_check_frozen(mrb, s1);
510
706
  if (s1 == s2) return mrb_obj_value(s1);
511
- s1->flags &= ~MRB_STR_NO_UTF;
512
- s1->flags |= s2->flags&MRB_STR_NO_UTF;
513
- len = RSTR_LEN(s2);
707
+ RSTR_COPY_ASCII_FLAG(s1, s2);
514
708
  if (RSTR_SHARED_P(s1)) {
515
709
  str_decref(mrb, s1->as.heap.aux.shared);
516
- RSTR_UNSET_SHARED_FLAG(s1);
517
710
  }
518
711
  else if (!RSTR_EMBED_P(s1) && !RSTR_NOFREE_P(s1) && !RSTR_FSHARED_P(s1)
519
712
  && s1->as.heap.ptr) {
520
713
  mrb_free(mrb, s1->as.heap.ptr);
521
714
  }
522
715
 
523
- RSTR_UNSET_FSHARED_FLAG(s1);
524
- RSTR_UNSET_NOFREE_FLAG(s1);
525
- if (len <= RSTRING_EMBED_LEN_MAX) {
526
- RSTR_UNSET_SHARED_FLAG(s1);
527
- RSTR_UNSET_FSHARED_FLAG(s1);
528
- RSTR_SET_EMBED_FLAG(s1);
529
- memcpy(s1->as.ary, RSTR_PTR(s2), len);
530
- RSTR_SET_EMBED_LEN(s1, len);
716
+ len = (size_t)RSTR_LEN(s2);
717
+ if (RSTR_EMBEDDABLE_P(len)) {
718
+ str_init_embed(s1, RSTR_PTR(s2), len);
531
719
  }
532
720
  else {
533
- str_make_shared(mrb, s2, s1);
721
+ str_share(mrb, s2, s1);
534
722
  }
535
723
 
536
724
  return mrb_obj_value(s1);
@@ -539,7 +727,7 @@ str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2)
539
727
  static mrb_int
540
728
  str_rindex(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos)
541
729
  {
542
- char *s, *sbeg, *t;
730
+ const char *s, *sbeg, *t;
543
731
  struct RString *ps = mrb_str_ptr(str);
544
732
  mrb_int len = RSTRING_LEN(sub);
545
733
 
@@ -552,11 +740,12 @@ str_rindex(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos)
552
740
  s = RSTR_PTR(ps) + pos;
553
741
  t = RSTRING_PTR(sub);
554
742
  if (len) {
743
+ s = char_adjust(sbeg, sbeg + RSTR_LEN(ps), s);
555
744
  while (sbeg <= s) {
556
745
  if (memcmp(s, t, len) == 0) {
557
746
  return (mrb_int)(s - RSTR_PTR(ps));
558
747
  }
559
- s--;
748
+ s = char_backtrack(sbeg, s);
560
749
  }
561
750
  return -1;
562
751
  }
@@ -644,65 +833,17 @@ mrb_locale_from_utf8(const char *utf8, int len)
644
833
  #endif
645
834
 
646
835
  MRB_API void
647
- mrb_str_modify(mrb_state *mrb, struct RString *s)
836
+ mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s)
648
837
  {
649
- check_frozen(mrb, s);
650
- s->flags &= ~MRB_STR_NO_UTF;
651
- if (RSTR_SHARED_P(s)) {
652
- mrb_shared_string *shared = s->as.heap.aux.shared;
653
-
654
- if (shared->nofree == 0 && shared->refcnt == 1 && s->as.heap.ptr == shared->ptr) {
655
- s->as.heap.ptr = shared->ptr;
656
- s->as.heap.aux.capa = shared->len;
657
- RSTR_PTR(s)[s->as.heap.len] = '\0';
658
- mrb_free(mrb, shared);
659
- }
660
- else {
661
- char *ptr, *p;
662
- mrb_int len;
663
-
664
- p = RSTR_PTR(s);
665
- len = s->as.heap.len;
666
- if (len < RSTRING_EMBED_LEN_MAX) {
667
- RSTR_SET_EMBED_FLAG(s);
668
- RSTR_SET_EMBED_LEN(s, len);
669
- ptr = RSTR_PTR(s);
670
- }
671
- else {
672
- ptr = (char *)mrb_malloc(mrb, (size_t)len + 1);
673
- s->as.heap.ptr = ptr;
674
- s->as.heap.aux.capa = len;
675
- }
676
- if (p) {
677
- memcpy(ptr, p, len);
678
- }
679
- ptr[len] = '\0';
680
- str_decref(mrb, shared);
681
- }
682
- RSTR_UNSET_SHARED_FLAG(s);
683
- return;
684
- }
685
- if (RSTR_NOFREE_P(s) || RSTR_FSHARED_P(s)) {
686
- char *p = s->as.heap.ptr;
687
- mrb_int len = s->as.heap.len;
838
+ mrb_check_frozen(mrb, s);
839
+ str_modify_keep_ascii(mrb, s);
840
+ }
688
841
 
689
- RSTR_UNSET_FSHARED_FLAG(s);
690
- RSTR_UNSET_NOFREE_FLAG(s);
691
- RSTR_UNSET_FSHARED_FLAG(s);
692
- if (len < RSTRING_EMBED_LEN_MAX) {
693
- RSTR_SET_EMBED_FLAG(s);
694
- RSTR_SET_EMBED_LEN(s, len);
695
- }
696
- else {
697
- s->as.heap.ptr = (char *)mrb_malloc(mrb, (size_t)len+1);
698
- s->as.heap.aux.capa = len;
699
- }
700
- if (p) {
701
- memcpy(RSTR_PTR(s), p, len);
702
- }
703
- RSTR_PTR(s)[len] = '\0';
704
- return;
705
- }
842
+ MRB_API void
843
+ mrb_str_modify(mrb_state *mrb, struct RString *s)
844
+ {
845
+ mrb_str_modify_keep_ascii(mrb, s);
846
+ RSTR_UNSET_ASCII_FLAG(s);
706
847
  }
707
848
 
708
849
  MRB_API mrb_value
@@ -731,14 +872,8 @@ mrb_str_to_cstr(mrb_state *mrb, mrb_value str0)
731
872
  {
732
873
  struct RString *s;
733
874
 
734
- if (!mrb_string_p(str0)) {
735
- mrb_raise(mrb, E_TYPE_ERROR, "expected String");
736
- }
737
-
875
+ check_null_byte(mrb, str0);
738
876
  s = str_new(mrb, RSTRING_PTR(str0), RSTRING_LEN(str0));
739
- if ((strlen(RSTR_PTR(s)) ^ RSTR_LEN(s)) != 0) {
740
- mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte");
741
- }
742
877
  return RSTR_PTR(s);
743
878
  }
744
879
 
@@ -826,13 +961,13 @@ mrb_str_times(mrb_state *mrb, mrb_value self)
826
961
  if (times < 0) {
827
962
  mrb_raise(mrb, E_ARGUMENT_ERROR, "negative argument");
828
963
  }
829
- if (times && MRB_INT_MAX / times < RSTRING_LEN(self)) {
964
+ if (times && MRB_SSIZE_MAX / times < RSTRING_LEN(self)) {
830
965
  mrb_raise(mrb, E_ARGUMENT_ERROR, "argument too big");
831
966
  }
832
967
 
833
968
  len = RSTRING_LEN(self)*times;
834
969
  str2 = str_new(mrb, 0, len);
835
- str_with_class(mrb, str2, self);
970
+ str_with_class(str2, self);
836
971
  p = RSTR_PTR(str2);
837
972
  if (len > 0) {
838
973
  n = RSTRING_LEN(self);
@@ -844,6 +979,7 @@ mrb_str_times(mrb_state *mrb, mrb_value self)
844
979
  memcpy(p + n, p, len-n);
845
980
  }
846
981
  p[RSTR_LEN(str2)] = '\0';
982
+ RSTR_COPY_ASCII_FLAG(str2, mrb_str_ptr(self));
847
983
 
848
984
  return mrb_obj_value(str2);
849
985
  }
@@ -912,21 +1048,7 @@ mrb_str_cmp_m(mrb_state *mrb, mrb_value str1)
912
1048
 
913
1049
  mrb_get_args(mrb, "o", &str2);
914
1050
  if (!mrb_string_p(str2)) {
915
- if (!mrb_respond_to(mrb, str2, mrb_intern_lit(mrb, "to_s"))) {
916
- return mrb_nil_value();
917
- }
918
- else if (!mrb_respond_to(mrb, str2, mrb_intern_lit(mrb, "<=>"))) {
919
- return mrb_nil_value();
920
- }
921
- else {
922
- mrb_value tmp = mrb_funcall(mrb, str2, "<=>", 1, str1);
923
-
924
- if (mrb_nil_p(tmp)) return mrb_nil_value();
925
- if (!mrb_fixnum_p(tmp)) {
926
- return mrb_funcall(mrb, mrb_fixnum_value(0), "-", 1, tmp);
927
- }
928
- result = -mrb_fixnum(tmp);
929
- }
1051
+ return mrb_nil_value();
930
1052
  }
931
1053
  else {
932
1054
  result = mrb_str_cmp(mrb, str1, str2);
@@ -981,6 +1103,8 @@ mrb_str_to_str(mrb_state *mrb, mrb_value str)
981
1103
  switch (mrb_type(str)) {
982
1104
  case MRB_TT_STRING:
983
1105
  return str;
1106
+ case MRB_TT_SYMBOL:
1107
+ return mrb_sym_str(mrb, mrb_symbol(str));
984
1108
  case MRB_TT_FIXNUM:
985
1109
  return mrb_fixnum_to_str(mrb, str, 10);
986
1110
  case MRB_TT_CLASS:
@@ -991,6 +1115,7 @@ mrb_str_to_str(mrb_state *mrb, mrb_value str)
991
1115
  }
992
1116
  }
993
1117
 
1118
+ /* obslete: use RSTRING_PTR() */
994
1119
  MRB_API const char*
995
1120
  mrb_string_value_ptr(mrb_state *mrb, mrb_value str)
996
1121
  {
@@ -998,6 +1123,7 @@ mrb_string_value_ptr(mrb_state *mrb, mrb_value str)
998
1123
  return RSTRING_PTR(str);
999
1124
  }
1000
1125
 
1126
+ /* obslete: use RSTRING_LEN() */
1001
1127
  MRB_API mrb_int
1002
1128
  mrb_string_value_len(mrb_state *mrb, mrb_value ptr)
1003
1129
  {
@@ -1005,76 +1131,101 @@ mrb_string_value_len(mrb_state *mrb, mrb_value ptr)
1005
1131
  return RSTRING_LEN(ptr);
1006
1132
  }
1007
1133
 
1008
- void
1009
- mrb_noregexp(mrb_state *mrb, mrb_value self)
1010
- {
1011
- mrb_raise(mrb, E_NOTIMP_ERROR, "Regexp class not implemented");
1012
- }
1013
-
1014
- void
1015
- mrb_regexp_check(mrb_state *mrb, mrb_value obj)
1016
- {
1017
- if (mrb_regexp_p(mrb, obj)) {
1018
- mrb_noregexp(mrb, obj);
1019
- }
1020
- }
1021
-
1022
1134
  MRB_API mrb_value
1023
1135
  mrb_str_dup(mrb_state *mrb, mrb_value str)
1024
1136
  {
1025
1137
  struct RString *s = mrb_str_ptr(str);
1026
1138
  struct RString *dup = str_new(mrb, 0, 0);
1027
1139
 
1028
- str_with_class(mrb, dup, str);
1140
+ str_with_class(dup, str);
1029
1141
  return str_replace(mrb, dup, s);
1030
1142
  }
1031
1143
 
1032
- static mrb_value
1033
- mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value indx)
1034
- {
1035
- mrb_int idx;
1144
+ enum str_convert_range {
1145
+ /* `beg` and `len` are byte unit in `0 ... str.bytesize` */
1146
+ STR_BYTE_RANGE_CORRECTED = 1,
1036
1147
 
1037
- mrb_regexp_check(mrb, indx);
1038
- switch (mrb_type(indx)) {
1039
- case MRB_TT_FIXNUM:
1040
- idx = mrb_fixnum(indx);
1148
+ /* `beg` and `len` are char unit in any range */
1149
+ STR_CHAR_RANGE = 2,
1041
1150
 
1042
- num_index:
1043
- str = str_substr(mrb, str, idx, 1);
1044
- if (!mrb_nil_p(str) && RSTRING_LEN(str) == 0) return mrb_nil_value();
1045
- return str;
1151
+ /* `beg` and `len` are char unit in `0 ... str.size` */
1152
+ STR_CHAR_RANGE_CORRECTED = 3,
1046
1153
 
1047
- case MRB_TT_STRING:
1048
- if (str_index_str(mrb, str, indx, 0) != -1)
1049
- return mrb_str_dup(mrb, indx);
1050
- return mrb_nil_value();
1154
+ /* `beg` is out of range */
1155
+ STR_OUT_OF_RANGE = -1
1156
+ };
1051
1157
 
1052
- case MRB_TT_RANGE:
1053
- goto range_arg;
1158
+ static enum str_convert_range
1159
+ str_convert_range(mrb_state *mrb, mrb_value str, mrb_value indx, mrb_value alen, mrb_int *beg, mrb_int *len)
1160
+ {
1161
+ if (!mrb_undef_p(alen)) {
1162
+ *beg = mrb_int(mrb, indx);
1163
+ *len = mrb_int(mrb, alen);
1164
+ return STR_CHAR_RANGE;
1165
+ }
1166
+ else {
1167
+ switch (mrb_type(indx)) {
1168
+ case MRB_TT_FIXNUM:
1169
+ *beg = mrb_fixnum(indx);
1170
+ *len = 1;
1171
+ return STR_CHAR_RANGE;
1054
1172
 
1055
- default:
1056
- indx = mrb_Integer(mrb, indx);
1057
- if (mrb_nil_p(indx)) {
1058
- range_arg:
1059
- {
1060
- mrb_int beg, len;
1061
-
1062
- len = RSTRING_CHAR_LEN(str);
1063
- switch (mrb_range_beg_len(mrb, indx, &beg, &len, len, TRUE)) {
1064
- case 1:
1065
- return str_subseq(mrb, str, beg, len);
1066
- case 2:
1067
- return mrb_nil_value();
1173
+ case MRB_TT_STRING:
1174
+ *beg = str_index_str(mrb, str, indx, 0);
1175
+ if (*beg < 0) { break; }
1176
+ *len = RSTRING_LEN(indx);
1177
+ return STR_BYTE_RANGE_CORRECTED;
1178
+
1179
+ case MRB_TT_RANGE:
1180
+ goto range_arg;
1181
+
1182
+ default:
1183
+ indx = mrb_to_int(mrb, indx);
1184
+ if (mrb_fixnum_p(indx)) {
1185
+ *beg = mrb_fixnum(indx);
1186
+ *len = 1;
1187
+ return STR_CHAR_RANGE;
1188
+ }
1189
+ range_arg:
1190
+ *len = RSTRING_CHAR_LEN(str);
1191
+ switch (mrb_range_beg_len(mrb, indx, beg, len, *len, TRUE)) {
1192
+ case MRB_RANGE_OK:
1193
+ return STR_CHAR_RANGE_CORRECTED;
1194
+ case MRB_RANGE_OUT:
1195
+ return STR_OUT_OF_RANGE;
1068
1196
  default:
1069
1197
  break;
1070
- }
1071
1198
  }
1199
+
1072
1200
  mrb_raise(mrb, E_TYPE_ERROR, "can't convert to Fixnum");
1201
+ }
1202
+ }
1203
+ return STR_OUT_OF_RANGE;
1204
+ }
1205
+
1206
+ static mrb_value
1207
+ mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value indx, mrb_value alen)
1208
+ {
1209
+ mrb_int beg, len;
1210
+
1211
+ switch (str_convert_range(mrb, str, indx, alen, &beg, &len)) {
1212
+ case STR_CHAR_RANGE_CORRECTED:
1213
+ return str_subseq(mrb, str, beg, len);
1214
+ case STR_CHAR_RANGE:
1215
+ str = str_substr(mrb, str, beg, len);
1216
+ if (mrb_undef_p(alen) && !mrb_nil_p(str) && RSTRING_LEN(str) == 0) return mrb_nil_value();
1217
+ return str;
1218
+ case STR_BYTE_RANGE_CORRECTED:
1219
+ if (mrb_string_p(indx)) {
1220
+ return mrb_str_dup(mrb, indx);
1073
1221
  }
1074
- idx = mrb_fixnum(indx);
1075
- goto num_index;
1222
+ else {
1223
+ return mrb_str_byte_subseq(mrb, str, beg, len);
1224
+ }
1225
+ case STR_OUT_OF_RANGE:
1226
+ default:
1227
+ return mrb_nil_value();
1076
1228
  }
1077
- return mrb_nil_value(); /* not reached */
1078
1229
  }
1079
1230
 
1080
1231
  /* 15.2.10.5.6 */
@@ -1084,8 +1235,6 @@ num_index:
1084
1235
  * str[fixnum] => fixnum or nil
1085
1236
  * str[fixnum, fixnum] => new_str or nil
1086
1237
  * str[range] => new_str or nil
1087
- * str[regexp] => new_str or nil
1088
- * str[regexp, fixnum] => new_str or nil
1089
1238
  * str[other_str] => new_str or nil
1090
1239
  * str.slice(fixnum) => fixnum or nil
1091
1240
  * str.slice(fixnum, fixnum) => new_str or nil
@@ -1121,20 +1270,198 @@ static mrb_value
1121
1270
  mrb_str_aref_m(mrb_state *mrb, mrb_value str)
1122
1271
  {
1123
1272
  mrb_value a1, a2;
1124
- mrb_int argc;
1125
1273
 
1126
- argc = mrb_get_args(mrb, "o|o", &a1, &a2);
1127
- if (argc == 2) {
1128
- mrb_int n1, n2;
1274
+ if (mrb_get_args(mrb, "o|o", &a1, &a2) == 1) {
1275
+ a2 = mrb_undef_value();
1276
+ }
1277
+
1278
+ return mrb_str_aref(mrb, str, a1, a2);
1279
+ }
1280
+
1281
+ static mrb_noreturn void
1282
+ str_out_of_index(mrb_state *mrb, mrb_value index)
1283
+ {
1284
+ mrb_raisef(mrb, E_INDEX_ERROR, "index %v out of string", index);
1285
+ }
1286
+
1287
+ static mrb_value
1288
+ str_replace_partial(mrb_state *mrb, mrb_value src, mrb_int pos, mrb_int end, mrb_value rep)
1289
+ {
1290
+ const mrb_int shrink_threshold = 256;
1291
+ struct RString *str = mrb_str_ptr(src);
1292
+ mrb_int len = RSTR_LEN(str);
1293
+ mrb_int replen, newlen;
1294
+ char *strp;
1295
+
1296
+ if (end > len) { end = len; }
1297
+
1298
+ if (pos < 0 || pos > len) {
1299
+ str_out_of_index(mrb, mrb_fixnum_value(pos));
1300
+ }
1301
+
1302
+ replen = (mrb_nil_p(rep) ? 0 : RSTRING_LEN(rep));
1303
+ newlen = replen + len - (end - pos);
1304
+
1305
+ if (newlen >= MRB_SSIZE_MAX || newlen < replen /* overflowed */) {
1306
+ mrb_raise(mrb, E_RUNTIME_ERROR, "string size too big");
1307
+ }
1308
+
1309
+ mrb_str_modify(mrb, str);
1310
+
1311
+ if (len < newlen) {
1312
+ resize_capa(mrb, str, newlen);
1313
+ }
1314
+
1315
+ strp = RSTR_PTR(str);
1316
+
1317
+ memmove(strp + newlen - (len - end), strp + end, len - end);
1318
+ if (!mrb_nil_p(rep)) {
1319
+ memmove(strp + pos, RSTRING_PTR(rep), replen);
1320
+ }
1321
+ RSTR_SET_LEN(str, newlen);
1322
+ strp[newlen] = '\0';
1129
1323
 
1130
- mrb_regexp_check(mrb, a1);
1131
- mrb_get_args(mrb, "ii", &n1, &n2);
1132
- return str_substr(mrb, str, n1, n2);
1324
+ if (len - newlen >= shrink_threshold) {
1325
+ resize_capa(mrb, str, newlen);
1133
1326
  }
1134
- if (argc != 1) {
1135
- mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%S for 1)", mrb_fixnum_value(argc));
1327
+
1328
+ return src;
1329
+ }
1330
+
1331
+ #define IS_EVSTR(p,e) ((p) < (e) && (*(p) == '$' || *(p) == '@' || *(p) == '{'))
1332
+
1333
+ static mrb_value
1334
+ str_escape(mrb_state *mrb, mrb_value str, mrb_bool inspect)
1335
+ {
1336
+ const char *p, *pend;
1337
+ char buf[4]; /* `\x??` or UTF-8 character */
1338
+ mrb_value result = mrb_str_new_lit(mrb, "\"");
1339
+ #ifdef MRB_UTF8_STRING
1340
+ uint32_t ascii_flag = MRB_STR_ASCII;
1341
+ #endif
1342
+
1343
+ p = RSTRING_PTR(str); pend = RSTRING_END(str);
1344
+ for (;p < pend; p++) {
1345
+ unsigned char c, cc;
1346
+ #ifdef MRB_UTF8_STRING
1347
+ if (inspect) {
1348
+ mrb_int clen = utf8len(p, pend);
1349
+ if (clen > 1) {
1350
+ mrb_int i;
1351
+
1352
+ for (i=0; i<clen; i++) {
1353
+ buf[i] = p[i];
1354
+ }
1355
+ mrb_str_cat(mrb, result, buf, clen);
1356
+ p += clen-1;
1357
+ ascii_flag = 0;
1358
+ continue;
1359
+ }
1360
+ }
1361
+ #endif
1362
+ c = *p;
1363
+ if (c == '"'|| c == '\\' || (c == '#' && IS_EVSTR(p+1, pend))) {
1364
+ buf[0] = '\\'; buf[1] = c;
1365
+ mrb_str_cat(mrb, result, buf, 2);
1366
+ continue;
1367
+ }
1368
+ if (ISPRINT(c)) {
1369
+ buf[0] = c;
1370
+ mrb_str_cat(mrb, result, buf, 1);
1371
+ continue;
1372
+ }
1373
+ switch (c) {
1374
+ case '\n': cc = 'n'; break;
1375
+ case '\r': cc = 'r'; break;
1376
+ case '\t': cc = 't'; break;
1377
+ case '\f': cc = 'f'; break;
1378
+ case '\013': cc = 'v'; break;
1379
+ case '\010': cc = 'b'; break;
1380
+ case '\007': cc = 'a'; break;
1381
+ case 033: cc = 'e'; break;
1382
+ default: cc = 0; break;
1383
+ }
1384
+ if (cc) {
1385
+ buf[0] = '\\';
1386
+ buf[1] = (char)cc;
1387
+ mrb_str_cat(mrb, result, buf, 2);
1388
+ continue;
1389
+ }
1390
+ else {
1391
+ buf[0] = '\\';
1392
+ buf[1] = 'x';
1393
+ buf[3] = mrb_digitmap[c % 16]; c /= 16;
1394
+ buf[2] = mrb_digitmap[c % 16];
1395
+ mrb_str_cat(mrb, result, buf, 4);
1396
+ continue;
1397
+ }
1398
+ }
1399
+ mrb_str_cat_lit(mrb, result, "\"");
1400
+ #ifdef MRB_UTF8_STRING
1401
+ if (inspect) {
1402
+ mrb_str_ptr(str)->flags |= ascii_flag;
1403
+ mrb_str_ptr(result)->flags |= ascii_flag;
1404
+ }
1405
+ else {
1406
+ RSTR_SET_ASCII_FLAG(mrb_str_ptr(result));
1407
+ }
1408
+ #endif
1409
+
1410
+ return result;
1411
+ }
1412
+
1413
+ static void
1414
+ mrb_str_aset(mrb_state *mrb, mrb_value str, mrb_value indx, mrb_value alen, mrb_value replace)
1415
+ {
1416
+ mrb_int beg, len, charlen;
1417
+
1418
+ mrb_to_str(mrb, replace);
1419
+
1420
+ switch (str_convert_range(mrb, str, indx, alen, &beg, &len)) {
1421
+ case STR_OUT_OF_RANGE:
1422
+ default:
1423
+ mrb_raise(mrb, E_INDEX_ERROR, "string not matched");
1424
+ case STR_CHAR_RANGE:
1425
+ if (len < 0) {
1426
+ mrb_raisef(mrb, E_INDEX_ERROR, "negative length %v", alen);
1427
+ }
1428
+ charlen = RSTRING_CHAR_LEN(str);
1429
+ if (beg < 0) { beg += charlen; }
1430
+ if (beg < 0 || beg > charlen) { str_out_of_index(mrb, indx); }
1431
+ /* fall through */
1432
+ case STR_CHAR_RANGE_CORRECTED:
1433
+ str_range_to_bytes(str, &beg, &len);
1434
+ /* fall through */
1435
+ case STR_BYTE_RANGE_CORRECTED:
1436
+ str_replace_partial(mrb, str, beg, beg + len, replace);
1437
+ }
1438
+ }
1439
+
1440
+ /*
1441
+ * call-seq:
1442
+ * str[fixnum] = replace
1443
+ * str[fixnum, fixnum] = replace
1444
+ * str[range] = replace
1445
+ * str[other_str] = replace
1446
+ *
1447
+ * Modify +self+ by replacing the content of +self+.
1448
+ * The portion of the string affected is determined using the same criteria as +String#[]+.
1449
+ */
1450
+ static mrb_value
1451
+ mrb_str_aset_m(mrb_state *mrb, mrb_value str)
1452
+ {
1453
+ mrb_value indx, alen, replace;
1454
+
1455
+ switch (mrb_get_args(mrb, "oo|S!", &indx, &alen, &replace)) {
1456
+ case 2:
1457
+ replace = alen;
1458
+ alen = mrb_undef_value();
1459
+ break;
1460
+ case 3:
1461
+ break;
1136
1462
  }
1137
- return mrb_str_aref(mrb, str, a1);
1463
+ mrb_str_aset(mrb, str, indx, alen, replace);
1464
+ return str;
1138
1465
  }
1139
1466
 
1140
1467
  /* 15.2.10.5.8 */
@@ -1157,7 +1484,7 @@ mrb_str_capitalize_bang(mrb_state *mrb, mrb_value str)
1157
1484
  mrb_bool modify = FALSE;
1158
1485
  struct RString *s = mrb_str_ptr(str);
1159
1486
 
1160
- mrb_str_modify(mrb, s);
1487
+ mrb_str_modify_keep_ascii(mrb, s);
1161
1488
  if (RSTR_LEN(s) == 0 || !RSTR_PTR(s)) return mrb_nil_value();
1162
1489
  p = RSTR_PTR(s); pend = RSTR_PTR(s) + RSTR_LEN(s);
1163
1490
  if (ISLOWER(*p)) {
@@ -1216,7 +1543,7 @@ mrb_str_chomp_bang(mrb_state *mrb, mrb_value str)
1216
1543
  struct RString *s = mrb_str_ptr(str);
1217
1544
 
1218
1545
  argc = mrb_get_args(mrb, "|S", &rs);
1219
- mrb_str_modify(mrb, s);
1546
+ mrb_str_modify_keep_ascii(mrb, s);
1220
1547
  len = RSTR_LEN(s);
1221
1548
  if (argc == 0) {
1222
1549
  if (len == 0) return mrb_nil_value();
@@ -1278,9 +1605,8 @@ mrb_str_chomp_bang(mrb_state *mrb, mrb_value str)
1278
1605
  * str.chomp(separator="\n") => new_str
1279
1606
  *
1280
1607
  * Returns a new <code>String</code> with the given record separator removed
1281
- * from the end of <i>str</i> (if present). If <code>$/</code> has not been
1282
- * changed from the default Ruby record separator, then <code>chomp</code> also
1283
- * removes carriage return characters (that is it will remove <code>\n</code>,
1608
+ * from the end of <i>str</i> (if present). <code>chomp</code> also removes
1609
+ * carriage return characters (that is it will remove <code>\n</code>,
1284
1610
  * <code>\r</code>, and <code>\r\n</code>).
1285
1611
  *
1286
1612
  * "hello".chomp #=> "hello"
@@ -1315,7 +1641,7 @@ mrb_str_chop_bang(mrb_state *mrb, mrb_value str)
1315
1641
  {
1316
1642
  struct RString *s = mrb_str_ptr(str);
1317
1643
 
1318
- mrb_str_modify(mrb, s);
1644
+ mrb_str_modify_keep_ascii(mrb, s);
1319
1645
  if (RSTR_LEN(s) > 0) {
1320
1646
  mrb_int len;
1321
1647
  #ifdef MRB_UTF8_STRING
@@ -1384,7 +1710,7 @@ mrb_str_downcase_bang(mrb_state *mrb, mrb_value str)
1384
1710
  mrb_bool modify = FALSE;
1385
1711
  struct RString *s = mrb_str_ptr(str);
1386
1712
 
1387
- mrb_str_modify(mrb, s);
1713
+ mrb_str_modify_keep_ascii(mrb, s);
1388
1714
  p = RSTR_PTR(s);
1389
1715
  pend = RSTR_PTR(s) + RSTR_LEN(s);
1390
1716
  while (p < pend) {
@@ -1452,7 +1778,7 @@ mrb_str_eql(mrb_state *mrb, mrb_value self)
1452
1778
  mrb_bool eql_p;
1453
1779
 
1454
1780
  mrb_get_args(mrb, "o", &str2);
1455
- eql_p = (mrb_type(str2) == MRB_TT_STRING) && str_eql(mrb, self, str2);
1781
+ eql_p = (mrb_string_p(str2)) && str_eql(mrb, self, str2);
1456
1782
 
1457
1783
  return mrb_bool_value(eql_p);
1458
1784
  }
@@ -1521,71 +1847,36 @@ mrb_str_include(mrb_state *mrb, mrb_value self)
1521
1847
  /*
1522
1848
  * call-seq:
1523
1849
  * str.index(substring [, offset]) => fixnum or nil
1524
- * str.index(fixnum [, offset]) => fixnum or nil
1525
- * str.index(regexp [, offset]) => fixnum or nil
1526
1850
  *
1527
1851
  * Returns the index of the first occurrence of the given
1528
- * <i>substring</i>,
1529
- * character (<i>fixnum</i>), or pattern (<i>regexp</i>) in <i>str</i>.
1530
- * Returns
1531
- * <code>nil</code> if not found.
1852
+ * <i>substring</i>. Returns <code>nil</code> if not found.
1532
1853
  * If the second parameter is present, it
1533
1854
  * specifies the position in the string to begin the search.
1534
1855
  *
1535
- * "hello".index('e') #=> 1
1856
+ * "hello".index('l') #=> 2
1536
1857
  * "hello".index('lo') #=> 3
1537
1858
  * "hello".index('a') #=> nil
1538
- * "hello".index(101) #=> 1(101=0x65='e')
1539
- * "hello".index(/[aeiou]/, -3) #=> 4
1859
+ * "hello".index('l', -2) #=> 3
1540
1860
  */
1541
1861
  static mrb_value
1542
1862
  mrb_str_index_m(mrb_state *mrb, mrb_value str)
1543
1863
  {
1544
- mrb_value *argv;
1545
- mrb_int argc;
1546
1864
  mrb_value sub;
1547
- mrb_int pos, clen;
1865
+ mrb_int pos;
1548
1866
 
1549
- mrb_get_args(mrb, "*!", &argv, &argc);
1550
- if (argc == 2) {
1551
- mrb_get_args(mrb, "oi", &sub, &pos);
1552
- }
1553
- else {
1867
+ if (mrb_get_args(mrb, "S|i", &sub, &pos) == 1) {
1554
1868
  pos = 0;
1555
- if (argc > 0)
1556
- sub = argv[0];
1557
- else
1558
- sub = mrb_nil_value();
1559
1869
  }
1560
- mrb_regexp_check(mrb, sub);
1561
- clen = RSTRING_CHAR_LEN(str);
1562
- if (pos < 0) {
1870
+ else if (pos < 0) {
1871
+ mrb_int clen = RSTRING_CHAR_LEN(str);
1563
1872
  pos += clen;
1564
1873
  if (pos < 0) {
1565
1874
  return mrb_nil_value();
1566
1875
  }
1567
1876
  }
1568
- if (pos > clen) return mrb_nil_value();
1569
- pos = chars2bytes(str, 0, pos);
1570
-
1571
- switch (mrb_type(sub)) {
1572
- default: {
1573
- mrb_value tmp;
1574
-
1575
- tmp = mrb_check_string_type(mrb, sub);
1576
- if (mrb_nil_p(tmp)) {
1577
- mrb_raisef(mrb, E_TYPE_ERROR, "type mismatch: %S given", sub);
1578
- }
1579
- sub = tmp;
1580
- }
1581
- /* fall through */
1582
- case MRB_TT_STRING:
1583
- pos = str_index_str(mrb, str, sub, pos);
1584
- break;
1585
- }
1877
+ pos = str_index_str_by_char(mrb, str, sub, pos);
1586
1878
 
1587
1879
  if (pos == -1) return mrb_nil_value();
1588
- pos = bytes2chars(RSTRING_PTR(str), pos);
1589
1880
  BYTES_ALIGN_CHECK(pos);
1590
1881
  return mrb_fixnum_value(pos);
1591
1882
  }
@@ -1658,15 +1949,10 @@ mrb_str_intern(mrb_state *mrb, mrb_value self)
1658
1949
  MRB_API mrb_value
1659
1950
  mrb_obj_as_string(mrb_state *mrb, mrb_value obj)
1660
1951
  {
1661
- mrb_value str;
1662
-
1663
1952
  if (mrb_string_p(obj)) {
1664
1953
  return obj;
1665
1954
  }
1666
- str = mrb_funcall(mrb, obj, "to_s", 0);
1667
- if (!mrb_string_p(str))
1668
- return mrb_any_to_s(mrb, obj);
1669
- return str;
1955
+ return mrb_str_to_str(mrb, obj);
1670
1956
  }
1671
1957
 
1672
1958
  MRB_API mrb_value
@@ -1699,6 +1985,18 @@ mrb_ptr_to_str(mrb_state *mrb, void *p)
1699
1985
  return mrb_obj_value(p_str);
1700
1986
  }
1701
1987
 
1988
+ static inline void
1989
+ str_reverse(char *p, char *e)
1990
+ {
1991
+ char c;
1992
+
1993
+ while (p < e) {
1994
+ c = *p;
1995
+ *p++ = *e;
1996
+ *e-- = c;
1997
+ }
1998
+ }
1999
+
1702
2000
  /* 15.2.10.5.30 */
1703
2001
  /*
1704
2002
  * call-seq:
@@ -1709,53 +2007,38 @@ mrb_ptr_to_str(mrb_state *mrb, void *p)
1709
2007
  static mrb_value
1710
2008
  mrb_str_reverse_bang(mrb_state *mrb, mrb_value str)
1711
2009
  {
2010
+ struct RString *s = mrb_str_ptr(str);
2011
+ char *p, *e;
2012
+
1712
2013
  #ifdef MRB_UTF8_STRING
1713
2014
  mrb_int utf8_len = RSTRING_CHAR_LEN(str);
1714
- mrb_int len = RSTRING_LEN(str);
1715
-
1716
- if (utf8_len == len) goto bytes;
1717
- if (utf8_len > 1) {
1718
- char *buf;
1719
- char *p, *e, *r;
1720
-
1721
- mrb_str_modify(mrb, mrb_str_ptr(str));
1722
- len = RSTRING_LEN(str);
1723
- buf = (char*)mrb_malloc(mrb, (size_t)len);
1724
- p = buf;
1725
- e = buf + len;
1726
-
1727
- memcpy(buf, RSTRING_PTR(str), len);
1728
- r = RSTRING_PTR(str) + len;
2015
+ mrb_int len = RSTR_LEN(s);
1729
2016
 
2017
+ if (utf8_len < 2) return str;
2018
+ if (utf8_len < len) {
2019
+ mrb_str_modify(mrb, s);
2020
+ p = RSTR_PTR(s);
2021
+ e = p + RSTR_LEN(s);
1730
2022
  while (p<e) {
1731
2023
  mrb_int clen = utf8len(p, e);
1732
- r -= clen;
1733
- memcpy(r, p, clen);
2024
+ str_reverse(p, p + clen - 1);
1734
2025
  p += clen;
1735
2026
  }
1736
- mrb_free(mrb, buf);
2027
+ goto bytes;
1737
2028
  }
1738
- return str;
1739
-
1740
- bytes:
1741
2029
  #endif
1742
- {
1743
- struct RString *s = mrb_str_ptr(str);
1744
- char *p, *e;
1745
- char c;
1746
2030
 
2031
+ if (RSTR_LEN(s) > 1) {
1747
2032
  mrb_str_modify(mrb, s);
1748
- if (RSTR_LEN(s) > 1) {
1749
- p = RSTR_PTR(s);
1750
- e = p + RSTR_LEN(s) - 1;
1751
- while (p < e) {
1752
- c = *p;
1753
- *p++ = *e;
1754
- *e-- = c;
1755
- }
1756
- }
1757
- return str;
2033
+ goto bytes;
1758
2034
  }
2035
+ return str;
2036
+
2037
+ bytes:
2038
+ p = RSTR_PTR(s);
2039
+ e = p + RSTR_LEN(s) - 1;
2040
+ str_reverse(p, e);
2041
+ return str;
1759
2042
  }
1760
2043
 
1761
2044
  /* ---------------------------------- */
@@ -1779,73 +2062,43 @@ mrb_str_reverse(mrb_state *mrb, mrb_value str)
1779
2062
  /* 15.2.10.5.31 */
1780
2063
  /*
1781
2064
  * call-seq:
1782
- * str.rindex(substring [, fixnum]) => fixnum or nil
1783
- * str.rindex(fixnum [, fixnum]) => fixnum or nil
1784
- * str.rindex(regexp [, fixnum]) => fixnum or nil
2065
+ * str.rindex(substring [, offset]) => fixnum or nil
1785
2066
  *
1786
- * Returns the index of the last occurrence of the given <i>substring</i>,
1787
- * character (<i>fixnum</i>), or pattern (<i>regexp</i>) in <i>str</i>. Returns
1788
- * <code>nil</code> if not found. If the second parameter is present, it
1789
- * specifies the position in the string to end the search---characters beyond
1790
- * this point will not be considered.
2067
+ * Returns the index of the last occurrence of the given <i>substring</i>.
2068
+ * Returns <code>nil</code> if not found. If the second parameter is
2069
+ * present, it specifies the position in the string to end the
2070
+ * search---characters beyond this point will not be considered.
1791
2071
  *
1792
2072
  * "hello".rindex('e') #=> 1
1793
2073
  * "hello".rindex('l') #=> 3
1794
2074
  * "hello".rindex('a') #=> nil
1795
- * "hello".rindex(101) #=> 1
1796
- * "hello".rindex(/[aeiou]/, -2) #=> 1
2075
+ * "hello".rindex('l', 2) #=> 2
1797
2076
  */
1798
2077
  static mrb_value
1799
2078
  mrb_str_rindex(mrb_state *mrb, mrb_value str)
1800
2079
  {
1801
- mrb_value *argv;
1802
- mrb_int argc;
1803
2080
  mrb_value sub;
1804
2081
  mrb_int pos, len = RSTRING_CHAR_LEN(str);
1805
2082
 
1806
- mrb_get_args(mrb, "*!", &argv, &argc);
1807
- if (argc == 2) {
1808
- mrb_get_args(mrb, "oi", &sub, &pos);
2083
+ if (mrb_get_args(mrb, "S|i", &sub, &pos) == 1) {
2084
+ pos = len;
2085
+ }
2086
+ else {
1809
2087
  if (pos < 0) {
1810
2088
  pos += len;
1811
2089
  if (pos < 0) {
1812
- mrb_regexp_check(mrb, sub);
1813
2090
  return mrb_nil_value();
1814
2091
  }
1815
2092
  }
1816
2093
  if (pos > len) pos = len;
1817
2094
  }
1818
- else {
1819
- pos = len;
1820
- if (argc > 0)
1821
- sub = argv[0];
1822
- else
1823
- sub = mrb_nil_value();
1824
- }
1825
2095
  pos = chars2bytes(str, 0, pos);
1826
- mrb_regexp_check(mrb, sub);
1827
-
1828
- switch (mrb_type(sub)) {
1829
- default: {
1830
- mrb_value tmp;
1831
-
1832
- tmp = mrb_check_string_type(mrb, sub);
1833
- if (mrb_nil_p(tmp)) {
1834
- mrb_raisef(mrb, E_TYPE_ERROR, "type mismatch: %S given", sub);
1835
- }
1836
- sub = tmp;
1837
- }
1838
- /* fall through */
1839
- case MRB_TT_STRING:
1840
- pos = str_rindex(mrb, str, sub, pos);
1841
- if (pos >= 0) {
1842
- pos = bytes2chars(RSTRING_PTR(str), pos);
1843
- BYTES_ALIGN_CHECK(pos);
1844
- return mrb_fixnum_value(pos);
1845
- }
1846
- break;
1847
-
1848
- } /* end of switch (TYPE(sub)) */
2096
+ pos = str_rindex(mrb, str, sub, pos);
2097
+ if (pos >= 0) {
2098
+ pos = bytes2chars(RSTRING_PTR(str), RSTRING_LEN(str), pos);
2099
+ BYTES_ALIGN_CHECK(pos);
2100
+ return mrb_fixnum_value(pos);
2101
+ }
1849
2102
  return mrb_nil_value();
1850
2103
  }
1851
2104
 
@@ -1853,23 +2106,18 @@ mrb_str_rindex(mrb_state *mrb, mrb_value str)
1853
2106
 
1854
2107
  /*
1855
2108
  * call-seq:
1856
- * str.split(pattern="\n", [limit]) => anArray
2109
+ * str.split(separator=nil, [limit]) => anArray
1857
2110
  *
1858
2111
  * Divides <i>str</i> into substrings based on a delimiter, returning an array
1859
2112
  * of these substrings.
1860
2113
  *
1861
- * If <i>pattern</i> is a <code>String</code>, then its contents are used as
1862
- * the delimiter when splitting <i>str</i>. If <i>pattern</i> is a single
2114
+ * If <i>separator</i> is a <code>String</code>, then its contents are used as
2115
+ * the delimiter when splitting <i>str</i>. If <i>separator</i> is a single
1863
2116
  * space, <i>str</i> is split on whitespace, with leading whitespace and runs
1864
2117
  * of contiguous whitespace characters ignored.
1865
2118
  *
1866
- * If <i>pattern</i> is a <code>Regexp</code>, <i>str</i> is divided where the
1867
- * pattern matches. Whenever the pattern matches a zero-length string,
1868
- * <i>str</i> is split into individual characters.
1869
- *
1870
- * If <i>pattern</i> is omitted, the value of <code>$;</code> is used. If
1871
- * <code>$;</code> is <code>nil</code> (which is the default), <i>str</i> is
1872
- * split on whitespace as if ' ' were specified.
2119
+ * If <i>separator</i> is omitted or <code>nil</code> (which is the default),
2120
+ * <i>str</i> is split on whitespace as if ' ' were specified.
1873
2121
  *
1874
2122
  * If the <i>limit</i> parameter is omitted, trailing null fields are
1875
2123
  * suppressed. If <i>limit</i> is a positive number, at most that number of
@@ -1880,9 +2128,6 @@ mrb_str_rindex(mrb_state *mrb, mrb_value str)
1880
2128
  *
1881
2129
  * " now's the time".split #=> ["now's", "the", "time"]
1882
2130
  * " now's the time".split(' ') #=> ["now's", "the", "time"]
1883
- * " now's the time".split(/ /) #=> ["", "now's", "", "the", "time"]
1884
- * "hello".split(//) #=> ["h", "e", "l", "l", "o"]
1885
- * "hello".split(//, 3) #=> ["h", "e", "llo"]
1886
2131
  *
1887
2132
  * "mellow yellow".split("ello") #=> ["m", "w y", "w"]
1888
2133
  * "1,2,,3,4,,".split(',') #=> ["1", "2", "", "3", "4"]
@@ -1895,7 +2140,7 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str)
1895
2140
  {
1896
2141
  mrb_int argc;
1897
2142
  mrb_value spat = mrb_nil_value();
1898
- enum {awk, string, regexp} split_type = string;
2143
+ enum {awk, string} split_type = string;
1899
2144
  mrb_int i = 0;
1900
2145
  mrb_int beg;
1901
2146
  mrb_int end;
@@ -1917,16 +2162,11 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str)
1917
2162
  if (argc == 0 || mrb_nil_p(spat)) {
1918
2163
  split_type = awk;
1919
2164
  }
1920
- else {
1921
- if (mrb_string_p(spat)) {
1922
- split_type = string;
1923
- if (RSTRING_LEN(spat) == 1 && RSTRING_PTR(spat)[0] == ' ') {
1924
- split_type = awk;
1925
- }
1926
- }
1927
- else {
1928
- mrb_noregexp(mrb, str);
1929
- }
2165
+ else if (!mrb_string_p(spat)) {
2166
+ mrb_raise(mrb, E_TYPE_ERROR, "expected String");
2167
+ }
2168
+ else if (RSTRING_LEN(spat) == 1 && RSTRING_PTR(spat)[0] == ' ') {
2169
+ split_type = awk;
1930
2170
  }
1931
2171
 
1932
2172
  result = mrb_ary_new(mrb);
@@ -1952,7 +2192,7 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str)
1952
2192
  }
1953
2193
  }
1954
2194
  else if (ISSPACE(c)) {
1955
- mrb_ary_push(mrb, result, byte_subseq(mrb, str, beg, end-beg));
2195
+ mrb_ary_push(mrb, result, mrb_str_byte_subseq(mrb, str, beg, end-beg));
1956
2196
  mrb_gc_arena_restore(mrb, ai);
1957
2197
  skip = TRUE;
1958
2198
  beg = idx;
@@ -1963,7 +2203,7 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str)
1963
2203
  }
1964
2204
  }
1965
2205
  }
1966
- else if (split_type == string) {
2206
+ else { /* split_type == string */
1967
2207
  mrb_int str_len = RSTRING_LEN(str);
1968
2208
  mrb_int pat_len = RSTRING_LEN(spat);
1969
2209
  mrb_int idx = 0;
@@ -1977,22 +2217,19 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str)
1977
2217
  else {
1978
2218
  end = chars2bytes(str, idx, 1);
1979
2219
  }
1980
- mrb_ary_push(mrb, result, byte_subseq(mrb, str, idx, end));
2220
+ mrb_ary_push(mrb, result, mrb_str_byte_subseq(mrb, str, idx, end));
1981
2221
  mrb_gc_arena_restore(mrb, ai);
1982
2222
  idx += end + pat_len;
1983
2223
  if (lim_p && lim <= ++i) break;
1984
2224
  }
1985
2225
  beg = idx;
1986
2226
  }
1987
- else {
1988
- mrb_noregexp(mrb, str);
1989
- }
1990
2227
  if (RSTRING_LEN(str) > 0 && (lim_p || RSTRING_LEN(str) > beg || lim < 0)) {
1991
2228
  if (RSTRING_LEN(str) == beg) {
1992
2229
  tmp = mrb_str_new_empty(mrb, str);
1993
2230
  }
1994
2231
  else {
1995
- tmp = byte_subseq(mrb, str, beg, RSTRING_LEN(str)-beg);
2232
+ tmp = mrb_str_byte_subseq(mrb, str, beg, RSTRING_LEN(str)-beg);
1996
2233
  }
1997
2234
  mrb_ary_push(mrb, result, tmp);
1998
2235
  }
@@ -2090,7 +2327,7 @@ mrb_str_len_to_inum(mrb_state *mrb, const char *str, mrb_int len, mrb_int base,
2090
2327
  break;
2091
2328
  default:
2092
2329
  if (base < 2 || 36 < base) {
2093
- mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix %S", mrb_fixnum_value(base));
2330
+ mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix %i", base);
2094
2331
  }
2095
2332
  break;
2096
2333
  } /* end of switch (base) { */
@@ -2150,8 +2387,7 @@ mrb_str_len_to_inum(mrb_state *mrb, const char *str, mrb_int len, mrb_int base,
2150
2387
  else
2151
2388
  #endif
2152
2389
  {
2153
- mrb_raisef(mrb, E_ARGUMENT_ERROR, "string (%S) too big for integer",
2154
- mrb_str_new(mrb, str, pend-str));
2390
+ mrb_raisef(mrb, E_RANGE_ERROR, "string (%l) too big for integer", str, pend-str);
2155
2391
  }
2156
2392
  }
2157
2393
  }
@@ -2167,8 +2403,7 @@ mrb_str_len_to_inum(mrb_state *mrb, const char *str, mrb_int len, mrb_int base,
2167
2403
  mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte");
2168
2404
  /* not reached */
2169
2405
  bad:
2170
- mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid string for number(%S)",
2171
- mrb_inspect(mrb, mrb_str_new(mrb, str, pend-str)));
2406
+ mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid string for number(%!l)", str, pend-str);
2172
2407
  /* not reached */
2173
2408
  return mrb_fixnum_value(0);
2174
2409
  }
@@ -2179,23 +2414,35 @@ mrb_cstr_to_inum(mrb_state *mrb, const char *str, mrb_int base, mrb_bool badchec
2179
2414
  return mrb_str_len_to_inum(mrb, str, strlen(str), base, badcheck);
2180
2415
  }
2181
2416
 
2417
+ /* obslete: use RSTRING_CSTR() or mrb_string_cstr() */
2182
2418
  MRB_API const char*
2183
2419
  mrb_string_value_cstr(mrb_state *mrb, mrb_value *ptr)
2184
2420
  {
2185
- mrb_value str = mrb_to_str(mrb, *ptr);
2186
- struct RString *ps = mrb_str_ptr(str);
2187
- mrb_int len = mrb_str_strlen(mrb, ps);
2188
- char *p = RSTR_PTR(ps);
2421
+ struct RString *ps;
2422
+ const char *p;
2423
+ mrb_int len;
2189
2424
 
2190
- if (!p || p[len] != '\0') {
2191
- if (MRB_FROZEN_P(ps)) {
2192
- *ptr = str = mrb_str_dup(mrb, str);
2193
- ps = mrb_str_ptr(str);
2194
- }
2195
- mrb_str_modify(mrb, ps);
2196
- return RSTR_PTR(ps);
2425
+ check_null_byte(mrb, *ptr);
2426
+ ps = mrb_str_ptr(*ptr);
2427
+ p = RSTR_PTR(ps);
2428
+ len = RSTR_LEN(ps);
2429
+ if (p[len] == '\0') {
2430
+ return p;
2197
2431
  }
2198
- return p;
2432
+
2433
+ /*
2434
+ * Even after str_modify_keep_ascii(), NULL termination is not ensured if
2435
+ * RSTR_SET_LEN() is used explicitly (e.g. String#delete_suffix!).
2436
+ */
2437
+ str_modify_keep_ascii(mrb, ps);
2438
+ RSTR_PTR(ps)[len] = '\0';
2439
+ return RSTR_PTR(ps);
2440
+ }
2441
+
2442
+ MRB_API const char*
2443
+ mrb_string_cstr(mrb_state *mrb, mrb_value str)
2444
+ {
2445
+ return mrb_string_value_cstr(mrb, &str);
2199
2446
  }
2200
2447
 
2201
2448
  MRB_API mrb_value
@@ -2204,7 +2451,8 @@ mrb_str_to_inum(mrb_state *mrb, mrb_value str, mrb_int base, mrb_bool badcheck)
2204
2451
  const char *s;
2205
2452
  mrb_int len;
2206
2453
 
2207
- s = mrb_string_value_ptr(mrb, str);
2454
+ mrb_to_str(mrb, str);
2455
+ s = RSTRING_PTR(str);
2208
2456
  len = RSTRING_LEN(str);
2209
2457
  return mrb_str_len_to_inum(mrb, s, len, base, badcheck);
2210
2458
  }
@@ -2237,7 +2485,7 @@ mrb_str_to_i(mrb_state *mrb, mrb_value self)
2237
2485
 
2238
2486
  mrb_get_args(mrb, "|i", &base);
2239
2487
  if (base < 0) {
2240
- mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix %S", mrb_fixnum_value(base));
2488
+ mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix %i", base);
2241
2489
  }
2242
2490
  return mrb_str_to_inum(mrb, self, base, FALSE);
2243
2491
  }
@@ -2250,8 +2498,6 @@ mrb_cstr_to_dbl(mrb_state *mrb, const char * p, mrb_bool badcheck)
2250
2498
  char buf[DBL_DIG * 4 + 10];
2251
2499
  double d;
2252
2500
 
2253
- enum {max_width = 20};
2254
-
2255
2501
  if (!p) return 0.0;
2256
2502
  while (ISSPACE(*p)) p++;
2257
2503
 
@@ -2262,7 +2508,7 @@ mrb_cstr_to_dbl(mrb_state *mrb, const char * p, mrb_bool badcheck)
2262
2508
  if (p == end) {
2263
2509
  if (badcheck) {
2264
2510
  bad:
2265
- mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid string for float(%S)", mrb_str_new_cstr(mrb, p));
2511
+ mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid string for float(%s)", p);
2266
2512
  /* not reached */
2267
2513
  }
2268
2514
  return d;
@@ -2309,22 +2555,7 @@ bad:
2309
2555
  MRB_API double
2310
2556
  mrb_str_to_dbl(mrb_state *mrb, mrb_value str, mrb_bool badcheck)
2311
2557
  {
2312
- char *s;
2313
- mrb_int len;
2314
-
2315
- mrb_to_str(mrb, str);
2316
- s = RSTRING_PTR(str);
2317
- len = RSTRING_LEN(str);
2318
- if (s) {
2319
- if (badcheck && memchr(s, '\0', len)) {
2320
- mrb_raise(mrb, E_ARGUMENT_ERROR, "string for Float contains null byte");
2321
- }
2322
- if (s[len]) { /* no sentinel somehow */
2323
- struct RString *temp_str = str_new(mrb, s, len);
2324
- s = RSTR_PTR(temp_str);
2325
- }
2326
- }
2327
- return mrb_cstr_to_dbl(mrb, s, badcheck);
2558
+ return mrb_cstr_to_dbl(mrb, RSTRING_CSTR(mrb, str), badcheck);
2328
2559
  }
2329
2560
 
2330
2561
  /* 15.2.10.5.39 */
@@ -2379,7 +2610,7 @@ mrb_str_upcase_bang(mrb_state *mrb, mrb_value str)
2379
2610
  char *p, *pend;
2380
2611
  mrb_bool modify = FALSE;
2381
2612
 
2382
- mrb_str_modify(mrb, s);
2613
+ mrb_str_modify_keep_ascii(mrb, s);
2383
2614
  p = RSTRING_PTR(str);
2384
2615
  pend = RSTRING_END(str);
2385
2616
  while (p < pend) {
@@ -2415,8 +2646,6 @@ mrb_str_upcase(mrb_state *mrb, mrb_value self)
2415
2646
  return str;
2416
2647
  }
2417
2648
 
2418
- #define IS_EVSTR(p,e) ((p) < (e) && (*(p) == '$' || *(p) == '@' || *(p) == '{'))
2419
-
2420
2649
  /*
2421
2650
  * call-seq:
2422
2651
  * str.dump -> new_str
@@ -2427,113 +2656,7 @@ mrb_str_upcase(mrb_state *mrb, mrb_value self)
2427
2656
  mrb_value
2428
2657
  mrb_str_dump(mrb_state *mrb, mrb_value str)
2429
2658
  {
2430
- mrb_int len;
2431
- const char *p, *pend;
2432
- char *q;
2433
- struct RString *result;
2434
-
2435
- len = 2; /* "" */
2436
- p = RSTRING_PTR(str); pend = p + RSTRING_LEN(str);
2437
- while (p < pend) {
2438
- unsigned char c = *p++;
2439
- switch (c) {
2440
- case '"': case '\\':
2441
- case '\n': case '\r':
2442
- case '\t': case '\f':
2443
- case '\013': case '\010': case '\007': case '\033':
2444
- len += 2;
2445
- break;
2446
-
2447
- case '#':
2448
- len += IS_EVSTR(p, pend) ? 2 : 1;
2449
- break;
2450
-
2451
- default:
2452
- if (ISPRINT(c)) {
2453
- len++;
2454
- }
2455
- else {
2456
- len += 4; /* \NNN */
2457
- }
2458
- break;
2459
- }
2460
- }
2461
-
2462
- result = str_new(mrb, 0, len);
2463
- str_with_class(mrb, result, str);
2464
- p = RSTRING_PTR(str); pend = p + RSTRING_LEN(str);
2465
- q = RSTR_PTR(result);
2466
- *q++ = '"';
2467
- while (p < pend) {
2468
- unsigned char c = *p++;
2469
-
2470
- switch (c) {
2471
- case '"':
2472
- case '\\':
2473
- *q++ = '\\';
2474
- *q++ = c;
2475
- break;
2476
-
2477
- case '\n':
2478
- *q++ = '\\';
2479
- *q++ = 'n';
2480
- break;
2481
-
2482
- case '\r':
2483
- *q++ = '\\';
2484
- *q++ = 'r';
2485
- break;
2486
-
2487
- case '\t':
2488
- *q++ = '\\';
2489
- *q++ = 't';
2490
- break;
2491
-
2492
- case '\f':
2493
- *q++ = '\\';
2494
- *q++ = 'f';
2495
- break;
2496
-
2497
- case '\013':
2498
- *q++ = '\\';
2499
- *q++ = 'v';
2500
- break;
2501
-
2502
- case '\010':
2503
- *q++ = '\\';
2504
- *q++ = 'b';
2505
- break;
2506
-
2507
- case '\007':
2508
- *q++ = '\\';
2509
- *q++ = 'a';
2510
- break;
2511
-
2512
- case '\033':
2513
- *q++ = '\\';
2514
- *q++ = 'e';
2515
- break;
2516
-
2517
- case '#':
2518
- if (IS_EVSTR(p, pend)) *q++ = '\\';
2519
- *q++ = '#';
2520
- break;
2521
-
2522
- default:
2523
- if (ISPRINT(c)) {
2524
- *q++ = c;
2525
- }
2526
- else {
2527
- *q++ = '\\';
2528
- *q++ = 'x';
2529
- q[1] = mrb_digitmap[c % 16]; c /= 16;
2530
- q[0] = mrb_digitmap[c % 16];
2531
- q += 2;
2532
- }
2533
- }
2534
- }
2535
- *q = '"';
2536
- return mrb_obj_value(result);
2659
+ return str_escape(mrb, str, FALSE);
2537
2660
  }
2538
2661
 
2539
2662
  MRB_API mrb_value
@@ -2552,21 +2675,21 @@ mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len)
2552
2675
 
2553
2676
  capa = RSTR_CAPA(s);
2554
2677
  total = RSTR_LEN(s)+len;
2555
- if (total >= MRB_INT_MAX) {
2678
+ if (total >= MRB_SSIZE_MAX) {
2556
2679
  size_error:
2557
2680
  mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
2558
2681
  }
2559
2682
  if (capa <= total) {
2560
2683
  if (capa == 0) capa = 1;
2561
2684
  while (capa <= total) {
2562
- if (capa <= MRB_INT_MAX / 2) {
2685
+ if (capa <= MRB_SSIZE_MAX / 2) {
2563
2686
  capa *= 2;
2564
2687
  }
2565
2688
  else {
2566
2689
  capa = total+1;
2567
2690
  }
2568
2691
  }
2569
- if (capa <= total || capa > MRB_INT_MAX) {
2692
+ if (capa <= total || capa > MRB_SSIZE_MAX) {
2570
2693
  goto size_error;
2571
2694
  }
2572
2695
  resize_capa(mrb, s, capa);
@@ -2575,7 +2698,7 @@ mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len)
2575
2698
  ptr = RSTR_PTR(s) + off;
2576
2699
  }
2577
2700
  memcpy(RSTR_PTR(s) + RSTR_LEN(s), ptr, len);
2578
- mrb_assert_int_fit(size_t, total, mrb_int, MRB_INT_MAX);
2701
+ mrb_assert_int_fit(size_t, total, mrb_ssize, MRB_SSIZE_MAX);
2579
2702
  RSTR_SET_LEN(s, total);
2580
2703
  RSTR_PTR(s)[total] = '\0'; /* sentinel */
2581
2704
  return str;
@@ -2603,8 +2726,6 @@ mrb_str_append(mrb_state *mrb, mrb_value str1, mrb_value str2)
2603
2726
  return mrb_str_cat_str(mrb, str1, str2);
2604
2727
  }
2605
2728
 
2606
- #define CHAR_ESC_LEN 13 /* sizeof(\x{ hex of 32bit unsigned int } \0) */
2607
-
2608
2729
  /*
2609
2730
  * call-seq:
2610
2731
  * str.inspect -> string
@@ -2619,68 +2740,7 @@ mrb_str_append(mrb_state *mrb, mrb_value str1, mrb_value str2)
2619
2740
  mrb_value
2620
2741
  mrb_str_inspect(mrb_state *mrb, mrb_value str)
2621
2742
  {
2622
- const char *p, *pend;
2623
- char buf[CHAR_ESC_LEN + 1];
2624
- mrb_value result = mrb_str_new_lit(mrb, "\"");
2625
-
2626
- p = RSTRING_PTR(str); pend = RSTRING_END(str);
2627
- for (;p < pend; p++) {
2628
- unsigned char c, cc;
2629
- #ifdef MRB_UTF8_STRING
2630
- mrb_int clen;
2631
-
2632
- clen = utf8len(p, pend);
2633
- if (clen > 1) {
2634
- mrb_int i;
2635
-
2636
- for (i=0; i<clen; i++) {
2637
- buf[i] = p[i];
2638
- }
2639
- mrb_str_cat(mrb, result, buf, clen);
2640
- p += clen-1;
2641
- continue;
2642
- }
2643
- #endif
2644
- c = *p;
2645
- if (c == '"'|| c == '\\' || (c == '#' && IS_EVSTR(p+1, pend))) {
2646
- buf[0] = '\\'; buf[1] = c;
2647
- mrb_str_cat(mrb, result, buf, 2);
2648
- continue;
2649
- }
2650
- if (ISPRINT(c)) {
2651
- buf[0] = c;
2652
- mrb_str_cat(mrb, result, buf, 1);
2653
- continue;
2654
- }
2655
- switch (c) {
2656
- case '\n': cc = 'n'; break;
2657
- case '\r': cc = 'r'; break;
2658
- case '\t': cc = 't'; break;
2659
- case '\f': cc = 'f'; break;
2660
- case '\013': cc = 'v'; break;
2661
- case '\010': cc = 'b'; break;
2662
- case '\007': cc = 'a'; break;
2663
- case 033: cc = 'e'; break;
2664
- default: cc = 0; break;
2665
- }
2666
- if (cc) {
2667
- buf[0] = '\\';
2668
- buf[1] = (char)cc;
2669
- mrb_str_cat(mrb, result, buf, 2);
2670
- continue;
2671
- }
2672
- else {
2673
- buf[0] = '\\';
2674
- buf[1] = 'x';
2675
- buf[3] = mrb_digitmap[c % 16]; c /= 16;
2676
- buf[2] = mrb_digitmap[c % 16];
2677
- mrb_str_cat(mrb, result, buf, 4);
2678
- continue;
2679
- }
2680
- }
2681
- mrb_str_cat_lit(mrb, result, "\"");
2682
-
2683
- return result;
2743
+ return str_escape(mrb, str, TRUE);
2684
2744
  }
2685
2745
 
2686
2746
  /*
@@ -2706,13 +2766,112 @@ mrb_str_bytes(mrb_state *mrb, mrb_value str)
2706
2766
  return a;
2707
2767
  }
2708
2768
 
2769
+ /*
2770
+ * call-seq:
2771
+ * str.getbyte(index) -> 0 .. 255
2772
+ *
2773
+ * returns the <i>index</i>th byte as an integer.
2774
+ */
2775
+ static mrb_value
2776
+ mrb_str_getbyte(mrb_state *mrb, mrb_value str)
2777
+ {
2778
+ mrb_int pos;
2779
+ mrb_get_args(mrb, "i", &pos);
2780
+
2781
+ if (pos < 0)
2782
+ pos += RSTRING_LEN(str);
2783
+ if (pos < 0 || RSTRING_LEN(str) <= pos)
2784
+ return mrb_nil_value();
2785
+
2786
+ return mrb_fixnum_value((unsigned char)RSTRING_PTR(str)[pos]);
2787
+ }
2788
+
2789
+ /*
2790
+ * call-seq:
2791
+ * str.setbyte(index, integer) -> integer
2792
+ *
2793
+ * modifies the <i>index</i>th byte as <i>integer</i>.
2794
+ */
2795
+ static mrb_value
2796
+ mrb_str_setbyte(mrb_state *mrb, mrb_value str)
2797
+ {
2798
+ mrb_int pos, byte;
2799
+ mrb_int len;
2800
+
2801
+ mrb_get_args(mrb, "ii", &pos, &byte);
2802
+
2803
+ len = RSTRING_LEN(str);
2804
+ if (pos < -len || len <= pos)
2805
+ mrb_raisef(mrb, E_INDEX_ERROR, "index %i out of string", pos);
2806
+ if (pos < 0)
2807
+ pos += len;
2808
+
2809
+ mrb_str_modify(mrb, mrb_str_ptr(str));
2810
+ byte &= 0xff;
2811
+ RSTRING_PTR(str)[pos] = (unsigned char)byte;
2812
+ return mrb_fixnum_value((unsigned char)byte);
2813
+ }
2814
+
2815
+ /*
2816
+ * call-seq:
2817
+ * str.byteslice(integer) -> new_str or nil
2818
+ * str.byteslice(integer, integer) -> new_str or nil
2819
+ * str.byteslice(range) -> new_str or nil
2820
+ *
2821
+ * Byte Reference---If passed a single Integer, returns a
2822
+ * substring of one byte at that position. If passed two Integer
2823
+ * objects, returns a substring starting at the offset given by the first, and
2824
+ * a length given by the second. If given a Range, a substring containing
2825
+ * bytes at offsets given by the range is returned. In all three cases, if
2826
+ * an offset is negative, it is counted from the end of <i>str</i>. Returns
2827
+ * <code>nil</code> if the initial offset falls outside the string, the length
2828
+ * is negative, or the beginning of the range is greater than the end.
2829
+ * The encoding of the resulted string keeps original encoding.
2830
+ *
2831
+ * "hello".byteslice(1) #=> "e"
2832
+ * "hello".byteslice(-1) #=> "o"
2833
+ * "hello".byteslice(1, 2) #=> "el"
2834
+ * "\x80\u3042".byteslice(1, 3) #=> "\u3042"
2835
+ * "\x03\u3042\xff".byteslice(1..3) #=> "\u3042"
2836
+ */
2837
+ static mrb_value
2838
+ mrb_str_byteslice(mrb_state *mrb, mrb_value str)
2839
+ {
2840
+ mrb_value a1, a2;
2841
+ mrb_int str_len = RSTRING_LEN(str), beg, len;
2842
+ mrb_bool empty = TRUE;
2843
+
2844
+ if (mrb_get_args(mrb, "o|o", &a1, &a2) == 2) {
2845
+ beg = mrb_fixnum(mrb_to_int(mrb, a1));
2846
+ len = mrb_fixnum(mrb_to_int(mrb, a2));
2847
+ }
2848
+ else if (mrb_range_p(a1)) {
2849
+ if (mrb_range_beg_len(mrb, a1, &beg, &len, str_len, TRUE) != MRB_RANGE_OK) {
2850
+ return mrb_nil_value();
2851
+ }
2852
+ }
2853
+ else {
2854
+ beg = mrb_fixnum(mrb_to_int(mrb, a1));
2855
+ len = 1;
2856
+ empty = FALSE;
2857
+ }
2858
+
2859
+ if (mrb_str_beg_len(str_len, &beg, &len) && (empty || len != 0)) {
2860
+ return mrb_str_byte_subseq(mrb, str, beg, len);
2861
+ }
2862
+ else {
2863
+ return mrb_nil_value();
2864
+ }
2865
+ }
2866
+
2709
2867
  /* ---------------------------*/
2710
2868
  void
2711
2869
  mrb_init_string(mrb_state *mrb)
2712
2870
  {
2713
2871
  struct RClass *s;
2714
2872
 
2715
- mrb_static_assert(RSTRING_EMBED_LEN_MAX < (1 << 5), "pointer size too big for embedded string");
2873
+ mrb_static_assert(RSTRING_EMBED_LEN_MAX < (1 << MRB_STR_EMBED_LEN_BIT),
2874
+ "pointer size too big for embedded string");
2716
2875
 
2717
2876
  mrb->string_class = s = mrb_define_class(mrb, "String", mrb->object_class); /* 15.2.10 */
2718
2877
  MRB_SET_INSTANCE_TT(s, MRB_TT_STRING);
@@ -2724,6 +2883,7 @@ mrb_init_string(mrb_state *mrb)
2724
2883
  mrb_define_method(mrb, s, "+", mrb_str_plus_m, MRB_ARGS_REQ(1)); /* 15.2.10.5.4 */
2725
2884
  mrb_define_method(mrb, s, "*", mrb_str_times, MRB_ARGS_REQ(1)); /* 15.2.10.5.5 */
2726
2885
  mrb_define_method(mrb, s, "[]", mrb_str_aref_m, MRB_ARGS_ANY()); /* 15.2.10.5.6 */
2886
+ mrb_define_method(mrb, s, "[]=", mrb_str_aset_m, MRB_ARGS_ANY());
2727
2887
  mrb_define_method(mrb, s, "capitalize", mrb_str_capitalize, MRB_ARGS_NONE()); /* 15.2.10.5.7 */
2728
2888
  mrb_define_method(mrb, s, "capitalize!", mrb_str_capitalize_bang, MRB_ARGS_NONE()); /* 15.2.10.5.8 */
2729
2889
  mrb_define_method(mrb, s, "chomp", mrb_str_chomp, MRB_ARGS_ANY()); /* 15.2.10.5.9 */
@@ -2737,7 +2897,7 @@ mrb_init_string(mrb_state *mrb)
2737
2897
 
2738
2898
  mrb_define_method(mrb, s, "hash", mrb_str_hash_m, MRB_ARGS_NONE()); /* 15.2.10.5.20 */
2739
2899
  mrb_define_method(mrb, s, "include?", mrb_str_include, MRB_ARGS_REQ(1)); /* 15.2.10.5.21 */
2740
- mrb_define_method(mrb, s, "index", mrb_str_index_m, MRB_ARGS_ANY()); /* 15.2.10.5.22 */
2900
+ mrb_define_method(mrb, s, "index", mrb_str_index_m, MRB_ARGS_ARG(1,1)); /* 15.2.10.5.22 */
2741
2901
  mrb_define_method(mrb, s, "initialize", mrb_str_init, MRB_ARGS_REQ(1)); /* 15.2.10.5.23 */
2742
2902
  mrb_define_method(mrb, s, "initialize_copy", mrb_str_replace, MRB_ARGS_REQ(1)); /* 15.2.10.5.24 */
2743
2903
  mrb_define_method(mrb, s, "intern", mrb_str_intern, MRB_ARGS_NONE()); /* 15.2.10.5.25 */
@@ -2761,6 +2921,10 @@ mrb_init_string(mrb_state *mrb)
2761
2921
  mrb_define_method(mrb, s, "upcase!", mrb_str_upcase_bang, MRB_ARGS_NONE()); /* 15.2.10.5.43 */
2762
2922
  mrb_define_method(mrb, s, "inspect", mrb_str_inspect, MRB_ARGS_NONE()); /* 15.2.10.5.46(x) */
2763
2923
  mrb_define_method(mrb, s, "bytes", mrb_str_bytes, MRB_ARGS_NONE());
2924
+
2925
+ mrb_define_method(mrb, s, "getbyte", mrb_str_getbyte, MRB_ARGS_REQ(1));
2926
+ mrb_define_method(mrb, s, "setbyte", mrb_str_setbyte, MRB_ARGS_REQ(2));
2927
+ mrb_define_method(mrb, s, "byteslice", mrb_str_byteslice, MRB_ARGS_ARG(1,1));
2764
2928
  }
2765
2929
 
2766
2930
  #ifndef MRB_WITHOUT_FLOAT