script_core 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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