diff --git a/.github/linters/.markdown-lint.yml b/.github/linters/.markdown-lint.yml index a1023acbd..5c6cbec4a 100644 --- a/.github/linters/.markdown-lint.yml +++ b/.github/linters/.markdown-lint.yml @@ -4,9 +4,6 @@ # MD001 heading-increment/header-increment - Heading levels should only increment by one level at a time MD001: false -# MD010 no-hard-tabs - Hard tabs -MD010: false - # MD013 line-length - Line length MD013: false diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bf963ff0b..870efdd24 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,7 +10,7 @@ jobs: MRUBY_CONFIG: ci/gcc-clang CC: gcc steps: - - uses: actions/checkout@v2.4.0 + - uses: actions/checkout@v3 - name: Ruby version run: ruby -v - name: Compiler version @@ -25,7 +25,7 @@ jobs: MRUBY_CONFIG: ci/gcc-clang CC: clang steps: - - uses: actions/checkout@v2.4.0 + - uses: actions/checkout@v3 - name: Ruby version run: ruby -v - name: Compiler version @@ -40,7 +40,7 @@ jobs: MRUBY_CONFIG: ci/gcc-clang CC: gcc steps: - - uses: actions/checkout@v2.4.0 + - uses: actions/checkout@v3 - name: Ruby version run: ruby -v - name: Compiler version @@ -55,7 +55,7 @@ jobs: MRUBY_CONFIG: ci/gcc-clang CC: clang steps: - - uses: actions/checkout@v2.4.0 + - uses: actions/checkout@v3 - name: Ruby version run: ruby -v - name: Compiler version @@ -70,7 +70,7 @@ jobs: MRUBY_CONFIG: ci/gcc-clang CC: clang steps: - - uses: actions/checkout@v2.4.0 + - uses: actions/checkout@v3 - name: Ruby version run: ruby -v - name: Compiler version @@ -85,7 +85,7 @@ jobs: MRUBY_CONFIG: ci/gcc-clang CC: gcc steps: - - uses: actions/checkout@v2.4.0 + - uses: actions/checkout@v3 - name: Ruby version run: ruby -v - name: Compiler version @@ -93,63 +93,17 @@ jobs: - name: Build and test run: rake -m test:build && rake test:run - Windows-Cygwin: - runs-on: windows-latest - timeout-minutes: 15 - env: - ACTIONS_ALLOW_UNSECURE_COMMANDS: true - MRUBY_CONFIG: ci/gcc-clang - CC: gcc - installer-path: '%TMP%\cygwin-setup.exe' - cygwin-root: C:\cygwin - package-dir: C:\cygwin-package - cache-version: v1 - steps: - - uses: actions/checkout@v2.4.0 - - uses: actions/cache@v2.1.7 - with: - path: ${{ env.package-dir }} - key: ${{ runner.os }}-cygwin-${{ env.cache-version }} - - name: Download Cygwin installer - shell: cmd - run: > - bitsadmin /transfer download /priority foreground - https://cygwin.com/setup-x86_64.exe ${{ env.installer-path }} - - name: Install Cygwin - shell: cmd - run: > - ${{ env.installer-path }} - --quiet-mode --no-shortcuts --no-startmenu --no-desktop --no-admin - --only-site --site http://mirrors.kernel.org/sourceware/cygwin/ - --root ${{ env.cygwin-root }} - --local-package-dir ${{ env.package-dir }} - --packages gcc-core,gcc-g++,ruby - - name: Set PATH for Cygwin - run: | - echo '::set-env name=PATH::${{ env.cygwin-root }}\bin;${{ env.cygwin-root }}\usr\bin' - - name: Ruby version - shell: cmd - run: ruby -v - - name: Compiler version - run: ${{ env.CC }} --version - - name: Build and test - shell: cmd - run: ruby /usr/bin/rake -m test:build && ruby /usr/bin/rake test:run - - name: Set PATH for cache archiving (tar) - # set Windows path so that Cygwin tar is not used for cache archiving - run: echo '::set-env name=PATH::C:\windows\System32' - Windows-VC: - runs-on: windows-latest + runs-on: windows-2022 timeout-minutes: 10 env: MRUBY_CONFIG: ci/msvc steps: - - uses: actions/checkout@v2.4.0 + - uses: actions/checkout@v3 - name: Ruby version run: ruby -v - name: Build and test shell: cmd run: | - call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat" + call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" rake -m test:build && rake test:run diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 184ca54c3..d23f85a47 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -2,6 +2,7 @@ name: "Code scanning - action" on: push: + branches-ignore: "dependabot/**" pull_request: schedule: - cron: '0 19 * * 4' @@ -13,7 +14,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2.4.0 + uses: actions/checkout@v3 with: # We must fetch at least the immediate parents so that if this is # a pull request then we can checkout the head. @@ -21,7 +22,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v2 # Override language selection by uncommenting this and choosing your languages # with: # languages: go, javascript, csharp, python, cpp, java @@ -29,7 +30,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v1 + uses: github/codeql-action/autobuild@v2 # â„šī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -43,4 +44,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 880b7ab6f..da6bc784a 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -8,23 +8,24 @@ jobs: runs-on: ubuntu-latest steps: - name: Check Out - uses: actions/checkout@v2.4.0 + uses: actions/checkout@v3 - name: Install run: wget -O - -q https://git.io/misspell | sh -s -- -b . - - name: Misspell + - name: Run misspell run: git ls-files --empty-directory | xargs ./misspell -error pre-commit: name: Run pre-commit runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2.4.0 - - name: Check merge conflict + - name: Check Out + uses: actions/checkout@v3 + - name: Install run: | python -m pip install --upgrade pip pip install pre-commit - name: Set PY run: echo "PY=$(python -VV | sha256sum | cut -d' ' -f1)" >> $GITHUB_ENV - - uses: actions/cache@v2.1.7 + - uses: actions/cache@v3 with: path: ~/.cache/pre-commit key: pre-commit|${{ env.PY }}|${{ hashFiles('.pre-commit-config.yaml') }} diff --git a/.github/workflows/oss-fuzz.yml b/.github/workflows/oss-fuzz.yml index da3cc2891..687b807dd 100644 --- a/.github/workflows/oss-fuzz.yml +++ b/.github/workflows/oss-fuzz.yml @@ -16,7 +16,7 @@ jobs: fuzz-seconds: 600 dry-run: false - name: Upload Crash - uses: actions/upload-artifact@v2.3.1 + uses: actions/upload-artifact@v3 if: failure() with: name: artifacts diff --git a/.github/workflows/super-linter.yml b/.github/workflows/super-linter.yml index f7a7a6fb4..53000aa81 100644 --- a/.github/workflows/super-linter.yml +++ b/.github/workflows/super-linter.yml @@ -1,19 +1,14 @@ name: Super Linter -on: - push: - branches-ignore: [master] - # Remove the line above to run when pushing to master - pull_request: - branches: [master] +on: [pull_request] jobs: build: name: Lint Code Base runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2.4.0 - - uses: github/super-linter@v4.8.5 + - uses: actions/checkout@v3 + - uses: github/super-linter@v4.9.2 env: ERROR_ON_MISSING_EXEC_BIT: true VALIDATE_BASH: true diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 266f88c83..d7c3cb36d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,14 +3,14 @@ default_stages: [commit, push] default_language_version: # force all unspecified Python hooks to run python3 python: python3 -minimum_pre_commit_version: "1.20.0" +minimum_pre_commit_version: '2.18.1' repos: - repo: meta hooks: - id: identity - id: check-hooks-apply - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.1.0 + rev: v4.2.0 hooks: - id: check-added-large-files - id: check-case-conflict @@ -39,7 +39,7 @@ repos: description: Check spelling with codespell entry: codespell --ignore-words=codespell.txt - repo: https://github.com/igorshubovych/markdownlint-cli - rev: v0.30.0 + rev: v0.31.1 hooks: - id: markdownlint name: Run markdownlint diff --git a/AUTHORS b/AUTHORS index 404cb2f9c..6ba888947 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,16 +1,16 @@ # Authors of mruby (mruby developers) -## The List of Contributors sorted by number of commits (as of 2022-01-10 69b1667) +## The List of Contributors sorted by number of commits (as of 2022-04-28 32fb8b1) - 7956 Yukihiro "Matz" Matsumoto (@matz)* + 8214 Yukihiro "Matz" Matsumoto (@matz)* 586 KOBAYASHI Shuji (@shuujii) 376 Daniel Bovensiepen (@bovi) + 372 dearblue (@dearblue)* 346 Takeshi Watanabe (@take-cheeze)* - 342 dearblue (@dearblue)* 334 Masaki Muranaka (@monaka) - 298 Tomoyuki Sahara (@tsahara)* + 308 Tomoyuki Sahara (@tsahara)* 234 Jun Hiroe (@suzukaze) - 219 Cremno (@cremno)* + 220 Cremno (@cremno)* 208 Yuki Kurihara (@ksss)+ 148 Yasuhiro Matsumoto (@mattn)* 113 Carson McDonald (@carsonmcdonald) @@ -20,12 +20,12 @@ 74 Yuichiro MASUI (@masuidrive) 71 Tatsuhiko Kubo (@cubicdaiya)* 68 Hiroshi Mimaki (@mimaki)* - 63 Akira Yumiyama (@akiray03)* + 67 Akira Yumiyama (@akiray03)* 62 Paolo Bosetti (@pbosetti)* + 60 John Bampton (@jbampton) 59 Kurebayashi, Takahiro (@crimsonwoods)* 56 h2so5 (@h2so5) 52 Ralph Desir (@Mav7)* - 49 John Bampton (@jbampton) 45 Rory O'Connell (@RoryO)* 43 Yuichiro Kaneko (@yui-knk)+ 42 fleuria (@flaneur2020) @@ -66,10 +66,10 @@ 12 Ukrainskiy Sergey (@ukrainskiysergey) 12 Xuejie "Rafael" Xiao (@xxuejie)* 11 Julien Ammous (@schmurfy) + 11 Kazuho Oku (@kazuho) 11 Seeker (@SeekingMeaning) 11 YAMAMOTO Masaya (pandax381) 11 takkaw (@takkaw) - 10 Kazuho Oku (@kazuho) 10 Miura Hideki (@miura1729) 10 Narihiro Nakamura (@authorNari) 10 Ray Chason (@chasonr)* @@ -107,6 +107,7 @@ 5 Yurie Yamane (@yurie)+ 5 dreamedge (@dreamedge) 5 nkshigeru (@nkshigeru) + 4 Chris Reuter (@suetanvil) 4 Dante Catalfamo (@dantecatalfamo) 4 Goro Kikuchi (@gorogit) 4 Herwin Weststrate (@herwinw) @@ -128,6 +129,7 @@ 3 Carlo Prelz (@asfluido)* 3 David Turnbull (@AE9RB) 3 Franck Verrot (@franckverrot) + 3 HASUMI Hitoshi (@hasumikin) 3 Horimoto Yasuhiro (@komainu8) 3 J. Mutua (@katmutua)+ 3 Jan Berdajs (@mrbrdo) @@ -158,7 +160,6 @@ 2 Francois Chagnon (@EiNSTeiN-)* 2 Gilad Zohari (@gzohari) 2 Go Saito (@govm) - 2 HASUMI Hitoshi (@hasumikin) 2 Hirohito Higashi (@HirohitoHigashi) 2 Hiroyuki Iwatsuki (@iwadon) 2 Huei-Horng Yo (@hiroshiyui) @@ -196,7 +197,6 @@ 1 Atsushi Morimoto (@mynz) 1 Ben A Morgan (@BenMorganIO) 1 Benoit Daloze (@eregon) - 1 Chris Reuter (@suetanvil) 1 Daehyub Kim (@lateau) 1 Daniel Varga (@vargad) 1 Edgar Boda-Majer (@eboda) @@ -225,6 +225,7 @@ 1 Kazuhiro NISHIYAMA (@znz) 1 Kei Sawada (@remore) 1 Kim H Madsen (@kimhmadsen) + 1 Koichi ITO (@koic) 1 Konstantin Haase (@rkh) 1 Leo Neat (@Leo-Neat) 1 Lian Cheng (@liancheng) diff --git a/SECURITY.md b/SECURITY.md index 2f0ae5b28..5227f98e7 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -15,4 +15,6 @@ We *don't* consider following issues as vulnerabilities: * Runtime C undefined behavior (including integer overflow) * Crash caused by misused API -* Crash caused by tweaked compiled binary +* Crash caused by modified compiled binary +* ASAN/Valgrind warning for too big memory allocation + mruby assumes `malloc(3)` returns `NULL` for too big allocations diff --git a/build_config/boxing.rb b/build_config/boxing.rb index d861bd537..8a31ab454 100644 --- a/build_config/boxing.rb +++ b/build_config/boxing.rb @@ -5,7 +5,7 @@ ints = [64, 32] boxings.product(bits, ints) do |boxing, bit, int| MRuby::Build.new("boxing-#{boxing}-m#{bit}-i#{int}") do |conf| conf.toolchain :gcc - conf.gembox 'default' + conf.gembox 'full-core' conf.compilers.each do |c| c.defines << "MRB_#{boxing.upcase}_BOXING" c.defines << "MRB_INT#{int}" diff --git a/build_config/host-f32.rb b/build_config/host-f32.rb index a449547ae..ef15231a0 100644 --- a/build_config/host-f32.rb +++ b/build_config/host-f32.rb @@ -3,7 +3,7 @@ MRuby::Build.new do |conf| toolchain :gcc # include the GEM box - conf.gembox 'default' + conf.gembox 'full-core' conf.cc.defines << 'MRB_USE_FLOAT32' diff --git a/build_config/host-gprof.rb b/build_config/host-gprof.rb index 2bdf5bebd..aab119b3e 100644 --- a/build_config/host-gprof.rb +++ b/build_config/host-gprof.rb @@ -3,7 +3,7 @@ MRuby::Build.new do |conf| toolchain :gcc # include the GEM box - conf.gembox 'default' + conf.gembox 'full-core' conf.cc.flags << '-pg' conf.linker.flags << '-pg' diff --git a/build_config/host-m32.rb b/build_config/host-m32.rb index 9e27a0792..5d67ccd62 100644 --- a/build_config/host-m32.rb +++ b/build_config/host-m32.rb @@ -3,7 +3,7 @@ MRuby::Build.new do |conf| toolchain :gcc # include the GEM box - conf.gembox 'default' + conf.gembox 'full-core' conf.cc.flags << '-m32' conf.linker.flags << '-m32' diff --git a/doc/guides/gc-arena-howto.md b/doc/guides/gc-arena-howto.md index 2c1cdc1fb..1fff624df 100644 --- a/doc/guides/gc-arena-howto.md +++ b/doc/guides/gc-arena-howto.md @@ -14,7 +14,7 @@ GC (garbage collector) must ensure that object is "alive", in other words, that it is referenced by somewhere from the program. This can be determined by checking if the object can be directly or indirectly referenced by root. The local variables, global variables and -constants etc are root. +constants etc. are root. If program execution is performed inside mruby VM, there is nothing to worry about because GC can access all roots owned by the VM. @@ -29,7 +29,7 @@ This can be a fatal bug if the GC tries to collect a live object. In CRuby, we scan C stack area, and use C variable as root to check whether object is alive or not. Of course, because we are accessing C stack just as memory region, we never know it is an integer or a -pointer. We workaround this by assuming that if it looks like a +pointer. We work around this by assuming that if it looks like a pointer, then assume it as a pointer. We call it "conservative". By the way, CRuby's "conservative GC" has some problems. @@ -65,14 +65,14 @@ objects (See `MRB_GC_FIXED_ARENA` and `MRB_GC_ARENA_SIZE` in doc/guides/mrbconf.md). If you create many objects in C functions, memory usage will increase, since -GC never kick in. This memory usage may look like memory leak, but will also +GC never kicks in. This memory usage may look like memory leaks, but will also make execution slower as more memory will need to be allocated. With the build time configuration, you can limit the maximum size of arena (e.g., 100). Then if you create many objects, arena overflows, thus you will get an "arena overflow error". -To workaround these problems, we have `mrb_gc_arena_save()` and +To work around these problems, we have `mrb_gc_arena_save()` and `mrb_gc_arena_restore()` functions. `int mrb_gc_arena_save(mrb)` returns the current position of the stack diff --git a/doc/guides/mrbgems.md b/doc/guides/mrbgems.md index 03f8829e1..9cd28c5fa 100644 --- a/doc/guides/mrbgems.md +++ b/doc/guides/mrbgems.md @@ -33,6 +33,9 @@ conf.gem :github => 'masuidrive/mrbgems-example', :branch => 'master' conf.gem :bitbucket => 'mruby/mrbgems-example', :branch => 'master' ``` +NOTE: `:bitbucket` option supports only git. Hg is unsupported in this +version. + You can specify the subdirectory of the repository with `:path` option: ```ruby @@ -55,10 +58,24 @@ conf.gem mgem: 'mruby-redis', checksum_hash: '3446d19fc4a3f9697b5ddbf2a904f301c4 If there are missing dependencies, mrbgem dependencies solver will reference mrbgem from the core or mgem-list. -To pull all gems from remote GIT repository on build, call `rake -p`, -or `rake --pull-gems`. +Note that if more than one git-based gem has the same base name +(i.e. the default checkout directory name), it is (now) an error +**UNLESS** they have the same repository URL, branch name and +commit-id (i.e. checksum hash). You can bypass this by explicitly +importing your preferred version **first** and setting the +`canonical:` option to `true`: -NOTE: `:bitbucket` option supports only git. Hg is unsupported in this version. +```ruby +conf.gem github: 'me/mruby-yaml', branch: 'my-hacked-branch', canonical: true +``` + +If you do this, the system will (mostly) silently ignore other +attempts to clone a gem with this name. + +Note that this only affects cloning the gem from git. It does not +resolve version conflicts. If the version as specified in the gem's +rakefile is incompatible with a dependency, your build will still +fail. ## GemBox @@ -94,7 +111,7 @@ conf.gembox 'custom' This will cause the `custom` GemBox to be read in during the build process, adding `mruby-time` and `mrbgems-example` to the build. -If you want, you can put GemBox outside of mruby directory. In that case you must +If you want, you can put GemBox outside the mruby directory. In that case you must specify an absolute path like below. ```ruby @@ -143,7 +160,7 @@ GEM directory. A typical GEM specification could look like this for example: MRuby::Gem::Specification.new('c_and_ruby_extension_example') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' - spec.summary = 'Example mrbgem using C and ruby' + spec.summary = 'Example mrbgem using C and Ruby' end ``` @@ -397,21 +414,21 @@ binary gems, to separate normal gems and binary gems. ``` +- mruby-bin-example/ | - +- README.md (Optional) + +- README.md (Optional) | +- bintest/ | | - | +- example.rb <- Test code for binary gem + | +- example.rb <- Test code for binary gem | - +- mrbgem.rake <- Gem specification + +- mrbgem.rake <- Gem specification | - +- mrblib/ <- Source for Ruby extension (Optional) + +- mrblib/ <- Source for Ruby extension (Optional) | - +- src/ <- Source for C extension (Optional) + +- src/ <- Source for C extension (Optional) | +- tools/ | - +- example/ <- Executable name directory - | - +- example.c <- Source for Executable (includes main) + +- example/ <- Executable name directory + | + +- example.c <- Source for Executable (includes main) ``` diff --git a/doc/internal/opcode.md b/doc/internal/opcode.md index 11f2133c6..230848cb5 100644 --- a/doc/internal/opcode.md +++ b/doc/internal/opcode.md @@ -22,107 +22,107 @@ sign) of operands. ## table.1 Instruction Table -| Instruction Name | Operand type | Semantics | -|------------------|--------------|----------------------------------------------------------| -| `OP_NOP` | `-` | `no operation` | -| `OP_MOVE` | `BB` | `R(a) = R(b)` | -| `OP_LOADL` | `BB` | `R(a) = Pool(b)` | -| `OP_LOADI` | `BB` | `R(a) = mrb_int(b)` | -| `OP_LOADINEG` | `BB` | `R(a) = mrb_int(-b)` | -| `OP_LOADI__1` | `B` | `R(a) = mrb_int(-1)` | -| `OP_LOADI_0` | `B` | `R(a) = mrb_int(0)` | -| `OP_LOADI_1` | `B` | `R(a) = mrb_int(1)` | -| `OP_LOADI_2` | `B` | `R(a) = mrb_int(2)` | -| `OP_LOADI_3` | `B` | `R(a) = mrb_int(3)` | -| `OP_LOADI_4` | `B` | `R(a) = mrb_int(4)` | -| `OP_LOADI_5` | `B` | `R(a) = mrb_int(5)` | -| `OP_LOADI_6` | `B` | `R(a) = mrb_int(6)` | -| `OP_LOADI_7` | `B` | `R(a) = mrb_int(7)` | -| `OP_LOADI16` | `BS` | `R(a) = mrb_int(b)` | -| `OP_LOADI32` | `BSS` | `R(a) = mrb_int((b<<16)+c)` | -| `OP_LOADSYM` | `BB` | `R(a) = Syms(b)` | -| `OP_LOADNIL` | `B` | `R(a) = nil` | -| `OP_LOADSELF` | `B` | `R(a) = self` | -| `OP_LOADT` | `B` | `R(a) = true` | -| `OP_LOADF` | `B` | `R(a) = false` | -| `OP_GETGV` | `BB` | `R(a) = getglobal(Syms(b))` | -| `OP_SETGV` | `BB` | `setglobal(Syms(b), R(a))` | -| `OP_GETSV` | `BB` | `R(a) = Special[Syms(b)]` | -| `OP_SETSV` | `BB` | `Special[Syms(b)] = R(a)` | -| `OP_GETIV` | `BB` | `R(a) = ivget(Syms(b))` | -| `OP_SETIV` | `BB` | `ivset(Syms(b),R(a))` | -| `OP_GETCV` | `BB` | `R(a) = cvget(Syms(b))` | -| `OP_SETCV` | `BB` | `cvset(Syms(b),R(a))` | -| `OP_GETCONST` | `BB` | `R(a) = constget(Syms(b))` | -| `OP_SETCONST` | `BB` | `constset(Syms(b),R(a))` | -| `OP_GETMCNST` | `BB` | `R(a) = R(a)::Syms(b)` | -| `OP_SETMCNST` | `BB` | `R(a+1)::Syms(b) = R(a)` | -| `OP_GETUPVAR` | `BBB` | `R(a) = uvget(b,c)` | -| `OP_SETUPVAR` | `BBB` | `uvset(b,c,R(a))` | -| `OP_JMP` | `S` | `pc+=a` | -| `OP_JMPIF` | `BS` | `if R(a) pc+=b` | -| `OP_JMPNOT` | `BS` | `if !R(a) pc+=b` | -| `OP_JMPNIL` | `BS` | `if R(a)==nil pc+=b` | -| `OP_JMPUW` | `S` | `unwind_and_jump_to(a)` | -| `OP_EXCEPT` | `B` | `R(a) = exc` | -| `OP_RESCUE` | `BB` | `R(b) = R(a).isa?(R(b))` | -| `OP_RAISEIF` | `B` | `raise(R(a)) if R(a)` | -| `OP_SEND` | `BBB` | `R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c))` | -| `OP_SENDB` | `BBB` | `R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c),&R(a+c+1))` | -| `OP_CALL` | `-` | `R(0) = self.call(frame.argc, frame.argv)` | -| `OP_SUPER` | `BB` | `R(a) = super(R(a+1),... ,R(a+b+1))` | -| `OP_ARGARY` | `BS` | `R(a) = argument array (16=m5:r1:m5:d1:lv4)` | -| `OP_ENTER` | `W` | `arg setup according to flags (23=m5:o5:r1:m5:k5:d1:b1)` | -| `OP_KEY_P` | `BB` | `R(a) = kdict.key?(Syms(b))` | -| `OP_KEYEND` | `-` | `raise unless kdict.empty?` | -| `OP_KARG` | `BB` | `R(a) = kdict[Syms(b)]; kdict.delete(Syms(b))` | -| `OP_RETURN` | `B` | `return R(a) (normal)` | -| `OP_RETURN_BLK` | `B` | `return R(a) (in-block return)` | -| `OP_BREAK` | `B` | `break R(a)` | -| `OP_BLKPUSH` | `BS` | `R(a) = block (16=m5:r1:m5:d1:lv4)` | -| `OP_ADD` | `B` | `R(a) = R(a)+R(a+1)` | -| `OP_ADDI` | `BB` | `R(a) = R(a)+mrb_int(b)` | -| `OP_SUB` | `B` | `R(a) = R(a)-R(a+1)` | -| `OP_SUBI` | `BB` | `R(a) = R(a)-mrb_int(b)` | -| `OP_MUL` | `B` | `R(a) = R(a)*R(a+1)` | -| `OP_DIV` | `B` | `R(a) = R(a)/R(a+1)` | -| `OP_EQ` | `B` | `R(a) = R(a)==R(a+1)` | -| `OP_LT` | `B` | `R(a) = R(a)R(a+1)` | -| `OP_GE` | `B` | `R(a) = R(a)>=R(a+1)` | -| `OP_ARRAY` | `BB` | `R(a) = ary_new(R(a),R(a+1)..R(a+b))` | -| `OP_ARRAY2` | `BBB` | `R(a) = ary_new(R(b),R(b+1)..R(b+c))` | -| `OP_ARYCAT` | `B` | `ary_cat(R(a),R(a+1))` | -| `OP_ARYPUSH` | `BB` | `ary_push(R(a),R(a+1)..R(a+b))` | -| `OP_ARYDUP` | `B` | `R(a) = ary_dup(R(a))` | -| `OP_AREF` | `BBB` | `R(a) = R(b)[c]` | -| `OP_ASET` | `BBB` | `R(b)[c] = R(a)` | -| `OP_APOST` | `BBB` | `*R(a),R(a+1)..R(a+c) = R(a)[b..]` | -| `OP_INTERN` | `B` | `R(a) = intern(R(a))` | -| `OP_STRING` | `BB` | `R(a) = str_dup(Pool(b))` | -| `OP_STRCAT` | `B` | `str_cat(R(a),R(a+1))` | -| `OP_HASH` | `BB` | `R(a) = hash_new(R(a),R(a+1)..R(a+b*2-1))` | -| `OP_HASHADD` | `BB` | `hash_push(R(a),R(a+1)..R(a+b*2))` | -| `OP_HASHCAT` | `B` | `R(a) = hash_cat(R(a),R(a+1))` | -| `OP_LAMBDA` | `BB` | `R(a) = lambda(Irep(b),OP_L_LAMBDA)` | -| `OP_BLOCK` | `BB` | `R(a) = lambda(Irep(b),OP_L_BLOCK)` | -| `OP_METHOD` | `BB` | `R(a) = lambda(Irep(b),OP_L_METHOD)` | -| `OP_RANGE_INC` | `B` | `R(a) = range_new(R(a),R(a+1),FALSE)` | -| `OP_RANGE_EXC` | `B` | `R(a) = range_new(R(a),R(a+1),TRUE)` | -| `OP_OCLASS` | `B` | `R(a) = ::Object` | -| `OP_CLASS` | `BB` | `R(a) = newclass(R(a),Syms(b),R(a+1))` | -| `OP_MODULE` | `BB` | `R(a) = newmodule(R(a),Syms(b))` | -| `OP_EXEC` | `BB` | `R(a) = blockexec(R(a),Irep[b])` | -| `OP_DEF` | `BB` | `R(a).newmethod(Syms(b),R(a+1)); R(a) = Syms(b)` | -| `OP_ALIAS` | `BB` | `alias_method(target_class,Syms(a),Syms(b))` | -| `OP_UNDEF` | `B` | `undef_method(target_class,Syms(a))` | -| `OP_SCLASS` | `B` | `R(a) = R(a).singleton_class` | -| `OP_TCLASS` | `B` | `R(a) = target_class` | -| `OP_DEBUG` | `BBB` | `print a,b,c` | -| `OP_ERR` | `B` | `raise(LocalJumpError, Pool(a))` | -| `OP_EXT1` | `-` | `make 1st operand 16bit` | -| `OP_EXT2` | `-` | `make 2nd operand 16bit` | -| `OP_EXT3` | `-` | `make 1st and 2nd operands 16bit` | -| `OP_STOP` | `-` | `stop VM` | -|------------------|--------------|----------------------------------------------------------| +| Instruction Name | Operand type | Semantics | +|--------------------|----------------|------------------------------------------------------------| +| `OP_NOP` | `-` | `no operation` | +| `OP_MOVE` | `BB` | `R(a) = R(b)` | +| `OP_LOADL` | `BB` | `R(a) = Pool(b)` | +| `OP_LOADI` | `BB` | `R(a) = mrb_int(b)` | +| `OP_LOADINEG` | `BB` | `R(a) = mrb_int(-b)` | +| `OP_LOADI__1` | `B` | `R(a) = mrb_int(-1)` | +| `OP_LOADI_0` | `B` | `R(a) = mrb_int(0)` | +| `OP_LOADI_1` | `B` | `R(a) = mrb_int(1)` | +| `OP_LOADI_2` | `B` | `R(a) = mrb_int(2)` | +| `OP_LOADI_3` | `B` | `R(a) = mrb_int(3)` | +| `OP_LOADI_4` | `B` | `R(a) = mrb_int(4)` | +| `OP_LOADI_5` | `B` | `R(a) = mrb_int(5)` | +| `OP_LOADI_6` | `B` | `R(a) = mrb_int(6)` | +| `OP_LOADI_7` | `B` | `R(a) = mrb_int(7)` | +| `OP_LOADI16` | `BS` | `R(a) = mrb_int(b)` | +| `OP_LOADI32` | `BSS` | `R(a) = mrb_int((b<<16)+c)` | +| `OP_LOADSYM` | `BB` | `R(a) = Syms(b)` | +| `OP_LOADNIL` | `B` | `R(a) = nil` | +| `OP_LOADSELF` | `B` | `R(a) = self` | +| `OP_LOADT` | `B` | `R(a) = true` | +| `OP_LOADF` | `B` | `R(a) = false` | +| `OP_GETGV` | `BB` | `R(a) = getglobal(Syms(b))` | +| `OP_SETGV` | `BB` | `setglobal(Syms(b), R(a))` | +| `OP_GETSV` | `BB` | `R(a) = Special[Syms(b)]` | +| `OP_SETSV` | `BB` | `Special[Syms(b)] = R(a)` | +| `OP_GETIV` | `BB` | `R(a) = ivget(Syms(b))` | +| `OP_SETIV` | `BB` | `ivset(Syms(b),R(a))` | +| `OP_GETCV` | `BB` | `R(a) = cvget(Syms(b))` | +| `OP_SETCV` | `BB` | `cvset(Syms(b),R(a))` | +| `OP_GETCONST` | `BB` | `R(a) = constget(Syms(b))` | +| `OP_SETCONST` | `BB` | `constset(Syms(b),R(a))` | +| `OP_GETMCNST` | `BB` | `R(a) = R(a)::Syms(b)` | +| `OP_SETMCNST` | `BB` | `R(a+1)::Syms(b) = R(a)` | +| `OP_GETUPVAR` | `BBB` | `R(a) = uvget(b,c)` | +| `OP_SETUPVAR` | `BBB` | `uvset(b,c,R(a))` | +| `OP_JMP` | `S` | `pc+=a` | +| `OP_JMPIF` | `BS` | `if R(a) pc+=b` | +| `OP_JMPNOT` | `BS` | `if !R(a) pc+=b` | +| `OP_JMPNIL` | `BS` | `if R(a)==nil pc+=b` | +| `OP_JMPUW` | `S` | `unwind_and_jump_to(a)` | +| `OP_EXCEPT` | `B` | `R(a) = exc` | +| `OP_RESCUE` | `BB` | `R(b) = R(a).isa?(R(b))` | +| `OP_RAISEIF` | `B` | `raise(R(a)) if R(a)` | +| `OP_SEND` | `BBB` | `R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c))` | +| `OP_SENDB` | `BBB` | `R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c),&R(a+c+1))` | +| `OP_CALL` | `-` | `R(0) = self.call(frame.argc, frame.argv)` | +| `OP_SUPER` | `BB` | `R(a) = super(R(a+1),... ,R(a+b+1))` | +| `OP_ARGARY` | `BS` | `R(a) = argument array (16=m5:r1:m5:d1:lv4)` | +| `OP_ENTER` | `W` | `arg setup according to flags (23=m5:o5:r1:m5:k5:d1:b1)` | +| `OP_KEY_P` | `BB` | `R(a) = kdict.key?(Syms(b))` | +| `OP_KEYEND` | `-` | `raise unless kdict.empty?` | +| `OP_KARG` | `BB` | `R(a) = kdict[Syms(b)]; kdict.delete(Syms(b))` | +| `OP_RETURN` | `B` | `return R(a) (normal)` | +| `OP_RETURN_BLK` | `B` | `return R(a) (in-block return)` | +| `OP_BREAK` | `B` | `break R(a)` | +| `OP_BLKPUSH` | `BS` | `R(a) = block (16=m5:r1:m5:d1:lv4)` | +| `OP_ADD` | `B` | `R(a) = R(a)+R(a+1)` | +| `OP_ADDI` | `BB` | `R(a) = R(a)+mrb_int(b)` | +| `OP_SUB` | `B` | `R(a) = R(a)-R(a+1)` | +| `OP_SUBI` | `BB` | `R(a) = R(a)-mrb_int(b)` | +| `OP_MUL` | `B` | `R(a) = R(a)*R(a+1)` | +| `OP_DIV` | `B` | `R(a) = R(a)/R(a+1)` | +| `OP_EQ` | `B` | `R(a) = R(a)==R(a+1)` | +| `OP_LT` | `B` | `R(a) = R(a)R(a+1)` | +| `OP_GE` | `B` | `R(a) = R(a)>=R(a+1)` | +| `OP_ARRAY` | `BB` | `R(a) = ary_new(R(a),R(a+1)..R(a+b))` | +| `OP_ARRAY2` | `BBB` | `R(a) = ary_new(R(b),R(b+1)..R(b+c))` | +| `OP_ARYCAT` | `B` | `ary_cat(R(a),R(a+1))` | +| `OP_ARYPUSH` | `BB` | `ary_push(R(a),R(a+1)..R(a+b))` | +| `OP_ARYDUP` | `B` | `R(a) = ary_dup(R(a))` | +| `OP_AREF` | `BBB` | `R(a) = R(b)[c]` | +| `OP_ASET` | `BBB` | `R(b)[c] = R(a)` | +| `OP_APOST` | `BBB` | `*R(a),R(a+1)..R(a+c) = R(a)[b..]` | +| `OP_INTERN` | `B` | `R(a) = intern(R(a))` | +| `OP_STRING` | `BB` | `R(a) = str_dup(Pool(b))` | +| `OP_STRCAT` | `B` | `str_cat(R(a),R(a+1))` | +| `OP_HASH` | `BB` | `R(a) = hash_new(R(a),R(a+1)..R(a+b*2-1))` | +| `OP_HASHADD` | `BB` | `hash_push(R(a),R(a+1)..R(a+b*2))` | +| `OP_HASHCAT` | `B` | `R(a) = hash_cat(R(a),R(a+1))` | +| `OP_LAMBDA` | `BB` | `R(a) = lambda(Irep(b),OP_L_LAMBDA)` | +| `OP_BLOCK` | `BB` | `R(a) = lambda(Irep(b),OP_L_BLOCK)` | +| `OP_METHOD` | `BB` | `R(a) = lambda(Irep(b),OP_L_METHOD)` | +| `OP_RANGE_INC` | `B` | `R(a) = range_new(R(a),R(a+1),FALSE)` | +| `OP_RANGE_EXC` | `B` | `R(a) = range_new(R(a),R(a+1),TRUE)` | +| `OP_OCLASS` | `B` | `R(a) = ::Object` | +| `OP_CLASS` | `BB` | `R(a) = newclass(R(a),Syms(b),R(a+1))` | +| `OP_MODULE` | `BB` | `R(a) = newmodule(R(a),Syms(b))` | +| `OP_EXEC` | `BB` | `R(a) = blockexec(R(a),Irep[b])` | +| `OP_DEF` | `BB` | `R(a).newmethod(Syms(b),R(a+1)); R(a) = Syms(b)` | +| `OP_ALIAS` | `BB` | `alias_method(target_class,Syms(a),Syms(b))` | +| `OP_UNDEF` | `B` | `undef_method(target_class,Syms(a))` | +| `OP_SCLASS` | `B` | `R(a) = R(a).singleton_class` | +| `OP_TCLASS` | `B` | `R(a) = target_class` | +| `OP_DEBUG` | `BBB` | `print a,b,c` | +| `OP_ERR` | `B` | `raise(LocalJumpError, Pool(a))` | +| `OP_EXT1` | `-` | `make 1st operand 16bit` | +| `OP_EXT2` | `-` | `make 2nd operand 16bit` | +| `OP_EXT3` | `-` | `make 1st and 2nd operands 16bit` | +| `OP_STOP` | `-` | `stop VM` | +| ------------------ | -------------- | ---------------------------------------------------------- | diff --git a/doc/mruby3.0.md b/doc/mruby3.0.md index 09d2c4af9..359d82c7b 100644 --- a/doc/mruby3.0.md +++ b/doc/mruby3.0.md @@ -75,7 +75,7 @@ to be default `mrb_value` representation. Now the default is ## `MRB_WORD_BOXING` Pack `mrb_value` in an `intptr_t` integer. Consumes less -memory compared to `MRB_NO_BOXING` especially on 32 bit +memory compared to `MRB_NO_BOXING` especially on 32-bit platforms. `Fixnum` size is 31 bits so some integer values does not fit in `Fixnum` integers. @@ -116,7 +116,7 @@ Instructions that access pool[i]/syms[i] where i>255. * `OP_STRING16` * `OP_LOADSYM16` -Instructions that load a 32 bit integer. +Instructions that load a 32-bit integer. * `OP_LOADI32` diff --git a/doc/mruby3.2.md b/doc/mruby3.2.md new file mode 100644 index 000000000..bbb274e76 --- /dev/null +++ b/doc/mruby3.2.md @@ -0,0 +1,44 @@ +# User visible changes in `mruby3.2` from `mruby3.1` + +# The language + +- Now `a::B = c` should evaluate `a` then `c`. +- Anonymous arguments `*`, `**`, `&` can be passed for forwarding. +- Multi-precision integer is available now via `mruby-bigint` gem. + +# Tools + +## `mruby` + +- `-b` only specifies the script is the binary. The files loaded by `-r` are not affected by the option. +- `mruby` now loads complied binary if the suffix is `.mrb`. + +## `mrbc` + +- Add `--no-optimize` option to disable optimization. + +# mrbgems + +## mruby-errno + +- `mruby-errno` gem is now bundled. + +## mruby-class-ext + +- Add `Class#subclasses` method. +- Add `Module#undefined_instance_methods` method. + +# CVEs + +Following CVEs are fixed. + +- [CVE-2022-0481](https://nvd.nist.gov/vuln/detail/CVE-2022-0481) +- [CVE-2022-0525](https://nvd.nist.gov/vuln/detail/CVE-2022-0525) +- [CVE-2022-0570](https://nvd.nist.gov/vuln/detail/CVE-2022-0570) +- [CVE-2022-0614](https://nvd.nist.gov/vuln/detail/CVE-2022-0614) +- [CVE-2022-0623](https://nvd.nist.gov/vuln/detail/CVE-2022-0623) +- [CVE-2022-0630](https://nvd.nist.gov/vuln/detail/CVE-2022-0630) +- [CVE-2022-0717](https://nvd.nist.gov/vuln/detail/CVE-2022-0817) +- [CVE-2022-1212](https://nvd.nist.gov/vuln/detail/CVE-2022-1212) +- [CVE-2022-1276](https://nvd.nist.gov/vuln/detail/CVE-2022-1276) +- [CVE-2022-1286](https://nvd.nist.gov/vuln/detail/CVE-2022-1286) diff --git a/include/mruby.h b/include/mruby.h index 3e92021ac..2eff81245 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -312,7 +312,7 @@ typedef struct mrb_state { struct RClass *eException_class; struct RClass *eStandardError_class; struct RObject *nomem_err; /* pre-allocated NoMemoryError */ - struct RObject *stack_err; /* pre-allocated SysStackError */ + struct RObject *stack_err; /* pre-allocated SystemStackError */ #ifdef MRB_GC_FIXED_ARENA struct RObject *arena_err; /* pre-allocated arena overflow error */ #endif @@ -948,14 +948,14 @@ typedef const char *mrb_args_format; /** * Get keyword arguments by `mrb_get_args()` with `:` specifier. * - * `mrb_kwargs::num` indicates that the number of keyword values. + * `mrb_kwargs::num` indicates that the total number of keyword values. * - * `mrb_kwargs::values` is an object array, and the keyword argument corresponding to the string array is assigned. - * Note that `undef` is assigned if there is no keyword argument corresponding to `mrb_kwargs::optional`. + * `mrb_kwargs::required` indicates that the specified number of keywords starting from the beginning of the `mrb_sym` array are required. * - * `mrb_kwargs::table` accepts a string array. + * `mrb_kwargs::table` accepts a `mrb_sym` array of C. * - * `mrb_kwargs::required` indicates that the specified number of keywords starting from the beginning of the string array are required. + * `mrb_kwargs::values` is an object array of C, and the keyword argument corresponding to the `mrb_sym` array is assigned. + * Note that `undef` is assigned if there is no keyword argument corresponding over `mrb_kwargs::required` to `mrb_kwargs::num`. * * `mrb_kwargs::rest` is the remaining keyword argument that can be accepted as `**rest` in Ruby. * If `NULL` is specified, `ArgumentError` is raised when there is an undefined keyword. @@ -965,10 +965,10 @@ typedef const char *mrb_args_format; * // def method(a: 1, b: 2) * * uint32_t kw_num = 2; - * const char *kw_names[kw_num] = { "a", "b" }; * uint32_t kw_required = 0; + * mrb_sym kw_names[] = { mrb_intern_lit(mrb, "a"), mrb_intern_lit(mrb, "b") }; * mrb_value kw_values[kw_num]; - * const mrb_kwargs kwargs = { kw_num, kw_required, kw_names, kw_values, NULL }; + * mrb_kwargs kwargs = { kw_num, kw_required, kw_names, kw_values, NULL }; * * mrb_get_args(mrb, ":", &kwargs); * if (mrb_undef_p(kw_values[0])) { kw_values[0] = mrb_fixnum_value(1); } @@ -979,10 +979,12 @@ typedef const char *mrb_args_format; * * mrb_value str, kw_rest; * uint32_t kw_num = 3; - * const mrb_sym kw_names[kw_num] = { MRB_SYM(x), MRB_SYM(y), MRB_SYM(z) }; * uint32_t kw_required = 1; + * // Note that `#include ` is required beforehand because `MRB_SYM()` is used. + * // If the usage of `MRB_SYM()` is not desired, replace it with `mrb_intern_lit()`. + * mrb_sym kw_names[] = { MRB_SYM(x), MRB_SYM(y), MRB_SYM(z) }; * mrb_value kw_values[kw_num]; - * const mrb_kwargs kwargs = { kw_num, kw_required, kw_names, kw_values, &kw_rest }; + * mrb_kwargs kwargs = { kw_num, kw_required, kw_names, kw_values, &kw_rest }; * * mrb_get_args(mrb, "S:", &str, &kwargs); * // or: mrb_get_args(mrb, ":S", &kwargs, &str); @@ -1178,13 +1180,13 @@ MRB_API void mrb_free(mrb_state*, void*); */ #define MRB_OBJ_ALLOC(mrb, tt, klass) ((MRB_VTYPE_TYPEOF(tt)*)mrb_obj_alloc(mrb, tt, klass)) -MRB_API mrb_value mrb_str_new(mrb_state *mrb, const char *p, size_t len); +MRB_API mrb_value mrb_str_new(mrb_state *mrb, const char *p, mrb_int len); /** * Turns a C string into a Ruby string value. */ MRB_API mrb_value mrb_str_new_cstr(mrb_state*, const char*); -MRB_API mrb_value mrb_str_new_static(mrb_state *mrb, const char *p, size_t len); +MRB_API mrb_value mrb_str_new_static(mrb_state *mrb, const char *p, mrb_int len); #define mrb_str_new_lit(mrb, lit) mrb_str_new_static(mrb, (lit), mrb_strlen_lit(lit)) MRB_API mrb_value mrb_obj_freeze(mrb_state*, mrb_value); @@ -1336,7 +1338,7 @@ MRB_API mrb_value mrb_obj_clone(mrb_state *mrb, mrb_value self); #define TOLOWER(c) (ISUPPER(c) ? ((c) | 0x20) : (c)) #endif -MRB_API mrb_value mrb_exc_new(mrb_state *mrb, struct RClass *c, const char *ptr, size_t len); +MRB_API mrb_value mrb_exc_new(mrb_state *mrb, struct RClass *c, const char *ptr, mrb_int len); MRB_API mrb_noreturn void mrb_exc_raise(mrb_state *mrb, mrb_value exc); MRB_API mrb_noreturn void mrb_raise(mrb_state *mrb, struct RClass *c, const char *msg); @@ -1404,6 +1406,9 @@ MRB_API mrb_value mrb_check_string_type(mrb_state *mrb, mrb_value str); #define mrb_to_str(mrb, str) mrb_ensure_string_type(mrb,str) /* obsolete: use mrb_obj_as_string() instead */ #define mrb_str_to_str(mrb, str) mrb_obj_as_string(mrb, str) +/* check if val is an integer (including Bigint) */ +MRB_API mrb_value mrb_ensure_integer_type(mrb_state *mrb, mrb_value val); +/* check if val fit in mrb_int */ MRB_API mrb_value mrb_ensure_int_type(mrb_state *mrb, mrb_value val); #define mrb_as_int(mrb, val) mrb_integer(mrb_ensure_int_type(mrb, val)) /* obsolete: use mrb_ensure_int_type() instead */ diff --git a/include/mruby/array.h b/include/mruby/array.h index 8bb652472..df5a16a91 100644 --- a/include/mruby/array.h +++ b/include/mruby/array.h @@ -85,7 +85,6 @@ struct RArray { #define ARY_SET_SHARED_FLAG(a) ((a)->flags |= MRB_ARY_SHARED) #define ARY_UNSET_SHARED_FLAG(a) ((a)->flags &= ~MRB_ARY_SHARED) -void mrb_ary_decref(mrb_state*, mrb_shared_array*); MRB_API void mrb_ary_modify(mrb_state*, struct RArray*); MRB_API mrb_value mrb_ary_new_capa(mrb_state*, mrb_int); @@ -296,8 +295,6 @@ MRB_API mrb_value mrb_ary_join(mrb_state *mrb, mrb_value ary, mrb_value sep); */ MRB_API mrb_value mrb_ary_resize(mrb_state *mrb, mrb_value ary, mrb_int new_len); -/* helper functions */ -mrb_value mrb_ary_subseq(mrb_state *mrb, mrb_value ary, mrb_int beg, mrb_int len); MRB_END_DECL diff --git a/include/mruby/class.h b/include/mruby/class.h index b97bc3991..ff16f1ac1 100644 --- a/include/mruby/class.h +++ b/include/mruby/class.h @@ -73,8 +73,6 @@ mrb_class(mrb_state *mrb, mrb_value v) #define MRB_SET_INSTANCE_TT(c, tt) ((c)->flags = (((c)->flags & ~MRB_INSTANCE_TT_MASK) | (char)(tt))) #define MRB_INSTANCE_TT(c) (enum mrb_vtype)((c)->flags & MRB_INSTANCE_TT_MASK) -struct RClass *mrb_vm_define_class(mrb_state*, mrb_value, mrb_value, mrb_sym); -struct RClass *mrb_vm_define_module(mrb_state*, mrb_value, mrb_sym); MRB_API void mrb_define_method_raw(mrb_state*, struct RClass*, mrb_sym, mrb_method_t); MRB_API void mrb_alias_method(mrb_state*, struct RClass *c, mrb_sym a, mrb_sym b); MRB_API void mrb_remove_method(mrb_state *mrb, struct RClass *c, mrb_sym sym); @@ -83,15 +81,6 @@ MRB_API mrb_method_t mrb_method_search_vm(mrb_state*, struct RClass**, mrb_sym); MRB_API mrb_method_t mrb_method_search(mrb_state*, struct RClass*, mrb_sym); MRB_API struct RClass* mrb_class_real(struct RClass* cl); -mrb_value mrb_instance_new(mrb_state *mrb, mrb_value cv); - -void mrb_class_name_class(mrb_state*, struct RClass*, struct RClass*, mrb_sym); -mrb_bool mrb_const_name_p(mrb_state*, const char*, mrb_int); -mrb_value mrb_class_find_path(mrb_state*, struct RClass*); -mrb_value mrb_mod_to_s(mrb_state*, mrb_value); -void mrb_gc_mark_mt(mrb_state*, struct RClass*); -size_t mrb_gc_mark_mt_size(mrb_state*, struct RClass*); -void mrb_gc_free_mt(mrb_state*, struct RClass*); #ifndef MRB_NO_METHOD_CACHE void mrb_mc_clear_by_class(mrb_state *mrb, struct RClass* c); diff --git a/include/mruby/debug.h b/include/mruby/debug.h index 7319ccb3f..4a62cce42 100644 --- a/include/mruby/debug.h +++ b/include/mruby/debug.h @@ -31,10 +31,11 @@ typedef struct mrb_irep_debug_info_file { uint32_t line_entry_count; mrb_debug_line_type line_type; union { + const char *s; void *ptr; - uint16_t *ary; - mrb_irep_debug_info_line *flat_map; - uint8_t *packed_map; + const uint16_t *ary; + const mrb_irep_debug_info_line *flat_map; + const uint8_t *packed_map; } lines; } mrb_irep_debug_info_file; diff --git a/include/mruby/dump.h b/include/mruby/dump.h index fea0ac2b1..a976deef0 100644 --- a/include/mruby/dump.h +++ b/include/mruby/dump.h @@ -21,15 +21,11 @@ MRB_BEGIN_DECL #define MRB_DUMP_STATIC 2 #define DUMP_DEBUG_INFO MRB_DUMP_DEBUG_INFO /* deprecated */ -int mrb_dump_irep(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size); #ifndef MRB_NO_STDIO -int mrb_dump_irep_binary(mrb_state*, const mrb_irep*, uint8_t, FILE*); -int mrb_dump_irep_cfunc(mrb_state *mrb, const mrb_irep*, uint8_t flags, FILE *f, const char *initname); -int mrb_dump_irep_cstruct(mrb_state *mrb, const mrb_irep*, uint8_t flags, FILE *f, const char *initname); -mrb_irep *mrb_read_irep_file(mrb_state*, FILE*); MRB_API mrb_value mrb_load_irep_file(mrb_state*,FILE*); MRB_API mrb_value mrb_load_irep_file_cxt(mrb_state*, FILE*, mrbc_context*); #endif +/* avoid mrb_read_irep(); use mrb_read_irep_buf() instead (may cause buffer overflow) */ MRB_API mrb_irep *mrb_read_irep(mrb_state*, const uint8_t*); MRB_API mrb_irep *mrb_read_irep_buf(mrb_state*, const void*, size_t); diff --git a/include/mruby/error.h b/include/mruby/error.h index 80c21434f..82ba38f75 100644 --- a/include/mruby/error.h +++ b/include/mruby/error.h @@ -17,20 +17,16 @@ MRB_BEGIN_DECL struct RException { MRB_OBJECT_HEADER; struct iv_tbl *iv; - struct RString *mesg; + struct RObject *mesg; // NULL or probably RString + struct RObject *backtrace; // NULL, RArray or RData }; #define mrb_exc_ptr(v) ((struct RException*)mrb_ptr(v)) -#define MRB_EXC_MESG_STRING_FLAG 0x100 -MRB_API void mrb_sys_fail(mrb_state *mrb, const char *mesg); +MRB_API mrb_noreturn void mrb_sys_fail(mrb_state *mrb, const char *mesg); MRB_API mrb_value mrb_exc_new_str(mrb_state *mrb, struct RClass* c, mrb_value str); #define mrb_exc_new_lit(mrb, c, lit) mrb_exc_new_str(mrb, c, mrb_str_new_lit(mrb, lit)) -#define mrb_exc_new_str_lit(mrb, c, lit) mrb_exc_new_lit(mrb, c, lit) MRB_API mrb_value mrb_make_exception(mrb_state *mrb, mrb_int argc, const mrb_value *argv); -mrb_value mrb_exc_backtrace(mrb_state *mrb, mrb_value exc); -mrb_value mrb_get_backtrace(mrb_state *mrb); - MRB_API mrb_noreturn void mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_value args, const char *fmt, ...); /* declaration for `fail` method */ diff --git a/include/mruby/gc.h b/include/mruby/gc.h index 9f9bba410..9f4ceec4d 100644 --- a/include/mruby/gc.h +++ b/include/mruby/gc.h @@ -84,8 +84,7 @@ typedef struct mrb_gc { size_t majorgc_old_threshold; } mrb_gc; -MRB_API mrb_bool -mrb_object_dead_p(struct mrb_state *mrb, struct RBasic *object); +MRB_API mrb_bool mrb_object_dead_p(struct mrb_state *mrb, struct RBasic *object); #define MRB_GC_RED 7 diff --git a/include/mruby/hash.h b/include/mruby/hash.h index 1b37a12d4..e591172ea 100644 --- a/include/mruby/hash.h +++ b/include/mruby/hash.h @@ -35,7 +35,6 @@ struct RHash { #define mrb_hash_ptr(v) ((struct RHash*)(mrb_ptr(v))) #define mrb_hash_value(p) mrb_obj_value((void*)(p)) -size_t mrb_hash_memsize(mrb_value obj); MRB_API mrb_value mrb_hash_new_capa(mrb_state *mrb, mrb_int capa); /* @@ -226,11 +225,6 @@ MRB_API void mrb_hash_merge(mrb_state *mrb, mrb_value hash1, mrb_value hash2); #define MRB_RHASH_DEFAULT_P(hash) (RHASH(hash)->flags & MRB_HASH_DEFAULT) #define MRB_RHASH_PROCDEFAULT_P(hash) (RHASH(hash)->flags & MRB_HASH_PROC_DEFAULT) -/* GC functions */ -void mrb_gc_mark_hash(mrb_state*, struct RHash*); -size_t mrb_gc_mark_hash_size(mrb_state*, struct RHash*); -void mrb_gc_free_hash(mrb_state*, struct RHash*); - /* return non zero to break the loop */ typedef int (mrb_hash_foreach_func)(mrb_state *mrb, mrb_value key, mrb_value val, void *data); MRB_API void mrb_hash_foreach(mrb_state *mrb, struct RHash *hash, mrb_hash_foreach_func *func, void *p); diff --git a/include/mruby/internal.h b/include/mruby/internal.h new file mode 100644 index 000000000..be71f0799 --- /dev/null +++ b/include/mruby/internal.h @@ -0,0 +1,192 @@ +/** +** @file mruby/internal.h - Functions only called from within the library +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_INTERNAL_H +#define MRUBY_INTERNAL_H + +#ifdef MRUBY_ARRAY_H +void mrb_ary_decref(mrb_state*, mrb_shared_array*); +mrb_value mrb_ary_subseq(mrb_state *mrb, mrb_value ary, mrb_int beg, mrb_int len); +#endif + +#ifdef MRUBY_CLASS_H +struct RClass *mrb_vm_define_class(mrb_state*, mrb_value, mrb_value, mrb_sym); +struct RClass *mrb_vm_define_module(mrb_state*, mrb_value, mrb_sym); +mrb_value mrb_instance_new(mrb_state *mrb, mrb_value cv); +void mrb_class_name_class(mrb_state*, struct RClass*, struct RClass*, mrb_sym); +mrb_bool mrb_const_name_p(mrb_state*, const char*, mrb_int); +mrb_value mrb_class_find_path(mrb_state*, struct RClass*); +mrb_value mrb_mod_to_s(mrb_state *, mrb_value); +void mrb_method_added(mrb_state *mrb, struct RClass *c, mrb_sym mid); +#endif + +/* debug */ +size_t mrb_packed_int_len(uint32_t num); +size_t mrb_packed_int_encode(uint32_t num, uint8_t *p, uint8_t *pend); +uint32_t mrb_packed_int_decode(const uint8_t *p, const uint8_t **newpos); + +/* dump */ +#ifdef MRUBY_IREP_H +int mrb_dump_irep(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size); +#ifndef MRB_NO_STDIO +int mrb_dump_irep_binary(mrb_state*, const mrb_irep*, uint8_t, FILE*); +int mrb_dump_irep_cfunc(mrb_state *mrb, const mrb_irep*, uint8_t flags, FILE *f, const char *initname); +int mrb_dump_irep_cstruct(mrb_state *mrb, const mrb_irep*, uint8_t flags, FILE *f, const char *initname); +mrb_irep *mrb_read_irep_file(mrb_state*, FILE*); +#endif +#endif + +/* error */ +mrb_value mrb_exc_inspect(mrb_state *mrb, mrb_value exc); +mrb_value mrb_exc_backtrace(mrb_state *mrb, mrb_value exc); +mrb_value mrb_get_backtrace(mrb_state *mrb); +void mrb_exc_mesg_set(mrb_state *mrb, struct RException *exc, mrb_value mesg); +mrb_value mrb_exc_mesg_get(mrb_state *mrb, struct RException *exc); + +/* gc */ +void mrb_gc_mark_mt(mrb_state*, struct RClass*); +size_t mrb_gc_mark_mt_size(mrb_state*, struct RClass*); +void mrb_gc_free_mt(mrb_state*, struct RClass*); + +/* hash */ +size_t mrb_hash_memsize(mrb_value obj); +void mrb_gc_mark_hash(mrb_state*, struct RHash*); +size_t mrb_gc_mark_hash_size(mrb_state*, struct RHash*); +void mrb_gc_free_hash(mrb_state*, struct RHash*); + +/* irep */ +struct mrb_insn_data mrb_decode_insn(const mrb_code *pc); +#ifdef MRUBY_IREP_H +void mrb_irep_free(mrb_state*, struct mrb_irep*); +void mrb_irep_incref(mrb_state*, struct mrb_irep*); +void mrb_irep_decref(mrb_state*, struct mrb_irep*); +void mrb_irep_cutref(mrb_state*, struct mrb_irep*); +void mrb_irep_remove_lv(mrb_state *mrb, mrb_irep *irep); + +static inline const struct mrb_irep_catch_handler * +mrb_irep_catch_handler_table(const struct mrb_irep *irep) +{ + if (irep->clen > 0) { + return (const struct mrb_irep_catch_handler*)(irep->iseq + irep->ilen); + } + else { + return (const struct mrb_irep_catch_handler*)NULL; + } +} +#endif + +/* numeric */ +mrb_int mrb_div_int(mrb_state *mrb, mrb_int x, mrb_int y); +mrb_value mrb_int_add(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_int_sub(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_int_mul(mrb_state *mrb, mrb_value x, mrb_value y); +void mrb_int_zerodiv(mrb_state *mrb); +void mrb_int_overflow(mrb_state *mrb, const char *reason); + +#ifdef MRB_USE_COMPLEX +mrb_value mrb_complex_new(mrb_state *mrb, mrb_float x, mrb_float y); +mrb_value mrb_complex_add(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_complex_sub(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_complex_mul(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_complex_div(mrb_state *mrb, mrb_value x, mrb_value y); +#endif +#ifdef MRB_USE_RATIONAL +mrb_value mrb_rational_new(mrb_state *mrb, mrb_int x, mrb_int y); +mrb_value mrb_rational_add(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_rational_sub(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_rational_mul(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_rational_div(mrb_state *mrb, mrb_value x, mrb_value y); +#endif + +#ifdef MRUBY_PROC_H +struct RProc *mrb_proc_new(mrb_state*, const mrb_irep*); +struct RProc *mrb_closure_new(mrb_state*, const mrb_irep*); +void mrb_proc_copy(mrb_state *mrb, struct RProc *a, struct RProc *b); +mrb_int mrb_proc_arity(const struct RProc *p); +#endif + +/* range */ +#ifdef MRUBY_RANGE_H +mrb_value mrb_get_values_at(mrb_state *mrb, mrb_value obj, mrb_int olen, mrb_int argc, const mrb_value *argv, mrb_value (*func)(mrb_state*, mrb_value, mrb_int)); +void mrb_gc_mark_range(mrb_state *mrb, struct RRange *r); +#endif + +/* string */ +void mrb_gc_free_str(mrb_state*, struct RString*); +uint32_t mrb_str_hash(mrb_state *mrb, mrb_value str); +mrb_value mrb_str_dump(mrb_state *mrb, mrb_value str); +mrb_value mrb_str_inspect(mrb_state *mrb, mrb_value str); +mrb_bool mrb_str_beg_len(mrb_int str_len, mrb_int *begp, mrb_int *lenp); +mrb_value mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len); +mrb_value mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value idx, mrb_value len); + +#ifdef MRB_UTF8_STRING +mrb_int mrb_utf8len(const char *str, const char *end); +mrb_int mrb_utf8_strlen(const char *str, mrb_int byte_len); +#endif + +/* variable */ +mrb_value mrb_vm_special_get(mrb_state*, mrb_sym); +void mrb_vm_special_set(mrb_state*, mrb_sym, mrb_value); +mrb_value mrb_vm_cv_get(mrb_state*, mrb_sym); +void mrb_vm_cv_set(mrb_state*, mrb_sym, mrb_value); +mrb_value mrb_vm_const_get(mrb_state*, mrb_sym); +void mrb_vm_const_set(mrb_state*, mrb_sym, mrb_value); +size_t mrb_obj_iv_tbl_memsize(mrb_value); +mrb_value mrb_obj_iv_inspect(mrb_state*, struct RObject*); +void mrb_obj_iv_set_force(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v); +mrb_value mrb_mod_constants(mrb_state *mrb, mrb_value mod); +mrb_value mrb_f_global_variables(mrb_state *mrb, mrb_value self); +mrb_value mrb_obj_instance_variables(mrb_state*, mrb_value); +mrb_value mrb_mod_class_variables(mrb_state*, mrb_value); +mrb_value mrb_mod_cv_get(mrb_state *mrb, struct RClass * c, mrb_sym sym); +mrb_bool mrb_mod_cv_defined(mrb_state *mrb, struct RClass * c, mrb_sym sym); +mrb_bool mrb_ident_p(const char *s, mrb_int len); + +/* GC functions */ +void mrb_gc_mark_gv(mrb_state*); +void mrb_gc_free_gv(mrb_state*); +void mrb_gc_mark_iv(mrb_state*, struct RObject*); +size_t mrb_gc_mark_iv_size(mrb_state*, struct RObject*); +void mrb_gc_free_iv(mrb_state*, struct RObject*); + +/* VM */ +mrb_int mrb_ci_bidx(mrb_callinfo *ci); + +#ifdef MRB_USE_BIGINT +mrb_value mrb_bint_new_int(mrb_state *mrb, mrb_int x); +mrb_value mrb_bint_new_str(mrb_state *mrb, const char *x, mrb_int len, mrb_int base); +mrb_value mrb_as_bint(mrb_state *mrb, mrb_value x); +mrb_value mrb_bint_add(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_bint_sub(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_bint_mul(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_bint_div(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_bint_divmod(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_bint_add_ii(mrb_state *mrb, mrb_int x, mrb_int y); +mrb_value mrb_bint_sub_ii(mrb_state *mrb, mrb_int x, mrb_int y); +mrb_value mrb_bint_mul_ii(mrb_state *mrb, mrb_int x, mrb_int y); +mrb_value mrb_bint_div_ii(mrb_state *mrb, mrb_int x, mrb_int y); +mrb_value mrb_bint_mod(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_bint_rem(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_bint_pow(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_bint_powm(mrb_state *mrb, mrb_value x, mrb_int y, mrb_value z); +mrb_value mrb_bint_and(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_bint_or(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_bint_xor(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_bint_rev(mrb_state *mrb, mrb_value x); +mrb_value mrb_bint_lshift(mrb_state *mrb, mrb_value x, mrb_int width); +mrb_value mrb_bint_rshift(mrb_state *mrb, mrb_value x, mrb_int width); +mrb_value mrb_bint_to_s(mrb_state *mrb, mrb_value x, mrb_int base); +#ifndef MRB_NO_FLOAT +mrb_value mrb_bint_new_float(mrb_state *mrb, mrb_float x); +mrb_float mrb_bint_as_float(mrb_state *mrb, mrb_value x); +#endif +mrb_int mrb_bint_as_int(mrb_state *mrb, mrb_value x); +mrb_int mrb_bint_cmp(mrb_state *mrb, mrb_value x, mrb_value y); +void mrb_gc_free_bint(mrb_state *mrb, struct RBasic *x); +#endif + +#endif /* MRUBY_INTERNAL_H */ diff --git a/include/mruby/irep.h b/include/mruby/irep.h index 8382c3b18..9957c98d2 100644 --- a/include/mruby/irep.h +++ b/include/mruby/irep.h @@ -99,7 +99,7 @@ MRB_API mrb_value mrb_load_irep(mrb_state*, const uint8_t*); /* * @param [const void*] irep code - * @param [size_t] size of irep buffer. If -1 is given, it is considered unrestricted. + * @param [size_t] size of irep buffer. */ MRB_API mrb_value mrb_load_irep_buf(mrb_state*, const void*, size_t); @@ -108,16 +108,10 @@ MRB_API mrb_value mrb_load_irep_cxt(mrb_state*, const uint8_t*, mrbc_context*); /* * @param [const void*] irep code - * @param [size_t] size of irep buffer. If -1 is given, it is considered unrestricted. + * @param [size_t] size of irep buffer. */ MRB_API mrb_value mrb_load_irep_buf_cxt(mrb_state*, const void*, size_t, mrbc_context*); -void mrb_irep_free(mrb_state*, struct mrb_irep*); -void mrb_irep_incref(mrb_state*, struct mrb_irep*); -void mrb_irep_decref(mrb_state*, struct mrb_irep*); -void mrb_irep_cutref(mrb_state*, struct mrb_irep*); -void mrb_irep_remove_lv(mrb_state *mrb, mrb_irep *irep); - struct mrb_insn_data { uint8_t insn; uint16_t a; @@ -126,19 +120,6 @@ struct mrb_insn_data { const mrb_code *addr; }; -struct mrb_insn_data mrb_decode_insn(const mrb_code *pc); - -static inline const struct mrb_irep_catch_handler * -mrb_irep_catch_handler_table(const struct mrb_irep *irep) -{ - if (irep->clen > 0) { - return (const struct mrb_irep_catch_handler*)(irep->iseq + irep->ilen); - } - else { - return (const struct mrb_irep_catch_handler*)NULL; - } -} - #define mrb_irep_catch_handler_pack(n, v) uint32_to_bin(n, v) #define mrb_irep_catch_handler_unpack(v) bin_to_uint32(v) diff --git a/include/mruby/numeric.h b/include/mruby/numeric.h index aec46413c..48adea3d1 100644 --- a/include/mruby/numeric.h +++ b/include/mruby/numeric.h @@ -30,16 +30,17 @@ MRB_BEGIN_DECL #endif #endif -MRB_API mrb_value mrb_num_plus(mrb_state *mrb, mrb_value x, mrb_value y); -MRB_API mrb_value mrb_num_minus(mrb_state *mrb, mrb_value x, mrb_value y); +/* utility functions */ +MRB_API mrb_value mrb_num_add(mrb_state *mrb, mrb_value x, mrb_value y); +MRB_API mrb_value mrb_num_sub(mrb_state *mrb, mrb_value x, mrb_value y); MRB_API mrb_value mrb_num_mul(mrb_state *mrb, mrb_value x, mrb_value y); +/* obsolete old names */ +#define mrb_num_plus(mrb, x, y) mrb_num_add(mrb, x, y) +#define mrb_num_minus(mrb, x, y) mrb_num_sub(mrb, x, y) MRB_API mrb_value mrb_integer_to_str(mrb_state *mrb, mrb_value x, mrb_int base); MRB_API char *mrb_int_to_cstr(char *buf, size_t len, mrb_int n, mrb_int base); -/* internal function(s) */ -mrb_int mrb_div_int(mrb_state *mrb, mrb_int x, mrb_int y); - /* obsolete function(s); will be removed */ #define mrb_fixnum_to_str(mrb, x, base) mrb_integer_to_str(mrb, x, base) @@ -166,10 +167,6 @@ mrb_float mrb_div_float(mrb_float x, mrb_float y); mrb_value mrb_float_to_str(mrb_state *mrb, mrb_value x, const char *fmt); int mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, char sign); -/* obsolete functions; will be removed */ -#define mrb_flo_to_fixnum(mrb, val) mrb_float_to_integer(mrb, val) -#define mrb_to_flo(mrb, x) mrb_as_float(mrb, x) - #endif /* MRB_NO_FLOAT */ MRB_END_DECL diff --git a/include/mruby/proc.h b/include/mruby/proc.h index a6aa4ed7f..97ae48e96 100644 --- a/include/mruby/proc.h +++ b/include/mruby/proc.h @@ -88,12 +88,8 @@ struct RProc { #define mrb_proc_ptr(v) ((struct RProc*)(mrb_ptr(v))) -struct RProc *mrb_proc_new(mrb_state*, const mrb_irep*); -struct RProc *mrb_closure_new(mrb_state*, const mrb_irep*); MRB_API struct RProc *mrb_proc_new_cfunc(mrb_state*, mrb_func_t); MRB_API struct RProc *mrb_closure_new_cfunc(mrb_state *mrb, mrb_func_t func, int nlocals); -void mrb_proc_copy(mrb_state *mrb, struct RProc *a, struct RProc *b); -mrb_int mrb_proc_arity(const struct RProc *p); /* following functions are defined in mruby-proc-ext so please include it when using */ MRB_API struct RProc *mrb_proc_new_cfunc_with_env(mrb_state *mrb, mrb_func_t func, mrb_int argc, const mrb_value *argv); diff --git a/include/mruby/range.h b/include/mruby/range.h index fea700c24..3898ef3cf 100644 --- a/include/mruby/range.h +++ b/include/mruby/range.h @@ -71,8 +71,6 @@ enum mrb_range_beg_len { }; MRB_API enum mrb_range_beg_len mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc); -mrb_value mrb_get_values_at(mrb_state *mrb, mrb_value obj, mrb_int olen, mrb_int argc, const mrb_value *argv, mrb_value (*func)(mrb_state*, mrb_value, mrb_int)); -void mrb_gc_mark_range(mrb_state *mrb, struct RRange *r); MRB_END_DECL diff --git a/include/mruby/string.h b/include/mruby/string.h index b296832af..cd300f8bd 100644 --- a/include/mruby/string.h +++ b/include/mruby/string.h @@ -102,7 +102,6 @@ struct RStringEmbed { #define RSTRING_LEN(s) RSTR_LEN(RSTRING(s)) #define RSTRING_CAPA(s) RSTR_CAPA(RSTRING(s)) #define RSTRING_END(s) (RSTRING_PTR(s) + RSTRING_LEN(s)) -MRB_API mrb_int mrb_str_strlen(mrb_state*, struct RString*); #define RSTRING_CSTR(mrb,s) mrb_string_cstr(mrb, s) #define MRB_STR_SHARED 1 @@ -115,8 +114,6 @@ MRB_API mrb_int mrb_str_strlen(mrb_state*, struct RString*); #define MRB_STR_EMBED_LEN_MASK (((1 << MRB_STR_EMBED_LEN_BIT) - 1) << MRB_STR_EMBED_LEN_SHIFT) #define MRB_STR_TYPE_MASK 15 -void mrb_gc_free_str(mrb_state*, struct RString*); - MRB_API void mrb_str_modify(mrb_state *mrb, struct RString *s); /* mrb_str_modify() with keeping ASCII flag if set */ MRB_API void mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s); @@ -324,7 +321,7 @@ MRB_API mrb_value mrb_str_resize(mrb_state *mrb, mrb_value str, mrb_int len); */ MRB_API mrb_value mrb_str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len); -MRB_API mrb_value mrb_str_new_capa(mrb_state *mrb, size_t capa); +MRB_API mrb_value mrb_str_new_capa(mrb_state *mrb, mrb_int capa); #define mrb_str_buf_new(mrb, capa) mrb_str_new_capa(mrb, (capa)) /* NULL terminated C string from mrb_value */ @@ -332,9 +329,11 @@ MRB_API const char *mrb_string_cstr(mrb_state *mrb, mrb_value str); /* NULL terminated C string from mrb_value; `str` will be updated */ MRB_API const char *mrb_string_value_cstr(mrb_state *mrb, mrb_value *str); /* obsolete: use RSTRING_PTR() */ -MRB_API const char *mrb_string_value_ptr(mrb_state *mrb, mrb_value str); +#define mrb_string_value_ptr(mrb, str) RSTRING_PTR(str) /* obsolete: use RSTRING_LEN() */ -MRB_API mrb_int mrb_string_value_len(mrb_state *mrb, mrb_value str); +#define mrb_string_value_len(mrb, str) RSTRING_LEN(str) +/* obsolete: substituted by a macro; shall be removed */ +#define mrb_str_strlen(mrb, s) strlen(RSTR_PTR(s)) /** * Duplicates a string object. @@ -422,27 +421,11 @@ MRB_API int mrb_str_cmp(mrb_state *mrb, mrb_value str1, mrb_value str2); */ MRB_API char *mrb_str_to_cstr(mrb_state *mrb, mrb_value str); -uint32_t mrb_str_hash(mrb_state *mrb, mrb_value str); -mrb_value mrb_str_dump(mrb_state *mrb, mrb_value str); - -/** - * Returns a printable version of str, surrounded by quote marks, with special characters escaped. - */ -mrb_value mrb_str_inspect(mrb_state *mrb, mrb_value str); - /* For backward compatibility */ #define mrb_str_cat2(mrb, str, ptr) mrb_str_cat_cstr(mrb, str, ptr) #define mrb_str_buf_cat(mrb, str, ptr, len) mrb_str_cat(mrb, str, ptr, len) #define mrb_str_buf_append(mrb, str, str2) mrb_str_cat_str(mrb, str, str2) -mrb_bool mrb_str_beg_len(mrb_int str_len, mrb_int *begp, mrb_int *lenp); -mrb_value mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len); - -#ifdef MRB_UTF8_STRING -mrb_int mrb_utf8len(const char *str, const char *end); -mrb_int mrb_utf8_strlen(const char *str, mrb_int byte_len); -#endif - MRB_END_DECL #endif /* MRUBY_STRING_H */ diff --git a/include/mruby/value.h b/include/mruby/value.h index ad439334b..d3a41cefd 100644 --- a/include/mruby/value.h +++ b/include/mruby/value.h @@ -154,7 +154,8 @@ static const unsigned int IEEE754_INFINITY_BITS_SINGLE = 0x7F800000; f(MRB_TT_ISTRUCT, struct RIStruct, "istruct") \ f(MRB_TT_BREAK, struct RBreak, "break") \ f(MRB_TT_COMPLEX, struct RComplex, "Complex") \ - f(MRB_TT_RATIONAL, struct RRational, "Rational") + f(MRB_TT_RATIONAL, struct RRational, "Rational") \ + f(MRB_TT_BIGINT, struct RBigint, "Integer") enum mrb_vtype { #define MRB_VTYPE_DEFINE(tt, type, name) tt, @@ -300,6 +301,9 @@ struct RCptr { #define mrb_bool(o) (mrb_type(o) != MRB_TT_FALSE) #endif #define mrb_test(o) mrb_bool(o) +#ifndef mrb_bigint_p +#define mrb_bigint_p(o) (mrb_type(o) == MRB_TT_BIGINT) +#endif /** * Returns a float in Ruby. diff --git a/include/mruby/variable.h b/include/mruby/variable.h index 3dc2c9a6d..0a7b7b42e 100644 --- a/include/mruby/variable.h +++ b/include/mruby/variable.h @@ -14,13 +14,6 @@ */ MRB_BEGIN_DECL -mrb_value mrb_vm_special_get(mrb_state*, mrb_sym); -void mrb_vm_special_set(mrb_state*, mrb_sym, mrb_value); -mrb_value mrb_vm_cv_get(mrb_state*, mrb_sym); -void mrb_vm_cv_set(mrb_state*, mrb_sym, mrb_value); -mrb_value mrb_vm_const_get(mrb_state*, mrb_sym); -void mrb_vm_const_set(mrb_state*, mrb_sym, mrb_value); -size_t mrb_obj_iv_tbl_memsize(mrb_value); MRB_API mrb_value mrb_const_get(mrb_state*, mrb_value, mrb_sym); MRB_API void mrb_const_set(mrb_state*, mrb_value, mrb_sym, mrb_value); MRB_API mrb_bool mrb_const_defined(mrb_state*, mrb_value, mrb_sym); @@ -99,22 +92,6 @@ MRB_API mrb_value mrb_cv_get(mrb_state *mrb, mrb_value mod, mrb_sym sym); MRB_API void mrb_mod_cv_set(mrb_state *mrb, struct RClass * c, mrb_sym sym, mrb_value v); MRB_API void mrb_cv_set(mrb_state *mrb, mrb_value mod, mrb_sym sym, mrb_value v); MRB_API mrb_bool mrb_cv_defined(mrb_state *mrb, mrb_value mod, mrb_sym sym); -mrb_value mrb_obj_iv_inspect(mrb_state*, struct RObject*); -void mrb_obj_iv_set_force(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v); -mrb_value mrb_mod_constants(mrb_state *mrb, mrb_value mod); -mrb_value mrb_f_global_variables(mrb_state *mrb, mrb_value self); -mrb_value mrb_obj_instance_variables(mrb_state*, mrb_value); -mrb_value mrb_mod_class_variables(mrb_state*, mrb_value); -mrb_value mrb_mod_cv_get(mrb_state *mrb, struct RClass * c, mrb_sym sym); -mrb_bool mrb_mod_cv_defined(mrb_state *mrb, struct RClass * c, mrb_sym sym); -mrb_bool mrb_ident_p(const char *s, mrb_int len); - -/* GC functions */ -void mrb_gc_mark_gv(mrb_state*); -void mrb_gc_free_gv(mrb_state*); -void mrb_gc_mark_iv(mrb_state*, struct RObject*); -size_t mrb_gc_mark_iv_size(mrb_state*, struct RObject*); -void mrb_gc_free_iv(mrb_state*, struct RObject*); /* return non zero to break the loop */ typedef int (mrb_iv_foreach_func)(mrb_state*,mrb_sym,mrb_value,void*); diff --git a/lib/mruby/build.rb b/lib/mruby/build.rb index 66005a6df..4925cee33 100644 --- a/lib/mruby/build.rb +++ b/lib/mruby/build.rb @@ -123,6 +123,7 @@ module MRuby @enable_test = false @enable_lock = true @enable_presym = true + @enable_benchmark = true @mrbcfile_external = false @internal = internal @toolchains = [] @@ -232,6 +233,14 @@ module MRuby @cxx_abi_enabled = true end + def benchmark_enabled? + @enable_benchmark + end + + def disable_benchmark + @enable_benchmark = false + end + def compile_as_cxx(src, cxx_src = nil, obj = nil, includes = []) # # If `cxx_src` is specified, this method behaves the same as before as @@ -491,7 +500,8 @@ EOS v = instance_variable_get(n) v = case v when nil, true, false, Numeric; v - when String, Command; v.clone + when String; v.clone + when Command; v.clone.tap { |u| u.build = build } else Marshal.load(Marshal.dump(v)) # deep clone end build.instance_variable_set(n, v) diff --git a/lib/mruby/build/load_gems.rb b/lib/mruby/build/load_gems.rb index 6609a5c8e..9633c67bf 100644 --- a/lib/mruby/build/load_gems.rb +++ b/lib/mruby/build/load_gems.rb @@ -1,5 +1,8 @@ +require 'yaml' + module MRuby module LoadGems + def gembox(gemboxfile) gembox = File.expand_path("#{gemboxfile}.gembox", "#{MRUBY_ROOT}/mrbgems") fail "Can't find gembox '#{gembox}'" unless File.exist?(gembox) @@ -12,28 +15,30 @@ module MRuby GemBox.path = nil end - def gem(gemdir, &block) - if gemdir.is_a?(Hash) - gemdir = load_special_path_gem(gemdir) - elsif GemBox.path - gemdir = File.expand_path(gemdir, File.dirname(GemBox.path)) - else - caller_dir = File.expand_path(File.dirname(caller(1,1)[0][/^(.*?):\d/,1])) - if caller_dir == "#{MRUBY_ROOT}/build_config" - caller_dir = MRUBY_ROOT - end - gemdir = File.expand_path(gemdir, caller_dir) - end + def gem(gem_src, &block) - gemrake = File.join(gemdir, "mrbgem.rake") + caller_dir = File.expand_path(File.dirname(caller(1,1)[0][/^(.*?):\d/,1])) + gem_src = {gemdir: gem_src} if gem_src.is_a? String + + @gem_checkouts ||= {} + checkout = GemLoader + .new(self, caller_dir, @gem_checkouts, **gem_src) + .fetch! + return nil unless checkout + @gem_checkouts[checkout.gemdir] = checkout + + # Load the gem's rakefile + gemrake = File.join(checkout.gemdir, "mrbgem.rake") fail "Can't find #{gemrake}" unless File.exist?(gemrake) + Gem.current = nil load gemrake return nil unless Gem.current current = Gem.current - current.dir = gemdir + # Add it to gems + current.dir = checkout.gemdir current.build = self.is_a?(MRuby::Build) ? self : MRuby::Build.current current.build_config_initializer = block gems << current @@ -44,92 +49,329 @@ module MRuby current end - def load_special_path_gem(params) - if params[:github] - params[:git] = "https://github.com/#{params[:github]}.git" - elsif params[:bitbucket] - if params[:method] == "ssh" - params[:git] = "git@bitbucket.org:#{params[:bitbucket]}.git" - else - params[:git] = "https://bitbucket.org/#{params[:bitbucket]}.git" - end - elsif params[:mgem] - mgem_list_dir = "#{gem_clone_dir}/mgem-list" - mgem_list_url = 'https://github.com/mruby/mgem-list.git' - if File.exist? mgem_list_dir - git.run_pull mgem_list_dir, mgem_list_url if $pull_gems - else - mkdir_p mgem_list_dir - git.run_clone mgem_list_dir, mgem_list_url, "--depth 1" - end - require 'yaml' + # Class to represent the relationship between a gem dependency and + # its remote repository (if any). + class GemCheckout + attr_reader :gemdir, :repo, :branch, :commit - conf_path = "#{mgem_list_dir}/#{params[:mgem]}.gem" - conf_path = "#{mgem_list_dir}/mruby-#{params[:mgem]}.gem" unless File.exist? conf_path - fail "mgem not found: #{params[:mgem]}" unless File.exist? conf_path - conf = YAML.load File.read conf_path + def initialize(gemdir, repo, branch, commit, canonical) + @gemdir = gemdir # Working copy of the gem - fail "unknown mgem protocol: #{conf['protocol']}" if conf['protocol'] != 'git' - params[:git] = conf['repository'] - params[:branch] = conf['branch'] if conf['branch'] + @repo = repo # Remote gem repo + @branch = branch # Branch to check out + @commit = commit # Commit-id to use + + @canonical = canonical # This is the One True checkout end - if params[:core] - gemdir = "#{root}/mrbgems/#{params[:core]}" - elsif params[:git] - url = params[:git] - gemdir = "#{gem_clone_dir}/#{url.match(/([-\w]+)(\.[-\w]+|)$/).to_a[1]}" + def canonical?() return @canonical; end + def git?() return !!@repo; end + def gemname() return File.basename(@gemdir); end - # by default the 'master' branch is used - branch = params[:branch] ? params[:branch] : 'master' + def hash() + return [@gemdir, @repo, @branch, @commit, @canonical].hash + end - lock = locks[url] if lock_enabled? + def ==(other) + return @gemdir == other.gemdir && @repo == other.repo && + @branch == other.branch && @commit == other.commit && + @canonical == other.canonical? + end + alias_method :eql?, :== - if File.exist?(gemdir) - if $pull_gems - # Jump to the top of the branch - git.run_checkout gemdir, branch - git.run_pull gemdir, url - elsif params[:checksum_hash] - git.run_checkout_detach gemdir, params[:checksum_hash] - elsif lock - git.run_checkout_detach gemdir, lock['commit'] - end + def to_s + desc = @gemdir + desc += " -> #{@repo}/#{@branch}" if git? + desc += "/#{commit}" if commit + return desc + end + end + + # Class to decode the argument set given to 'MRuby::Build::gem', + # and git-clone+git-checkout the sources if needed. + class GemLoader + def initialize(build, + build_config_dir, # Parent dir. of build_config + gem_checkouts, # Hash of existing checkouts + + # Git repo: + git: nil, + branch: "master", + checksum_hash: nil, + options: [], + + # Git repo on GitHub + github: nil, + + # Git repo on BitBucket + bitbucket: nil, + method: nil, + + # mgem entry + mgem: nil, + + # Core package + core: nil, + + # Path relative to the mruby checkout; probably wrong! + path: nil, + + # Local file(s) + gemdir: nil, + + # Related flags: + canonical: false # Ignore subsequent checkout of this gem + ) + @build = build + @build_config_dir = build_config_dir + @gem_checkouts = gem_checkouts + @canonical = canonical + + @git = git + @branch = branch + @checksum_hash = checksum_hash + @options = options + @canonical = canonical + + @github = github + + @bitbucket = bitbucket + @method = method + + @mgem = mgem + @core = core + @path = path + @gemdir = gemdir + + + actions = [git, github, bitbucket, mgem, core, path, gemdir] + fail("Need to set exactly ONE of git, github, bitbucket, mgem, core, " + + "path, or gemdir") unless actions.compact.size == 1 + end + + # Retrieve the repo and return the details in a GemCheckout + # object or nil if nothing needed to be done. + def fetch! + return fromGemdir! if @gemdir + return fromCore! if @core + return fromPath! if @path + return fromGitHub! if @github + return fromBitBucket! if @bitbucket + + return fromMGem! if @mgem + + return fromGit!(@git, @branch) if @git + + # Shouldn't be reachable, but... + fail "Invalid gem configuration!" + end + + private + + # + # Local Paths + # + + def fromGemdir! + gem_src = @gemdir + + # If @gemdir is a relative path, we first convert it to an + # absolute path; this depends on circumstances. + if MRuby::GemBox.path + # If GemBox.path is set, it means that this fetch operation is + # happening as part of a gembox evaluation and we use the + # gembox's path as the starting point. + gem_src = File.expand_path(gem_src, File.dirname(MRuby::GemBox.path)) else - options = [params[:options]] || [] - options << "--recursive" - options << "--branch \"#{branch}\"" - options << "--depth 1" unless params[:checksum_hash] || lock - mkdir_p "#{gem_clone_dir}" - git.run_clone gemdir, url, options + # Otherwise, we use the path to the build_config.rb file that + # requested this gem. This path was extracted earlier and + # stored in @build_config_dir via the second argument of + # 'initialize'. + root_dir = @build_config_dir - # Jump to the specified commit - if params[:checksum_hash] - git.run_checkout_detach gemdir, params[:checksum_hash] - elsif lock - git.run_checkout_detach gemdir, lock['commit'] - end + # And we default to the repo root if the file is one of the + # stock configs in build_config/. + root_dir = MRUBY_ROOT if root_dir == "#{MRUBY_ROOT}/build_config" + + gem_src = File.expand_path(gem_src, root_dir) end - if lock_enabled? - @gem_dir_to_repo_url[gemdir] = url unless params[:path] - locks[url] = { + return GemCheckout.new(gem_src, nil, nil, nil, @canonical) + end + + def fromCore! + return GemCheckout.new("#{@build.root}/mrbgems/#{@core}", nil, nil, + nil, @canonical) + end + + # This is probably incorrect. + # + # According to doc/guides/mrbgems.md, this should specify a + # subdirectory of a git checkout (i.e. for the case where the gem + # itself is not in the repository's root.) + # + # However, the code treats this as simple path to a local + # directory (just like :gemdir) with relative paths resolved + # relative to the project root. + # + # I'm pretty sure that the correct thing is what guide says but + # I'm going to keep the initial semantics for now. + def fromPath! + p = Pathname.new(@path).absolute? ? @path : "#{@build.root}/#{@path}" + return GemCheckout.new(p, nil, nil, nil, @canonical) + end + + + # + # Git forges + # + + def fromGitHub! + url = "https://github.com/#{@github}.git" + return fromGit!(url, @branch) + end + + def fromBitBucket! + if @method == "ssh" + url = "git@bitbucket.org:#{@bitbucket}.git" + else + url = "https://bitbucket.org/#{@bitbucket}.git" + end + + return fromGit!(url, @branch) + end + + + # + # mgem file + # + + def fromMGem! + mgem = fetchMGem(@mgem) + + url = mgem['repository'] + branch = mgem['branch'] || @branch + + return fromGit!(url, branch) + end + + # Fetch the contents of the named mgem item. Will clone the + # mgem-list repo if not present + def fetchMGem(mgem) + list_dir = "#{@build.gem_clone_dir}/mgem-list" + url = 'https://github.com/mruby/mgem-list.git' + + git_clone_dependency(url, list_dir, nil, 'master') + + conf_path = "#{list_dir}/#{mgem}.gem" + conf_path = "#{list_dir}/mruby-#{mgem}.gem" unless + File.exist? conf_path + fail "mgem not found: #{mgem}" unless File.exist? conf_path + + conf = YAML.load File.read conf_path + fail "unknown mgem protocol: #{conf['protocol']}" if + conf['protocol'] != 'git' + + return conf + end + + + # + # Git checkouts + # + + def fromGit!(url, branch) + repo_dir = "#{@build.gem_clone_dir}/" + + "#{url.match(/([-\w]+)(\.[-\w]+|)$/).to_a[1]}" + commit = @checksum_hash + + return nil if skip_this?(url, repo_dir, branch, commit) + + # If there's a lockfile entry for this repo AND the user hasn't + # specified a specific commit ID, we use the locked branch and + # commit. + lock = @build.locks[url] if @build.lock_enabled? + if !commit && lock + branch = lock['branch'] + commit = lock['commit'] + end + + # Clone the dependency (if needed) and checkout the expected + # revision. + git_clone_dependency(url, repo_dir, commit, branch) + git_checkout_dependency(repo_dir, commit, branch) + + # Set the lockfile entry if enabled + if @build.lock_enabled? + @build.gem_dir_to_repo_url[repo_dir] = url + @build.locks[url] = { 'url' => url, - 'branch' => git.current_branch(gemdir), - 'commit' => git.commit_hash(gemdir), + 'branch' => @build.git.current_branch(repo_dir), + 'commit' => @build.git.commit_hash(repo_dir), } end - gemdir << "/#{params[:path]}" if params[:path] - elsif params[:path] - require 'pathname' - gemdir = Pathname.new(params[:path]).absolute? ? params[:path] : "#{root}/#{params[:path]}" - else - fail "unknown gem option #{params}" + return GemCheckout.new(repo_dir, url, branch, commit, @canonical) end - gemdir + + # Test if this repo can be skipped. This will happen if it's + # already in @gem_checkouts and EITHER it is identical (same + # url, branch and commit-ID) as the current checkout OR it's + # "canonical" flag is true. If it's in @gem_checkouts and + # neither of these conditions is true, that's a fatal error; it + # means there are multiple incompatible versions of this gem to + # be checked out into this directory. + # + # Otherwise, returns false. + def skip_this?(url, repo_dir, branch, commit) + prev = @gem_checkouts[repo_dir] + return false unless prev + + # Canonical declarations must precede all others. + fail("Attempted to re-declare #{prev.gemname} as canonical!\n" + + "('canonical' can only be used on its first declaration.)") if + prev && @canonical + + # If prev is canonical, we can ignore this + if prev.canonical? + puts "Found canonical #{prev.gemname}; skipping this one." + return true + end + + # If this checkout is identical to the current one, we can skip it. + candidate = GemCheckout.new(repo_dir, url, branch, commit, @canonical) + if prev == candidate + puts "Found duplicate checkout for #{repo_dir}; ignoring." + return true + end + + # Otherwise, we have a checkout conflict. This is an error. + fail "Conflicting gem definitions for '#{repo_dir}':\n" + + " #{candidate}\n" + + " #{prev}\n" + end + + + # Retrieve a git repo if it's not present. Return + # [path_to_checkout, did_clone] + def git_clone_dependency(url, repo_dir, commit, branch) + return if File.exist?(repo_dir) + + FileUtils.mkdir_p repo_dir + + options = @options.dup + options << "--recursive" + options << "--branch \"#{branch}\"" + options << "--depth 1" unless commit + + @build.git.run_clone repo_dir, url, options + end + + def git_checkout_dependency(repo_dir, commit, branch) + @build.git.run_checkout_detach(repo_dir, commit) + end end def enable_gems? diff --git a/mrbgems/mruby-array-ext/src/array.c b/mrbgems/mruby-array-ext/src/array.c index ae8a55d4d..97a394691 100644 --- a/mrbgems/mruby-array-ext/src/array.c +++ b/mrbgems/mruby-array-ext/src/array.c @@ -3,6 +3,7 @@ #include #include #include +#include #include /* @@ -111,6 +112,8 @@ mrb_ary_values_at(mrb_state *mrb, mrb_value self) return mrb_get_values_at(mrb, self, RARRAY_LEN(self), argc, argv, ary_ref); } +mrb_value mrb_ary_delete_at(mrb_state *mrb, mrb_value self); + /* * call-seq: * ary.slice!(index) -> obj or nil @@ -137,7 +140,6 @@ mrb_ary_slice_bang(mrb_state *mrb, mrb_value self) { struct RArray *a = mrb_ary_ptr(self); mrb_int i, j, k, len, alen; - mrb_value val; mrb_value *ptr; mrb_value ary; @@ -146,21 +148,13 @@ mrb_ary_slice_bang(mrb_state *mrb, mrb_value self) if (mrb_get_argc(mrb) == 1) { mrb_value index = mrb_get_arg1(mrb); - switch (mrb_type(index)) { - case MRB_TT_RANGE: + if (mrb_type(index) == MRB_TT_RANGE) { if (mrb_range_beg_len(mrb, index, &i, &len, ARY_LEN(a), TRUE) == MRB_RANGE_OK) { goto delete_pos_len; } - else { - return mrb_nil_value(); - } - case MRB_TT_INTEGER: - val = mrb_funcall_id(mrb, self, MRB_SYM(delete_at), 1, index); - return val; - default: - val = mrb_funcall_id(mrb, self, MRB_SYM(delete_at), 1, index); - return val; + return mrb_nil_value(); } + return mrb_ary_delete_at(mrb, self); } mrb_get_args(mrb, "ii", &i, &len); diff --git a/mrbgems/mruby-bigint/README-fgmp.md b/mrbgems/mruby-bigint/README-fgmp.md new file mode 100644 index 000000000..3e5400dd5 --- /dev/null +++ b/mrbgems/mruby-bigint/README-fgmp.md @@ -0,0 +1,154 @@ +# fgmp + +FGMP is a public domain implementation of a subset of the GNU gmp library with the same API. + +WELCOME TO FGMP. + +FGMP is a public domain implementation of a subset of the GNU gmp library +with the same API. + +For instance, you can link the following trivial program with either +this code, or libgmp.a and get the same results. + +``` C +#include +#include "gmp.h" +main() +{ + MP_INT a; MP_INT b; MP_INT c; + + mpz_init_set_ui(&a,1); mpz_init_set_ui(&b,2); mpz_init(&c); + mpz_add(&c,&a,&b); + printf("\n%s\n", mpz_get_str(NULL,10,&c)); +} +``` + +FGMP is really in the public domain. You can do whatever you want with +it. + +I wrote FGMP so that we would all have access to a (truly free) +implementation of this subset of the API of GNU libgmp. I encourage +everyone to distribute this as widely as possible. + +If you need more documentation, I suggest you look at the file +gmp.texi which is included with the GNU gmp library. + +You can send me bug reports, implementations of missing functions, flames +and rants by Email. + +Any submissions of new code to be integrated into fgmp must also be +placed in the public domain (For the particularly dense, you can +release a new fgmp yourself under different licensing terms. This +is a condition for including a submission in a release of FGMP that +I personally prepare). + +Mark Henderson + +# This is the fifth BETA release. 1.0b5 + +I hearby place this file and all of FGMP in the public domain. + +Thanks to Paul Rouse for changes to get fgmp +to work on a 286 MS-DOS compiler, the functions mpz_sqrt and +mpz_sqrtrem, plus other general bug fixes. + +Thanks also to Erick Gallesio for a fix +to mpz_init_set_str + +Define B64 if your "long" type is 64 bits. Otherwise we assume 32 +bit longs. (The 64 bit version hasn't been tested enough) + +``` +Platforms: +Linux 0.99 (gcc) +IBM RS6000/AIX 3.2 (IBM xlc compiler and gcc 2.3) +Sun OS 4.1, Sun 3/4 +DEC Alpha OSF/1 (only lightly tested, 64 bit longs do make a difference, + thanks to DEC for providing access via axposf.pa.dec.com). Define B64 + for this platform +MS-DOS 286 C compiler (see credits above) +``` + +# Some differences between gmp and fgmp + +1. fgmp is considerably slower than gmp +2. fgmp does not implement the following: + all mpq_* + internal mpn_* functions + mpz_perfect_square_p + mpz_inp_raw, mpz_out_raw + mp_set_memory_functions, mpz_out_str, mpz_inp_str +3. fgmp implements the following in addition to the routines in GNU gmp. + `int mpz_jacobi(MP_INT *a, MP_INT *b)` + - finds the jacobi symbol (a/b) +4. mpz_sizeinbase often overestimates the exact value + +5. To convert your gmp based program to fgmp (subject to the +above) + +- recompile your source. Make sure to include the gmp.h file included + with fgmp rather than that included with gmp. (The point is to recompile + all files which include gmp.h) +- link with gmp.o instead of libgmp.a + +Here's a complete sorted list of function implemented in fgmp: + +``` +_mpz_realloc +mpz_abs +mpz_add +mpz_add_ui +mpz_and +mpz_clear +mpz_cmp +mpz_cmp_si +mpz_cmp_ui +mpz_div +mpz_div_2exp +mpz_div_ui +mpz_divmod +mpz_divmod_ui +mpz_fac_ui +mpz_gcd +mpz_gcdext +mpz_get_si +mpz_get_str +mpz_get_ui +mpz_init +mpz_init_set +mpz_init_set_si +mpz_init_set_str +mpz_init_set_ui +mpz_jacobi +mpz_mdiv +mpz_mdiv_ui +mpz_mdivmod +mpz_mdivmod_ui +mpz_mmod +mpz_mmod_ui +mpz_mod +mpz_mod_2exp +mpz_mod_ui +mpz_mul +mpz_mul_2exp +mpz_mul_ui +mpz_neg +mpz_or +mpz_pow_ui +mpz_powm +mpz_powm_ui +mpz_probab_prime_p +mpz_random +mpz_random2 +mpz_set +mpz_set_si +mpz_set_str +mpz_set_ui +mpz_size +mpz_sizeinbase +mpz_sqrt +mpz_sqrtrem +mpz_sub +mpz_sub_ui +mpz_xor +``` diff --git a/mrbgems/mruby-bigint/README.md b/mrbgems/mruby-bigint/README.md new file mode 100644 index 000000000..81b368601 --- /dev/null +++ b/mrbgems/mruby-bigint/README.md @@ -0,0 +1,5 @@ +# Multi-precision Integer extension for mruby + +This extension uses fgmp, which is a public domain implementation of a subset of the GNU gmp library by Mark Henderson +But it's heavily modified to fit with mruby. You can get the original source code from +You can read the original README for fgmp in diff --git a/mrbgems/mruby-bigint/core/bigint.c b/mrbgems/mruby-bigint/core/bigint.c new file mode 100644 index 000000000..d51efdf6f --- /dev/null +++ b/mrbgems/mruby-bigint/core/bigint.c @@ -0,0 +1,1459 @@ +/** +** @file mruby/bigint.h - Multi-precision, Integer +** +** See Copyright Notice in mruby.h +*/ + +#include +#include +#include +#include +#include +#include +#include +#include "bigint.h" + +static void +mpz_init(mrb_state *mrb, mpz_t *s) +{ + s->p = (mp_limb*)mrb_malloc(mrb, sizeof(mp_limb)*2); + (s->p)[0] = 0; + (s->p)[1] = 0; + s->sn=0; + s->sz=2; +} + +#if 0 +static void +mpz_init_set(mrb_state *mrb, mpz_t *s, mpz_t *t) +{ + s->p = (mp_limb*)mrb_malloc(mrb, sizeof(mp_limb) * t->sz); + for (size_t i=0;i < t->sz ; i++) + (s->p)[i] = (t->p)[i]; + + s->sn = t->sn; + s->sz = t->sz; +} +#endif + +static void +mpz_set_int(mrb_state *mrb, mpz_t *y, mrb_int v) +{ + for (size_t i=1; isz; i++) + y->p[i] = 0; + if (v < 0) { + y->sn = -1; + y->p[0] = (-v) & LMAX; + y->p[1] = ((-v) & LC) >> DIGITBITS; + } + else if (v > 0) { + y->sn = 1; + y->p[0] = v & LMAX; + y->p[1] = (v & LC) >> DIGITBITS; + } + else { + y->sn=0; + y->p[0] = 0; + y->p[1] = 0; + } +} + +static void +mpz_init_set_int(mrb_state *mrb, mpz_t *y, mrb_int v) +{ + mp_limb u; + + y->p = (mp_limb*)mrb_malloc(mrb, sizeof(mp_limb)*2); + if (v < 0) { + y->sn = -1; + u = -v; + } + else if (v > 0) { + y->sn = 1; + u = v; + } + else { + y->sn=0; + u = 0; + } + y->p[0] = u & LMAX; + y->p[1] = (u & LC) >> DIGITBITS; + y -> sz = 2; +} + +static void +mpz_clear(mrb_state *mrb, mpz_t *s) +{ + if (s->p) + mrb_free(mrb, s->p); + s->p=NULL; + s->sn=0; + s->sz=0; +} + +static void +mpz_realloc(mrb_state *mrb, mpz_t *x, size_t size) +{ + if (size > 1 && x->sz < size) { + x->p=(mp_limb*)mrb_realloc(mrb,x->p,size * sizeof(mp_limb)); + for (size_t i=x->sz; ip)[i] = 0; + x->sz = size; + } +} + +static size_t +digits(mpz_t *x) +{ + size_t i; + for (i = (x->sz) - 1; (x->p)[i] == 0 ; i--) + if (i == 0) break; + return i+1; +} + +/* y = x */ +static void +mpz_set(mrb_state *mrb, mpz_t *y, mpz_t *x) +{ + size_t i,k = x->sz; + if (y->sz < k) { + k=digits(x); + mpz_realloc(mrb, y, (size_t)k); + } + if (y->sz > x->sz) { + mpz_clear(mrb, y); + mpz_init(mrb, y); + mpz_realloc(mrb, y, (size_t)(x->sz)); + } + + for (i=0;i < k; i++) + (y->p)[i] = (x->p)[i]; + + for (;isz;i++) + (y->p)[i] = 0; + + y->sn = x->sn; +} + +/* z = x + y, without regard for sign */ +static void +uadd(mrb_state *mrb, mpz_t *z, mpz_t *x, mpz_t *y) +{ + mp_limb c; + size_t i; + mpz_t *t; + + if (y->sz < x->sz) { + t=x; x=y; y=t; + } + + /* now y->sz >= x->sz */ + + mpz_realloc(mrb, z, (size_t)((y->sz)+1)); + + c=0; + for (i=0; isz; i++) { + if ((z->p[i] = y->p[i] + x->p[i] + c) & CMASK) { + c=1; + (z->p[i]) &=LMAX; + } + else + c=0; + } + for (;isz; i++) { + if ((z->p[i] = (y->p[i] + c)) & CMASK) + z->p[i]=0; + else + c=0; + } + (z->p)[y->sz]=c; +} + +/* z = y - x, ignoring sign */ +/* precondition: abs(y) >= abs(x) */ +static void +usub(mrb_state *mrb, mpz_t *z, mpz_t *y, mpz_t *x) +{ + mp_limb b,m; + mpz_realloc(mrb, z, (size_t)(y->sz)); + b=0; + for (size_t i=0;isz;i++) { + m=((y->p)[i]-b)-dg(x,i); + if (m < 0) { + b = 1; + m = LMAX + 1 + m; + } + else + b = 0; + z->p[i] = m; + } +} + +/* compare abs(x) and abs(y) */ +static int +ucmp(mpz_t *y, mpz_t *x) +{ + size_t i; + for (i=imax(x->sz,y->sz)-1;;i--) { + if (dg(y,i) < dg(x,i)) + return (-1); + else if (dg(y,i) > dg(x,i)) + return 1; + if (i == 0) break; + } + return 0; +} + +static int +uzero(mpz_t *x) +{ + for (size_t i=0; i < x->sz; i++) + if ((x->p)[i] != 0) + return 0; + return 1; +} + +static void +zero(mpz_t *x) +{ + x->sn=0; + for (size_t i=0;isz;i++) + (x->p)[i] = 0; +} + +/* z = x + y */ +static void +mpz_add(mrb_state *mrb, mpz_t *zz, mpz_t *x, mpz_t *y) +{ + int mg; + mpz_t z; + if (x->sn == 0) { + mpz_set(mrb, zz, y); + return; + } + if (y->sn == 0) { + mpz_set(mrb, zz, x); + return; + } + mpz_init(mrb, &z); + + if (x->sn > 0 && y->sn > 0) { + uadd(mrb, &z, x, y); + z.sn = 1; + } + else if (x->sn < 0 && y->sn < 0) { + uadd(mrb, &z, x, y); + z.sn = -1; + } + else { + /* signs differ */ + if ((mg = ucmp(x,y)) == 0) { + zero(&z); + } + else if (mg > 0) { /* abs(y) < abs(x) */ + usub(mrb, &z, x, y); + z.sn = (x->sn > 0 && y->sn < 0) ? 1 : (-1); + } + else { /* abs(y) > abs(x) */ + usub(mrb, &z, y, x); + z.sn = (x->sn < 0 && y->sn > 0) ? 1 : (-1); + } + } + mpz_set(mrb,zz,&z); + mpz_clear(mrb,&z); +} + +/* z = x - y -- just use mpz_add - I'm lazy */ +static void +mpz_sub(mrb_state *mrb, mpz_t *z, mpz_t *x, mpz_t *y) +{ + mpz_t u; + mpz_init(mrb, &u); + mpz_set(mrb, &u, y); + u.sn = -(u.sn); + mpz_add(mrb, z, x, &u); + mpz_clear(mrb, &u); +} + +/* x = y - n */ +static void +mpz_sub_int(mrb_state *mrb, mpz_t *x, mpz_t *y, mrb_int n) +{ + mpz_t z; + mpz_init_set_int(mrb, &z, n); + mpz_sub(mrb, x, y, &z); + mpz_clear(mrb, &z); +} + +/* w = u * v */ +static void +mpz_mul(mrb_state *mrb, mpz_t *ww, mpz_t *u, mpz_t *v) +{ + size_t i,j; + mp_limb t0,t1,t2,t3; + mp_limb cc; + mpz_t w; + + mpz_init(mrb, &w); + mpz_realloc(mrb, &w, (size_t)(u->sz + v->sz)); + for (j=0; j < 2*u->sz; j++) { + cc = (mp_limb)0; + t3 = hd(u,j); + for (i=0; i < 2*v->sz; i++) { + t0 = t3 * hd(v,i); + t1 = HIGH(t0); t0 = LOW(t0); + if ((i+j)%2) + t2 = HIGH(w.p[(i+j)/2]); + else + t2 = LOW(w.p[(i+j)/2]); + t2 += cc; + if (t2 & HCMASK) { + cc = 1; t2&=HLMAX; + } + else + cc = 0; + t2 += t0; + if (t2 & HCMASK) { + cc++ ; t2&=HLMAX; + } + cc+=t1; + if ((i+j)%2) + w.p[(i+j)/2] = LOW(w.p[(i+j)/2]) | + (t2 << HALFDIGITBITS); + else + w.p[(i+j)/2] = (HIGH(w.p[(i+j)/2]) << HALFDIGITBITS) | t2; + } + if (cc) { + if ((j+i)%2) + w.p[(i+j)/2] += cc << HALFDIGITBITS; + else + w.p[(i+j)/2] += cc; + } + } + w.sn = (u->sn) * (v->sn); + mpz_set(mrb, ww, &w); + mpz_clear(mrb, &w); +} + +static void +mpz_mul_int(mrb_state *mrb, mpz_t *x, mpz_t *y, mrb_int n) +{ + mpz_t z; + mpz_init_set_int(mrb,&z,n); + mpz_mul(mrb,x,y,&z); + mpz_clear(mrb,&z); +} + +/* number of leading zero bits in digit */ +static int +lzb(mp_limb a) +{ + mp_limb i; int j=0; + + for (i = ((mp_limb)1 << (DIGITBITS-1)); i && !(a&i) ; j++,i>>=1) + ; + return j; +} + +/* c1 = a>>n */ +/* n must be < DIGITBITS */ +static void +urshift(mrb_state *mrb, mpz_t *c1, mpz_t *a, size_t n) +{ + mp_limb cc = 0; + mrb_assert(n < DIGITBITS); + if (n == 0) + mpz_set(mrb, c1, a); + else { + mpz_t c; size_t i; + mp_limb rm = (((mp_limb)1<sz)); + for (i=a->sz-1;; i--) { + c.p[i] = ((a->p[i] >> n) | cc) & LMAX; + cc = (a->p[i] & rm) << (DIGITBITS - n); + if (i == 0) break; + } + mpz_set(mrb,c1,&c); + mpz_clear(mrb,&c); + } +} + +/* c1 = a<sz + 1)); + for (i=0; isz; i++) { + c.p[i] = (((mp_ulimb)a->p[i] << n) | cc) & LMAX; + cc = (a->p[i] & rm) >> (DIGITBITS -n); + } + c.p[i] = cc; + mpz_set(mrb,c1,&c); + mpz_clear(mrb,&c); + } +} + +/* internal routine to compute x/y and x%y ignoring signs */ +static void +udiv(mrb_state *mrb, mpz_t *qq, mpz_t *rr, mpz_t *xx, mpz_t *yy) +{ + mpz_t q, x, y, r; + int ns,f,ccc=0; + size_t xd,yd,i,j; + mp_limb zz,z,qhat,b,u,m; + + if (uzero(yy)) + return; + mpz_init(mrb,&q); mpz_init(mrb,&x);mpz_init(mrb,&y);mpz_init(mrb,&r); + mpz_realloc(mrb,&x,(size_t)((xx->sz)+1)); + yd = digits(yy); + ns = lzb(yy->p[yd-1]); + ulshift(mrb,&x,xx,ns); + ulshift(mrb,&y,yy,ns); + xd = digits(&x); + mpz_realloc(mrb,&q,(size_t)xd); + xd*=2; yd*=2; + z = hd(&y,yd-1); + for (j=(xd-yd);;j--) { + if (z == LMAX) + qhat = hd(&x,j+yd); + else { + qhat = ((hd(&x,j+yd)<< HALFDIGITBITS) + hd(&x,j+yd-1)) / (z+1); + } + b = 0; zz=0; + if (qhat) { + for (i=0; i hd(&y,i)) { + f=1; + break; + } + if (hd(&x,j+i) < hd(&y,i)) { + f=0; + break; + } + if (i == 0) break; + } + } + if (!f) + break; + qhat++; + ccc++; + b=0; + for (i=0;isz)); + zero(&r); + urshift(mrb,&r,&x,ns); + mpz_set(mrb,rr,&r); + mpz_set(mrb,qq,&q); + mpz_clear(mrb,&x); mpz_clear(mrb,&y); + mpz_clear(mrb,&q); mpz_clear(mrb,&r); +} + +static void +mpz_mdiv(mrb_state *mrb, mpz_t *q, mpz_t *x, mpz_t *y) +{ + mpz_t r; + short sn1 = x->sn, sn2 = y->sn, qsign; + mpz_init(mrb,&r); + udiv(mrb,q,&r,x,y); + qsign = q->sn = sn1*sn2; + if (uzero(q)) + q->sn = 0; + /* now if r != 0 and q < 0 we need to round q towards -inf */ + if (!uzero(&r) && qsign < 0) + mpz_sub_int(mrb,q,q,1); + mpz_clear(mrb,&r); +} + +static void +mpz_mmod(mrb_state *mrb, mpz_t *r, mpz_t *x, mpz_t *y) +{ + mpz_t q; + short sn1 = x->sn, sn2 = y->sn; + mpz_init(mrb, &q); + if (sn1 == 0) { + zero(r); + return; + } + udiv(mrb,&q,r,x,y); + if (uzero(r)) { + r->sn = 0; + return; + } + q.sn = sn1*sn2; + if (q.sn > 0) + r->sn = sn1; + else if (sn1 < 0 && sn2 > 0) { + r->sn = 1; + mpz_sub(mrb,r,y,r); + } + else { + r->sn = 1; + mpz_add(mrb,r,y,r); + } +} + +static void +mpz_mdivmod(mrb_state *mrb, mpz_t *q, mpz_t *r, mpz_t *x, mpz_t *y) +{ + short sn1 = x->sn, sn2 = y->sn, qsign; + if (sn1 == 0) { + zero(q); + zero(r); + return; + } + udiv(mrb,q,r,x,y); + qsign = q->sn = sn1*sn2; + if (uzero(r)) { + /* q != 0, since q=r=0 would mean x=0, which was tested above */ + r->sn = 0; + return; + } + if (q->sn > 0) + r->sn = sn1; + else if (sn1 < 0 && sn2 > 0) { + r->sn = 1; + mpz_sub(mrb,r,y,r); + } + else { + r->sn = 1; + mpz_add(mrb,r,y,r); + } + if (uzero(q)) + q->sn = 0; + /* now if r != 0 and q < 0 we need to round q towards -inf */ + if (!uzero(r) && qsign < 0) + mpz_sub_int(mrb,q,q,1); +} + +static void +mpz_mod(mrb_state *mrb, mpz_t *r, mpz_t *x, mpz_t *y) +{ + mpz_t q; + short sn = x->sn; + mpz_init(mrb, &q); + if (x->sn == 0) { + zero(r); + return; + } + udiv(mrb,&q,r,x,y); + r->sn = sn; + if (uzero(r)) + r->sn = 0; + mpz_clear(mrb,&q); +} + +static mrb_int +mpz_cmp(mrb_state *mrb, mpz_t *x, mpz_t *y) +{ + int abscmp; + if (x->sn < 0 && y->sn > 0) + return (-1); + if (x->sn > 0 && y->sn < 0) + return 1; + abscmp=ucmp(x,y); + if (x->sn >=0 && y->sn >=0) + return abscmp; + return (-abscmp); // if (x->sn <=0 && y->sn <=0) +} + +/* 2<=base <=36 - this overestimates the optimal value, which is OK */ +static int +mpz_sizeinbase(mpz_t *x, int base) +{ + int i,j; + size_t bits = digits(x) * DIGITBITS; + mrb_assert(2 <= base && base <= 36); + for (j=0,i=1; i<=base; i*=2,j++) + ; + return (int)((bits)/(j-1)+1); +} + +static int +mpz_init_set_str(mrb_state *mrb, mpz_t *x, const char *s, mrb_int len, mrb_int base) +{ + size_t i; + int retval = 0; + mpz_t t,m,bb; + short sn; + unsigned int k; + mpz_init(mrb,x); + mpz_init_set_int(mrb,&m,1); + mpz_init(mrb,&t); + zero(x); + if (*s == '-') { + sn = -1; s++; + } + else if (base < 0) { /* trick: negative if base < 0 */ + sn = -1; base = -base; + } + else + sn = 1; + mpz_init_set_int(mrb,&bb, base); + for (i = len-1;; i--) { + if (s[i]=='_') continue; + if (s[i] >= '0' && s[i] <= '9') + k = (unsigned int)s[i] - (unsigned int)'0'; + else if (s[i] >= 'A' && s[i] <= 'Z') + k = (unsigned int)s[i] - (unsigned int)'A'+10; + else if (s[i] >= 'a' && s[i] <= 'z') + k = (unsigned int)s[i] - (unsigned int)'a'+10; + else { + retval = (-1); + break; + } + if (k >= base) { + retval = (-1); + break; + } + mpz_mul_int(mrb,&t,&m,(mrb_int)k); + mpz_add(mrb,x,x,&t); + mpz_mul(mrb,&m,&m,&bb); + if (i == 0) break; + } + if (x->sn) + x->sn = sn; + mpz_clear(mrb,&m); + mpz_clear(mrb,&bb); + mpz_clear(mrb,&t); + return retval; +} + +static char* +mpz_get_str(mrb_state *mrb, char *s, mrb_int sz, mrb_int base, mpz_t *x) +{ + mpz_t xx,q,r,bb; + char *p,*t,*ps; + mp_limb d; + mrb_assert(2 <= base && base <= 36); + if (uzero(x)) { + *s='0'; + *(s+1)='\0'; + return s; + } + t = (char*)mrb_malloc(mrb, sz+2); + mpz_init(mrb,&xx); mpz_init(mrb,&q); mpz_init(mrb,&r); + mpz_init_set_int(mrb,&bb,base); + mpz_set(mrb,&xx,x); + ps = s; + if (x->sn < 0) { + *ps++= '-'; + xx.sn = 1; + } + p = t; + while (!uzero(&xx)) { + udiv(mrb,&xx,&r,&xx,&bb); + d = r.p[0]; + if (d < 10) + *p++ = (char)(r.p[0] + '0'); + else + *p++ = (char)(r.p[0] + -10 + 'a'); + } + + p--; + for (;p>=t;p--,ps++) + *ps = *p; + *ps='\0'; + + mrb_free(mrb,t); + mpz_clear(mrb,&xx); mpz_clear(mrb,&q); mpz_clear(mrb,&r); mpz_clear(mrb,&bb); + return s; +} + +static int +mpz_get_int(mpz_t *y, mrb_int *v) +{ + mp_limb i; + + if (y->sn == 0) { + i = 0; + } + else if (digits(y) > 2 || y->p[1] > 1) { + return FALSE; + } + else { + i = (y->sn * (y->p[0] | (y->p[1] & 1) << DIGITBITS)); + if (MRB_INT_MAX < i || i < MRB_INT_MIN) return FALSE; + } + *v = i; + return TRUE; +} + +static void +mpz_mul_2exp(mrb_state *mrb, mpz_t *z, mpz_t *x, mrb_int e) +{ + short sn = x->sn; + if (e==0) + mpz_set(mrb,z,x); + else { + size_t i; + mp_limb digs = (e / DIGITBITS); + size_t bs = (e % (DIGITBITS)); + mpz_t y; + + mpz_init(mrb, &y); + mpz_realloc(mrb, &y,(size_t)((x->sz)+digs)); + for (i=digs;i<((x->sz) + digs);i++) + (y.p)[i] = (x->p)[i - digs]; + if (bs) { + ulshift(mrb,z,&y,bs); + } + else { + mpz_set(mrb,z,&y); + } + z->sn = sn; + mpz_clear(mrb,&y); + } +} + +static void +mpz_div_2exp(mrb_state *mrb, mpz_t *z, mpz_t *x, mrb_int e) +{ + short sn = x->sn; + if (e==0) + mpz_set(mrb,z,x); + else { + size_t i; + mp_limb digs = (e / DIGITBITS); + size_t bs = (e % (DIGITBITS)); + mpz_t y; + + mpz_init(mrb,&y); + mpz_realloc(mrb,&y,(size_t)((x->sz) - digs)); + for (i=0; i < (x->sz - digs); i++) + (y.p)[i] = (x->p)[i+digs]; + if (bs) { + urshift(mrb,z,&y,bs); + } + else { + mpz_set(mrb,z,&y); + } + if (uzero(z)) + z->sn = 0; + else + z->sn = sn; + mpz_clear(mrb,&y); + } +} + +static void +mpz_neg(mrb_state *mrb, mpz_t *x, mpz_t *y) +{ + if (x!=y) + mpz_set(mrb,x,y); + x->sn = -(y->sn); +} + +static void +mpz_and(mrb_state *mrb, mpz_t *z, mpz_t *x, mpz_t *y) /* not the most efficient way to do this */ +{ + size_t i,sz; + sz = imax(x->sz, y->sz); + mpz_realloc(mrb,z,(size_t)sz); + for (i=0; i < sz; i++) + (z->p)[i] = dg(x,i) & dg(y,i); + if (x->sn < 0 && y->sn < 0) + z->sn = (-1); + else + z->sn = 1; + if (uzero(z)) + z->sn = 0; +} + +static void +mpz_or(mrb_state *mrb, mpz_t *z, mpz_t *x, mpz_t *y) /* not the most efficient way to do this */ +{ + size_t i,sz; + sz = imax(x->sz, y->sz); + mpz_realloc(mrb,z,(size_t)sz); + for (i=0; i < sz; i++) + (z->p)[i] = dg(x,i) | dg(y,i); + if (x->sn < 0 || y->sn < 0) + z->sn = (-1); + else + z->sn = 1; + if (uzero(z)) + z->sn = 0; +} + +static void +mpz_xor(mrb_state *mrb, mpz_t *z, mpz_t *x, mpz_t *y) /* not the most efficient way to do this */ +{ + size_t i,sz; + sz = imax(x->sz, y->sz); + mpz_realloc(mrb,z,(size_t)sz); + for (i=0; i < sz; i++) + (z->p)[i] = dg(x,i) ^ dg(y,i); + if ((x->sn <= 0 && y->sn > 0) || (x->sn > 0 && y->sn <=0)) + z->sn = (-1); + else + z->sn = 1; + if (uzero(z)) + z->sn = 0; +} + +static void +mpz_pow(mrb_state *mrb, mpz_t *zz, mpz_t *x, mrb_int e) +{ + mpz_t t; + mp_ulimb mask = (((mp_ulimb)1)<< (LONGBITS-1)); + + if (e==0) { + mpz_set_int(mrb, zz, 1L); + return; + } + + mpz_init(mrb,&t); + mpz_set(mrb,&t,x); + for (;!(mask &e); mask>>=1) + ; + mask>>=1; + for (;mask!=0; mask>>=1) { + mpz_mul(mrb,&t,&t,&t); + if (e & mask) + mpz_mul(mrb,&t,&t,x); + } + mpz_set(mrb,zz,&t); + mpz_clear(mrb,&t); +} + +#define lowdigit(x) (((x)->p)[0]) + +struct is { + mp_limb v; + struct is *next; +}; + +static void +push(mrb_state *mrb, mp_limb i, struct is **sp) +{ + struct is *tmp; + tmp = *sp; + *sp = (struct is*)mrb_malloc(mrb, sizeof(struct is)); + (*sp)->v = i; + (*sp)->next=tmp; +} + +static mp_limb +pop(mrb_state *mrb, struct is **sp) +{ + struct is *tmp; + mp_limb i; + if (!(*sp)) + return (-1); + tmp = *sp; + *sp = (*sp)->next; + i = tmp->v; + tmp->v = 0; + mrb_free(mrb,tmp); + return i; +} + +static void +mpz_powm(mrb_state *mrb, mpz_t *zz, mpz_t *x, mrb_int ex, mpz_t *n) +{ + mpz_t t, e; + struct is *stack = NULL; + size_t k,i; + + if (ex == 0) { + mpz_set_int(mrb,zz,1); + return; + } + + if (ex < 0) { + return; + } + mpz_init_set_int(mrb,&e, ex); + mpz_init(mrb,&t); + + for (k=0;!uzero(&e);k++,mpz_div_2exp(mrb,&e,&e,1)) + push(mrb,lowdigit(&e) & 1,&stack); + k--; + i=pop(mrb,&stack); + + mpz_mod(mrb,&t,x,n); /* t=x%n */ + + for (i=k-1;;i--) { + mpz_mul(mrb,&t,&t,&t); + mpz_mod(mrb,&t,&t,n); + if (pop(mrb,&stack)) { + mpz_mul(mrb,&t,&t,x); + mpz_mod(mrb,&t,&t,n); + } + if (i == 0) break; + } + mpz_set(mrb,zz,&t); + mpz_clear(mrb,&t); + mpz_clear(mrb,&e); +} + +/* --- mruby functions --- */ +static struct RBigint* +bint_new(mrb_state *mrb) +{ + struct RBigint *b = MRB_OBJ_ALLOC(mrb, MRB_TT_BIGINT, mrb->integer_class); + mpz_init(mrb, &b->mp); + return b; +} + +static struct RBigint* +bint_new_int(mrb_state *mrb, mrb_int x) +{ + struct RBigint *b = MRB_OBJ_ALLOC(mrb, MRB_TT_BIGINT, mrb->integer_class); + mpz_init_set_int(mrb, &b->mp, x); + return b; +} + +mrb_value +mrb_bint_new(mrb_state *mrb) +{ + struct RBigint *b = bint_new(mrb); + return mrb_obj_value(b); +} + +mrb_value +mrb_bint_new_int(mrb_state *mrb, mrb_int x) +{ + struct RBigint *b = bint_new_int(mrb, x); + return mrb_obj_value(b); +} + +mrb_value +mrb_bint_new_str(mrb_state *mrb, const char *x, mrb_int len, mrb_int base) +{ + struct RBigint *b = MRB_OBJ_ALLOC(mrb, MRB_TT_BIGINT, mrb->integer_class); + mrb_assert(2 <= iabs(base) && iabs(base) <= 36); + mpz_init_set_str(mrb, &b->mp, x, len, base); + return mrb_obj_value(b); +} + +static mrb_value +bint_norm(mrb_state *mrb, struct RBigint *b) +{ + mrb_int i; + + if (mpz_get_int(&b->mp, &i)) { + return mrb_int_value(mrb, i); + } + return mrb_obj_value(b); +} + +void +mrb_gc_free_bint(mrb_state *mrb, struct RBasic *x) +{ + struct RBigint *b = (struct RBigint*)x; + mpz_clear(mrb, &b->mp); +} + +#ifndef MRB_NO_FLOAT +mrb_value +mrb_bint_new_float(mrb_state *mrb, mrb_float x) +{ + /* x should not be NaN nor Infinity */ + mrb_assert(x == x && x != x * 0.5); + + if (x < 1.0) { + return mrb_fixnum_value(0); + } + + struct RBigint *bint = bint_new(mrb); + mpz_t *r = &bint->mp; + + if (x < 0.0) { + x = -x; + r->sn = -1; + } + else { + r->sn = 1; + } + + mrb_float b = (double)CMASK; + mrb_float bi = 1.0 / b; + size_t rn, i; + mp_limb *rp; + mp_limb f; + + for (rn = 1; x >= b; rn++) + x *= bi; + + mpz_realloc(mrb, r, rn); + rp = r->p; + for (i=rn-1;;i--) { + f = (mp_limb)x; + x -= f; + mrb_assert(x < 1.0); + rp[i] = f; + if (i == 0) break; + } + return bint_norm(mrb, bint); +} + +mrb_float +mrb_bint_as_float(mrb_state *mrb, mrb_value self) +{ + struct RBigint *b = RBIGINT(self); + mpz_t *i = &b->mp; + mp_limb *d = i->p + i->sz; + mrb_float val = 0; + + while (d-- > i->p) { + val = val * (LMAX+1) + *d; + } + + if (i->sn < 0) { + val = -val; + } + return val; +} +#endif + +mrb_value +mrb_as_bint(mrb_state *mrb, mrb_value x) +{ + if (mrb_bigint_p(x)) return x; + return mrb_bint_new_int(mrb, mrb_as_int(mrb, x)); +} + +mrb_int +mrb_bint_as_int(mrb_state *mrb, mrb_value x) +{ + struct RBigint *b = RBIGINT(x); + mrb_int i; + + if (!mpz_get_int(&b->mp, &i)) { + mrb_raise(mrb, E_RANGE_ERROR, "integer too big"); + } + return i; +} + +mrb_value +mrb_bint_add(mrb_state *mrb, mrb_value x, mrb_value y) +{ +#ifndef MRB_NO_FLOAT + if (mrb_float_p(y)) { + mrb_float v1 = mrb_bint_as_float(mrb, x); + mrb_float v2 = mrb_float(y); + return mrb_float_value(mrb,v1+v2); + } +#endif + y = mrb_as_bint(mrb, y); + struct RBigint *b = RBIGINT(x); + struct RBigint *b2 = RBIGINT(y); + struct RBigint *b3 = bint_new(mrb); + mpz_add(mrb, &b3->mp, &b->mp, &b2->mp); + return bint_norm(mrb, b3); +} + +mrb_value +mrb_bint_sub(mrb_state *mrb, mrb_value x, mrb_value y) +{ +#ifndef MRB_NO_FLOAT + if (mrb_float_p(y)) { + mrb_float v1 = mrb_bint_as_float(mrb, x); + mrb_float v2 = mrb_float(y); + return mrb_float_value(mrb,v1-v2); + } +#endif + y = mrb_as_bint(mrb, y); + struct RBigint *b = RBIGINT(x); + struct RBigint *b2 = RBIGINT(y); + struct RBigint *b3 = bint_new(mrb); + mpz_sub(mrb, &b3->mp, &b->mp, &b2->mp); + return bint_norm(mrb, b3); +} + +mrb_value +mrb_bint_mul(mrb_state *mrb, mrb_value x, mrb_value y) +{ +#ifndef MRB_NO_FLOAT + if (mrb_float_p(y)) { + mrb_float v1 = mrb_bint_as_float(mrb, x); + mrb_float v2 = mrb_float(y); + return mrb_float_value(mrb,v1*v2); + } +#endif + y = mrb_as_bint(mrb, y); + struct RBigint *b = RBIGINT(x); + struct RBigint *b2 = RBIGINT(y); + struct RBigint *b3 = bint_new(mrb); + mpz_mul(mrb, &b3->mp, &b->mp, &b2->mp); + return bint_norm(mrb, b3); +} + +mrb_value +mrb_bint_div(mrb_state *mrb, mrb_value x, mrb_value y) +{ +#ifndef MRB_NO_FLOAT + if (mrb_float_p(y)) { + mrb_float v1 = mrb_bint_as_float(mrb, x); + mrb_float v2 = mrb_float(y); + return mrb_float_value(mrb,v1*v2); + } +#endif + y = mrb_as_bint(mrb, y); + struct RBigint *b = RBIGINT(x); + struct RBigint *b2 = RBIGINT(y); + struct RBigint *b3 = bint_new(mrb); + mpz_mdiv(mrb, &b3->mp, &b->mp, &b2->mp); + return bint_norm(mrb, b3); +} + +mrb_value +mrb_bint_add_ii(mrb_state *mrb, mrb_int x, mrb_int y) +{ + struct RBigint *b = bint_new(mrb); + mpz_t z1, z2; + + mpz_init_set_int(mrb,&z1,x); + mpz_init_set_int(mrb,&z2,y); + mpz_add(mrb,&b->mp,&z1,&z2); + mpz_clear(mrb,&z1); + mpz_clear(mrb,&z2); + return bint_norm(mrb, b); +} + +mrb_value +mrb_bint_sub_ii(mrb_state *mrb, mrb_int x, mrb_int y) +{ + struct RBigint *b = bint_new(mrb); + mpz_t z1, z2; + + mpz_init_set_int(mrb,&z1,x); + mpz_init_set_int(mrb,&z2,y); + mpz_sub(mrb,&b->mp,&z1,&z2); + mpz_clear(mrb,&z1); + mpz_clear(mrb,&z2); + return bint_norm(mrb, b); +} + +mrb_value +mrb_bint_mul_ii(mrb_state *mrb, mrb_int x, mrb_int y) +{ + struct RBigint *b = bint_new(mrb); + mpz_t z1, z2; + + mpz_init_set_int(mrb,&z1,x); + mpz_init_set_int(mrb,&z2,y); + mpz_mul(mrb,&b->mp,&z1,&z2); + mpz_clear(mrb,&z1); + mpz_clear(mrb,&z2); + return bint_norm(mrb, b); +} + +mrb_value +mrb_bint_div_ii(mrb_state *mrb, mrb_int x, mrb_int y) +{ + struct RBigint *b = bint_new(mrb); + mpz_t z1, z2; + + mpz_init_set_int(mrb,&z1,x); + mpz_init_set_int(mrb,&z2,y); + mpz_mdiv(mrb,&b->mp,&z1,&z2); + mpz_clear(mrb,&z1); + mpz_clear(mrb,&z2); + return bint_norm(mrb, b); +} + +mrb_value +mrb_bint_idiv(mrb_state *mrb, mrb_value x, mrb_value y) +{ + return mrb_nil_value(); +} + +mrb_value +mrb_bint_mod(mrb_state *mrb, mrb_value x, mrb_value y) +{ +#ifndef MRB_NO_FLOAT + if (mrb_float_p(y)) { + mrb_float v1 = mrb_bint_as_float(mrb, x); + mrb_float v2 = mrb_float(y); + return mrb_float_value(mrb,fmod(v1,v2)); + } +#endif + y = mrb_as_bint(mrb, y); + struct RBigint *b = RBIGINT(x); + struct RBigint *b2 = RBIGINT(y); + struct RBigint *b3 = bint_new(mrb); + mpz_mmod(mrb, &b3->mp, &b->mp, &b2->mp); + return bint_norm(mrb, b3); +} + +mrb_value +mrb_bint_rem(mrb_state *mrb, mrb_value x, mrb_value y) +{ + /* called from mrbgems/mruby-numeric-ext/src/numeric_ext.c */ + /* y should not be float */ + struct RBigint *b = RBIGINT(x); + struct RBigint *b2 = RBIGINT(y); + struct RBigint *b3 = bint_new(mrb); + y = mrb_as_bint(mrb, y); + mpz_mod(mrb, &b3->mp, &b->mp, &b2->mp); + return bint_norm(mrb, b3); +} + +mrb_value +mrb_bint_divmod(mrb_state *mrb, mrb_value x, mrb_value y) +{ + /* called from src/numeric.c */ + /* y should not be float */ + y = mrb_as_bint(mrb, y); + struct RBigint *b = RBIGINT(x); + struct RBigint *b2 = RBIGINT(y); + struct RBigint *b3 = bint_new(mrb); + struct RBigint *b4 = bint_new(mrb); + mpz_mdivmod(mrb, &b3->mp, &b4->mp, &b->mp, &b2->mp); + x = bint_norm(mrb, b3); + y = bint_norm(mrb, b4); + return mrb_assoc_new(mrb, x, y); +} + +mrb_int +mrb_bint_cmp(mrb_state *mrb, mrb_value x, mrb_value y) +{ +#ifndef MRB_NO_FLOAT + if (mrb_float_p(y)) { + mrb_float v1 = mrb_bint_as_float(mrb, x); + mrb_float v2 = mrb_float(y); + if (v1 == v2) return 0; + if (v1 > v2) return 1; + return -1; + } +#endif + struct RBigint *b = RBIGINT(x); + if (!mrb_bigint_p(y)) { + if (!mrb_integer_p(y)) return -2; /* type mismatch */ + + mrb_int i1, i2 = mrb_integer(y); + if (mpz_get_int(&b->mp, &i1)) { + if (i1 == i2) return 0; + if (i1 > i2) return 1; + return -1; + } + if (b->mp.sn > 0) return 1; + return -1; + } + struct RBigint *b2 = RBIGINT(y); + return mpz_cmp(mrb, &b->mp, &b2->mp); +} + +mrb_value +mrb_bint_pow(mrb_state *mrb, mrb_value x, mrb_value y) +{ + struct RBigint *b = RBIGINT(x); + switch (mrb_type(y)) { + case MRB_TT_INTEGER: + { + struct RBigint *b3 = bint_new(mrb); + mpz_pow(mrb, &b3->mp, &b->mp, mrb_integer(y)); + return mrb_obj_value(b3); + } + case MRB_TT_BIGINT: + mrb_raise(mrb, E_TYPE_ERROR, "too big power"); + default: + mrb_raisef(mrb, E_TYPE_ERROR, "%v cannot be convert to integer", y); + } + return mrb_nil_value(); +} + +mrb_value +mrb_bint_powm(mrb_state *mrb, mrb_value x, mrb_int exp, mrb_value mod) +{ + struct RBigint *b = RBIGINT(x); + switch (mrb_type(mod)) { + case MRB_TT_INTEGER: + { + struct RBigint *b2 = bint_new(mrb); + struct RBigint *b3 = bint_new_int(mrb, mrb_integer(mod)); + mpz_powm(mrb, &b2->mp, &b->mp, exp, &b3->mp); + return mrb_obj_value(b3); + } + case MRB_TT_BIGINT: + { + struct RBigint *b2 = bint_new(mrb); + struct RBigint *b3 = RBIGINT(mod); + mpz_powm(mrb, &b2->mp, &b->mp, exp, &b3->mp); + return bint_norm(mrb, b3); + } + mrb_raise(mrb, E_TYPE_ERROR, "too big power"); + default: + mrb_raisef(mrb, E_TYPE_ERROR, "%v cannot be convert to integer", mod); + } + return mrb_nil_value(); +} + +mrb_value +mrb_bint_to_s(mrb_state *mrb, mrb_value x, mrb_int base) +{ + struct RBigint *b = RBIGINT(x); + mrb_int len = mpz_sizeinbase(&b->mp, (int)base); + mrb_value str = mrb_str_new(mrb, NULL, len+2); + mpz_get_str(mrb, RSTRING_PTR(str), len, base, &b->mp); + RSTR_SET_LEN(RSTRING(str), strlen(RSTRING_PTR(str))); + return str; +} + +mrb_value +mrb_bint_and(mrb_state *mrb, mrb_value x, mrb_value y) +{ + struct RBigint *b1 = RBIGINT(x); + struct RBigint *b3 = bint_new(mrb); + +#ifndef MRB_NO_FLOAT + if (mrb_float_p(y)) { + mpz_t z; + mpz_init_set_int(mrb, &z, (mrb_int)mrb_float(y)); + mpz_and(mrb, &b3->mp, &b1->mp, &z); + mpz_clear(mrb, &z); + return bint_norm(mrb, b3); + } +#endif + y = mrb_as_bint(mrb, y); + struct RBigint *b2 = RBIGINT(y); + mpz_and(mrb, &b3->mp, &b1->mp, &b2->mp); + return bint_norm(mrb, b3); +} + +mrb_value +mrb_bint_or(mrb_state *mrb, mrb_value x, mrb_value y) +{ + struct RBigint *b1 = RBIGINT(x); + struct RBigint *b3 = bint_new(mrb); + +#ifndef MRB_NO_FLOAT + if (mrb_float_p(y)) { + mpz_t z; + mpz_init_set_int(mrb, &z, (mrb_int)mrb_float(y)); + mpz_or(mrb, &b3->mp, &b1->mp, &z); + mpz_clear(mrb, &z); + return bint_norm(mrb, b3); + } +#endif + y = mrb_as_bint(mrb, y); + struct RBigint *b2 = RBIGINT(y); + mpz_or(mrb, &b3->mp, &b1->mp, &b2->mp); + return bint_norm(mrb, b3); +} + +mrb_value +mrb_bint_xor(mrb_state *mrb, mrb_value x, mrb_value y) +{ + struct RBigint *b3 = bint_new(mrb); + struct RBigint *b1 = RBIGINT(x); + +#ifndef MRB_NO_FLOAT + if (mrb_float_p(y)) { + mpz_t z; + mpz_init_set_int(mrb, &z, (mrb_int)mrb_float(y)); + mpz_xor(mrb, &b3->mp, &b1->mp, &z); + mpz_clear(mrb, &z); + return bint_norm(mrb, b3); + } +#endif + y = mrb_as_bint(mrb, y); + struct RBigint *b2 = RBIGINT(y); + mpz_xor(mrb, &b3->mp, &b1->mp, &b2->mp); + return bint_norm(mrb, b3); +} + +mrb_value +mrb_bint_rev(mrb_state *mrb, mrb_value x) +{ + struct RBigint *b1 = RBIGINT(x); + struct RBigint *b2 = bint_new(mrb); + + mpz_neg(mrb, &b2->mp, &b1->mp); + mpz_sub_int(mrb, &b2->mp, &b2->mp, 1); + return bint_norm(mrb, b2); +} + +mrb_value +mrb_bint_lshift(mrb_state *mrb, mrb_value x, mrb_int width) +{ + struct RBigint *b = RBIGINT(x); + struct RBigint *b2 = bint_new(mrb); + if (width < 0) { + mpz_div_2exp(mrb, &b2->mp, &b->mp, -width); + } + else { + mpz_mul_2exp(mrb, &b2->mp, &b->mp, width); + } + return bint_norm(mrb, b2); +} + +mrb_value +mrb_bint_rshift(mrb_state *mrb, mrb_value x, mrb_int width) +{ + struct RBigint *b = RBIGINT(x); + struct RBigint *b2 = bint_new(mrb); + if (width < 0) { + mpz_mul_2exp(mrb, &b2->mp, &b->mp, -width); + } + else { + mpz_div_2exp(mrb, &b2->mp, &b->mp, width); + } + return bint_norm(mrb, b2); +} diff --git a/mrbgems/mruby-bigint/core/bigint.h b/mrbgems/mruby-bigint/core/bigint.h new file mode 100644 index 000000000..24ed6ee7c --- /dev/null +++ b/mrbgems/mruby-bigint/core/bigint.h @@ -0,0 +1,87 @@ +/** +** @file mruby/bigint.h - Multi-precision, Integer +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_BIGINT_H +#define MRUBY_BIGINT_H +/* + * FREE GMP - a public domain implementation of a subset of the + * gmp library + * + * I hearby place the file in the public domain. + * + * Do whatever you want with this code. Change it. Sell it. Claim you + * wrote it. + * Bugs, complaints, flames, rants: please send email to + * Mark Henderson + * I'm already aware that fgmp is considerably slower than gmp + * + * CREDITS: + * Paul Rouse - generic bug fixes, mpz_sqrt and + * mpz_sqrtrem, and modifications to get fgmp to compile on a system + * with int and long of different sizes (specifically MS-DOS,286 compiler) + * Also see the file "notes" included with the fgmp distribution, for + * more credits. + * + * VERSION 1.0 - beta 5 + */ + +#include + +#if defined(MRB_32BIT) && defined(MRB_INT32) +/* + * The values below are for 32 bit machines (i.e. machines with a + * 32 bit long type) + * You'll need to change them, if you're using something else + * If DIGITBITS is odd, see the comment at the top of mpz_sqrtrem + */ +typedef int32_t mp_limb; +typedef uint32_t mp_ulimb; +#define LMAX 0x3fffffffL +#define LC 0xc0000000L +#define CMASK (LMAX+1) +#define HLMAX 0x7fffL +#define HCMASK (HLMAX + 1) +#define HIGH(x) (((x) & 0x3fff8000L) >> 15) +#define LOW(x) ((x) & 0x7fffL) + +#else +/* 64 bit long type */ +typedef int64_t mp_limb; +typedef uint64_t mp_ulimb; +#define LMAX 0x3fffffffffffffffLL +#define LC 0xc000000000000000LL +#define CMASK (LMAX+1) +#define HLMAX 0x7fffffffLL +#define HCMASK (HLMAX + 1) +#define HIGH(x) (((x) & 0x3fffffff80000000LL) >> 31) +#define LOW(x) ((x) & 0x7fffffffLL) +#endif + +typedef struct _mpz_t { + mp_limb *p; + short sn; + size_t sz; +} mpz_t; + +struct RBigint { + MRB_OBJECT_HEADER; + mpz_t mp; +}; +#define RBIGINT(v) ((struct RBigint*)mrb_ptr(v)) + +#define iabs(x) ((x>0) ? (x) : (-x)) +#define imax(x,y) ((x>y)?x:y) +#define LONGBITS (sizeof(mp_limb)*8) +#define DIGITBITS (LONGBITS-2) +#define HALFDIGITBITS ((LONGBITS-2)/2) + +#define hd(x,i) (((size_t)(i)>=2*((x)->sz))? 0:(((i)%2) ? HIGH((x)->p[(i)/2]) \ + : LOW((x)->p[(i)/2]))) +#define dg(x,i) (((size_t)(i) < (x)->sz) ? ((x)->p)[i] : 0) + +#define RBIGINT(v) ((struct RBigint*)mrb_ptr(v)) + +#endif /* MRUBY_BIGINT_H */ diff --git a/mrbgems/mruby-bigint/mrbgem.rake b/mrbgems/mruby-bigint/mrbgem.rake new file mode 100644 index 000000000..a1039bf57 --- /dev/null +++ b/mrbgems/mruby-bigint/mrbgem.rake @@ -0,0 +1,10 @@ +MRuby::Gem::Specification.new('mruby-bigint') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'Integer class extension to multiple-precision' + spec.build.defines << "MRB_USE_BIGINT" + + spec.build.libmruby_core_objs << Dir.glob(File.join(__dir__, "core/**/*.c")).map { |fn| + objfile(fn.relative_path_from(__dir__).pathmap("#{spec.build_dir}/%X")) + } +end diff --git a/mrbgems/mruby-bigint/test/bigint.rb b/mrbgems/mruby-bigint/test/bigint.rb new file mode 100644 index 000000000..8ab09548e --- /dev/null +++ b/mrbgems/mruby-bigint/test/bigint.rb @@ -0,0 +1,23 @@ +assert 'Bigint basic' do + n = 1<<65 + assert_equal 36893488147419103232, n + assert_equal 36893488147419104229, n+997 + assert_equal 36893488147419102235, n-997 + assert_equal 36782807682976845922304, n*997 + assert_equal 37004501652376231, n.div(997) +end + +assert 'Bigint to_s' do + n = 1197857166996989179607278372168909873645893814254642585755536286462800958278984531968 + assert_equal n, "11978_571669_96989179607278372168909873645893814254642585755536286462800958278984531968".to_i + assert_equal(-n, "-11978_571669_96989179607278372168909873645893814254642585755536286462800958278984531968".to_i) + n = 0x1197857166996989179607278372168909873645893814254642585755536286462800958278984531968 + assert_equal n, "1197857166996989179607278372168909873645893814254642585755536286462800958278984531968".to_i(16) +end + +assert 'Bigint pow' do + n = 18446744073709551616 + assert_equal n, 2 ** 64 + assert_equal n, 1 << 64 + assert_equal 2, n >> 63 +end diff --git a/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c b/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c index 55c6cd125..a69d65dd9 100644 --- a/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c +++ b/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "mrdberror.h" #include "apibreak.h" #include "apistring.h" @@ -20,8 +21,6 @@ #define MRB_DEBUG_BP_FILE_OK (0x0001) #define MRB_DEBUG_BP_LINENO_OK (0x0002) -uint32_t mrb_packed_int_decode(uint8_t *p, uint8_t **newpos); - static uint16_t check_lineno(mrb_irep_debug_info_file *info_file, uint16_t lineno) { @@ -47,8 +46,8 @@ check_lineno(mrb_irep_debug_info_file *info_file, uint16_t lineno) case mrb_debug_line_packed_map: { - uint8_t *p = info_file->lines.packed_map; - uint8_t *pend = p + count; + const uint8_t *p = info_file->lines.packed_map; + const uint8_t *pend = p + count; uint32_t line = 0; while (p < pend) { mrb_packed_int_decode(p, &p); diff --git a/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c b/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c index ee2ae0aca..340a57b56 100644 --- a/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c +++ b/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "mrdb.h" #include "apibreak.h" diff --git a/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c b/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c index 7732914d7..ef806bdf0 100644 --- a/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c +++ b/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c @@ -9,6 +9,7 @@ #include #include #include +#include #define RITEBIN_EXT ".mrb" #define C_EXT ".c" @@ -25,7 +26,8 @@ struct mrbc_args { mrb_bool verbose : 1; mrb_bool remove_lv : 1; mrb_bool no_ext_ops : 1; - uint8_t flags : 4; + mrb_bool no_optimize : 1; + uint8_t flags : 2; }; static void @@ -42,6 +44,7 @@ usage(const char *name) "-s define as static variable", "--remove-lv remove local variables", "--no-ext-ops prohibit using OP_EXTs", + "--no-optimize disable peephole optimization", "--verbose run at verbose mode", "--version print the version", "--copyright print the copyright", @@ -169,6 +172,10 @@ parse_args(mrb_state *mrb, int argc, char **argv, struct mrbc_args *args) args->no_ext_ops = TRUE; break; } + else if (strcmp(argv[i] + 2, "no-optimize") == 0) { + args->no_optimize = TRUE; + break; + } return -1; default: return i; @@ -224,6 +231,7 @@ load_file(mrb_state *mrb, struct mrbc_args *args) c->dump_result = TRUE; c->no_exec = TRUE; c->no_ext_ops = args->no_ext_ops; + c->no_optimize = args->no_optimize; if (input[0] == '-' && input[1] == '\0') { infile = stdin; } @@ -366,31 +374,3 @@ mrb_final_mrbgems(mrb_state *mrb) { } #endif - -#ifdef MRB_USE_COMPLEX -mrb_value mrb_complex_to_i(mrb_state *mrb, mrb_value comp) -{ - /* dummy method */ - return mrb_nil_value(); -} -mrb_value mrb_complex_to_f(mrb_state *mrb, mrb_value comp) -{ - /* dummy method */ - return mrb_nil_value(); -} -#endif - -#ifdef MRB_USE_RATIONAL -mrb_value -mrb_rational_to_i(mrb_state *mrb, mrb_value rat) -{ - /* dummy method */ - return mrb_nil_value(); -} -mrb_value -mrb_rational_to_f(mrb_state *mrb, mrb_value rat) -{ - /* dummy method */ - return mrb_nil_value(); -} -#endif diff --git a/mrbgems/mruby-bin-mrbc/tools/mrbc/stub.c b/mrbgems/mruby-bin-mrbc/tools/mrbc/stub.c new file mode 100644 index 000000000..1ad628664 --- /dev/null +++ b/mrbgems/mruby-bin-mrbc/tools/mrbc/stub.c @@ -0,0 +1,68 @@ +#include + +/* + functions defined in mrbgems referenced from the core should be listed here + to avoid link errors, since mrbc does not link any mrbgem ignoring configuration. +*/ + +#ifdef MRB_USE_COMPLEX +mrb_value mrb_complex_new(mrb_state *mrb, mrb_float x, mrb_float y) +{ + return mrb_nil_value(); +} +mrb_value mrb_complex_add(mrb_state *mrb, mrb_value x, mrb_value y) +{ + return mrb_nil_value(); +} +mrb_value mrb_complex_sub(mrb_state *mrb, mrb_value x, mrb_value y) +{ + return mrb_nil_value(); +} +mrb_value mrb_complex_mul(mrb_state *mrb, mrb_value x, mrb_value y) +{ + return mrb_nil_value(); +} +mrb_value mrb_complex_div(mrb_state *mrb, mrb_value x, mrb_value y) +{ + return mrb_nil_value(); +} +mrb_value mrb_complex_to_i(mrb_state *mrb, mrb_value x) +{ + return mrb_nil_value(); +} +mrb_value mrb_complex_to_f(mrb_state *mrb, mrb_value x) +{ + return mrb_nil_value(); +} +#endif + +#ifdef MRB_USE_RATIONAL +mrb_value mrb_rational_new(mrb_state *mrb, mrb_int x, mrb_int y) +{ + return mrb_nil_value(); +} +mrb_value mrb_rational_add(mrb_state *mrb, mrb_value x, mrb_value y) +{ + return mrb_nil_value(); +} +mrb_value mrb_rational_sub(mrb_state *mrb, mrb_value x, mrb_value y) +{ + return mrb_nil_value(); +} +mrb_value mrb_rational_mul(mrb_state *mrb, mrb_value x, mrb_value y) +{ + return mrb_nil_value(); +} +mrb_value mrb_rational_div(mrb_state *mrb, mrb_value x, mrb_value y) +{ + return mrb_nil_value(); +} +mrb_value mrb_rational_to_i(mrb_state *mrb, mrb_value x) +{ + return mrb_nil_value(); +} +mrb_value mrb_rational_to_f(mrb_state *mrb, mrb_value x) +{ + return mrb_nil_value(); +} +#endif diff --git a/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c b/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c index b189aca69..1822a585d 100644 --- a/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c +++ b/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c @@ -63,6 +63,16 @@ usage(const char *name) printf(" %s\n", *p++); } +static mrb_bool +mrb_extension_p(const char *path) +{ + const char *e = strrchr(path, '.'); + if (e && e[1] == 'm' && e[2] == 'r' && e[3] == 'b' && e[4] == '\0') { + return TRUE; + } + return FALSE; +} + static void options_init(struct options *opts, int argc, char **argv) { @@ -323,7 +333,7 @@ main(int argc, char **argv) return EXIT_FAILURE; } mrbc_filename(mrb, c, args.libv[i]); - if (args.mrbfile) { + if (mrb_extension_p(args.libv[i])) { v = mrb_load_irep_file_cxt(mrb, lfp, c); } else { @@ -340,7 +350,7 @@ main(int argc, char **argv) mrbc_filename(mrb, c, cmdline); /* Load program */ - if (args.mrbfile) { + if (args.mrbfile || mrb_extension_p(cmdline)) { v = mrb_load_irep_file_cxt(mrb, args.rfp, c); } else if (args.rfp) { diff --git a/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c b/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c index 0c632b7c1..ff39dd357 100644 --- a/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c +++ b/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c @@ -8,6 +8,7 @@ #include #include #include +#include struct strip_args { int argc_start; diff --git a/mrbgems/mruby-binding/src/binding.c b/mrbgems/mruby-binding/src/binding.c index eb44f0e90..e4c362793 100644 --- a/mrbgems/mruby-binding/src/binding.c +++ b/mrbgems/mruby-binding/src/binding.c @@ -45,7 +45,7 @@ binding_eval_error_check(mrb_state *mrb, struct mrb_parser_state *p, const char struct expand_lvspace { mrb_irep *irep; struct REnv *env; - size_t numvar; + int numvar; mrb_sym syms[LV_BUFFERS]; }; diff --git a/mrbgems/mruby-binding/test/binding.c b/mrbgems/mruby-binding/test/binding.c index 5a37ca043..efc982a75 100644 --- a/mrbgems/mruby-binding/test/binding.c +++ b/mrbgems/mruby-binding/test/binding.c @@ -1,9 +1,10 @@ #include +#include static mrb_value binding_in_c(mrb_state *mrb, mrb_value self) { - return mrb_funcall_argv(mrb, mrb_obj_value(mrb->object_class), mrb_intern_lit(mrb, "binding"), 0, NULL); + return mrb_funcall_argv(mrb, mrb_obj_value(mrb->object_class), MRB_SYM(binding), 0, NULL); } void diff --git a/mrbgems/mruby-class-ext/src/class.c b/mrbgems/mruby-class-ext/src/class.c index 290ddf4b3..373af8312 100644 --- a/mrbgems/mruby-class-ext/src/class.c +++ b/mrbgems/mruby-class-ext/src/class.c @@ -1,6 +1,7 @@ #include "mruby.h" #include "mruby/class.h" #include "mruby/string.h" +#include "mruby/array.h" #include "mruby/proc.h" static mrb_value @@ -56,6 +57,57 @@ mrb_mod_module_exec(mrb_state *mrb, mrb_value self) return mrb_yield_cont(mrb, blk, self, argc, argv); } +struct subclass_args { + struct RClass *c; + mrb_value ary; +}; + +static int +add_subclasses(mrb_state *mrb, struct RBasic *obj, void *data) +{ + struct subclass_args *args = (struct subclass_args*)data; + if (obj->tt == MRB_TT_CLASS) { + struct RClass *c = (struct RClass*)obj; + if (mrb_class_real(c->super) == args->c) { + mrb_ary_push(mrb, args->ary, mrb_obj_value(obj)); + } + } + return MRB_EACH_OBJ_OK; +} + +/* + * call-seq: + * subclasses -> array + * + * Returns an array of classes where the receiver is the + * direct superclass of the class, excluding singleton classes. + * The order of the returned array is not defined. + * + * class A; end + * class B < A; end + * class C < B; end + * class D < A; end + * + * A.subclasses #=> [D, B] + * B.subclasses #=> [C] + * C.subclasses #=> [] + */ +static mrb_value +mrb_class_subclasses(mrb_state *mrb, mrb_value self) +{ + struct RClass *c; + mrb_value ary; + + c = mrb_class_ptr(self); + ary = mrb_ary_new(mrb); + + if (c->flags & MRB_FL_CLASS_IS_INHERITED) { + struct subclass_args arg = {c, ary}; + mrb_objspace_each_objects(mrb, add_subclasses, &arg); + } + return ary; +} + void mrb_mruby_class_ext_gem_init(mrb_state *mrb) { @@ -65,6 +117,9 @@ mrb_mruby_class_ext_gem_init(mrb_state *mrb) mrb_define_method(mrb, mod, "singleton_class?", mrb_mod_singleton_class_p, MRB_ARGS_NONE()); mrb_define_method(mrb, mod, "module_exec", mrb_mod_module_exec, MRB_ARGS_ANY()|MRB_ARGS_BLOCK()); mrb_define_method(mrb, mod, "class_exec", mrb_mod_module_exec, MRB_ARGS_ANY()|MRB_ARGS_BLOCK()); + + struct RClass *cls = mrb->module_class; + mrb_define_method(mrb, cls, "subclasses", mrb_class_subclasses, MRB_ARGS_NONE()); } void diff --git a/mrbgems/mruby-class-ext/test/class.rb b/mrbgems/mruby-class-ext/test/class.rb new file mode 100644 index 000000000..2043b39cb --- /dev/null +++ b/mrbgems/mruby-class-ext/test/class.rb @@ -0,0 +1,13 @@ +assert 'Class#subclasses' do + a = Class.new + b = Class.new(a) + c = Class.new(b) + d = Class.new(a) + + a_sub = a.subclasses + assert_equal(2, a_sub.size) + assert_true(a_sub.include?(b)) + assert_true(a_sub.include?(d)) + assert_equal([c], b.subclasses) + assert_equal([], c.subclasses) +end diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 98721496e..2357af9d2 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -18,6 +18,7 @@ #include #include #include +#include #ifndef MRB_CODEGEN_LEVEL_MAX #define MRB_CODEGEN_LEVEL_MAX 256 @@ -57,7 +58,7 @@ typedef struct scope { uint32_t pc; uint32_t lastpc; uint32_t lastlabel; - size_t ainfo:15; + uint16_t ainfo:15; mrb_bool mscope:1; struct loopinfo *loop; @@ -101,8 +102,8 @@ static void loop_pop(codegen_scope *s, int val); static int catch_handler_new(codegen_scope *s); static void catch_handler_set(codegen_scope *s, int ent, enum mrb_catch_type type, uint32_t begin, uint32_t end, uint32_t target); -static void gen_assignment(codegen_scope *s, node *tree, int sp, int val); -static void gen_vmassignment(codegen_scope *s, node *tree, int rhs, int val); +static void gen_assignment(codegen_scope *s, node *tree, node *rhs, int sp, int val); +static void gen_massignment(codegen_scope *s, node *tree, int sp, int val); static void codegen(codegen_scope *s, node *tree, int val); static void raise_error(codegen_scope *s, const char *msg); @@ -286,10 +287,10 @@ genop_2(codegen_scope *s, mrb_code i, uint16_t a, uint16_t b) } static void -genop_3(codegen_scope *s, mrb_code i, uint16_t a, uint16_t b, uint8_t c) +genop_3(codegen_scope *s, mrb_code i, uint16_t a, uint16_t b, uint16_t c) { genop_2(s, i, a, b); - gen_B(s, c); + gen_B(s, (uint8_t)c); } static void @@ -594,9 +595,22 @@ gen_move(codegen_scope *s, uint16_t dst, uint16_t src, int nopeep) switch (data.insn) { case OP_MOVE: - if (dst == src) return; /* remove useless MOVE */ - if (data.b == dst && data.a == src) /* skip swapping MOVE */ + if (dst == src) return; /* remove useless MOVE */ + if (data.a == src) { + if (data.b == dst) /* skip swapping MOVE */ + return; + if (data.a < s->nlocals) goto normal; + rewind_pc(s); + s->lastpc = addr_pc(s, mrb_prev_pc(s, data.addr)); + gen_move(s, dst, data.b, FALSE); return; + } + if (dst == data.a) { /* skip overwritten move */ + rewind_pc(s); + s->lastpc = addr_pc(s, mrb_prev_pc(s, data.addr)); + gen_move(s, dst, src, FALSE); + return; + } goto normal; case OP_LOADNIL: case OP_LOADSELF: case OP_LOADT: case OP_LOADF: case OP_LOADI__1: @@ -606,7 +620,7 @@ gen_move(codegen_scope *s, uint16_t dst, uint16_t src, int nopeep) rewind_pc(s); genop_1(s, data.insn, dst); return; - case OP_HASH: case OP_ARRAY: + case OP_HASH: if (data.b != 0) goto normal; /* fall through */ case OP_LOADI: case OP_LOADINEG: @@ -631,6 +645,19 @@ gen_move(codegen_scope *s, uint16_t dst, uint16_t src, int nopeep) genop_2SS(s, data.insn, dst, i); } return; + case OP_ARRAY: + if (data.a != src || data.a < s->nlocals || data.a < dst) goto normal; + rewind_pc(s); + if (data.b == 0 || dst == data.a) + genop_2(s, OP_ARRAY, dst, 0); + else + genop_3(s, OP_ARRAY2, dst, data.a, data.b); + return; + case OP_ARRAY2: + if (data.a != src || data.a < s->nlocals || data.a < dst) goto normal; + rewind_pc(s); + genop_3(s, OP_ARRAY2, dst, data.b, data.c); + return; case OP_AREF: case OP_GETUPVAR: if (data.a != src || data.a < s->nlocals) goto normal; @@ -831,13 +858,14 @@ gen_muldiv(codegen_scope *s, uint8_t op, uint16_t dst) goto normal; } struct mrb_insn_data data0 = mrb_decode_insn(mrb_prev_pc(s, data.addr)); - if (!get_int_operand(s, &data0, &n0) || n == 0) { + if (!get_int_operand(s, &data0, &n0)) { goto normal; } if (op == OP_MUL) { if (mrb_int_mul_overflow(n0, n, &n)) goto normal; } else { /* OP_DIV */ + if (n == 0) goto normal; if (n0 == MRB_INT_MIN && n == -1) goto normal; n = mrb_div_int(s->mrb, n0, n); } @@ -961,6 +989,17 @@ pop_n_(codegen_scope *s, int n) #define pop_n(n) pop_n_(s,n) #define cursp() (s->sp) +static mrb_pool_value* +lit_pool_extend(codegen_scope *s) +{ + if (s->irep->plen == s->pcapa) { + s->pcapa *= 2; + s->pool = (mrb_pool_value*)codegen_realloc(s, s->pool, sizeof(mrb_pool_value)*s->pcapa); + } + + return &s->pool[s->irep->plen++]; +} + static int new_litbn(codegen_scope *s, const char *p, int base, mrb_bool neg) { @@ -981,13 +1020,8 @@ new_litbn(codegen_scope *s, const char *p, int base, mrb_bool neg) return i; } - if (s->irep->plen == s->pcapa) { - s->pcapa *= 2; - s->pool = (mrb_pool_value*)codegen_realloc(s, s->pool, sizeof(mrb_pool_value)*s->pcapa); - } + pv = lit_pool_extend(s); - pv = &s->pool[s->irep->plen]; - i = s->irep->plen++; { char *buf; pv->tt = IREP_TT_BIGINT; @@ -1003,104 +1037,100 @@ new_litbn(codegen_scope *s, const char *p, int base, mrb_bool neg) } static int -new_lit(codegen_scope *s, mrb_value val) +new_lit_str(codegen_scope *s, const char *str, mrb_int len) { int i; mrb_pool_value *pv; - switch (mrb_type(val)) { - case MRB_TT_STRING: - for (i=0; iirep->plen; i++) { - mrb_int len; - pv = &s->pool[i]; - if (pv->tt & IREP_TT_NFLAG) continue; - len = pv->tt>>2; - if (RSTRING_LEN(val) != len) continue; - if (memcmp(pv->u.str, RSTRING_PTR(val), len) == 0) - return i; - } - break; -#ifndef MRB_NO_FLOAT - case MRB_TT_FLOAT: - for (i=0; iirep->plen; i++) { - mrb_float f1, f2; - pv = &s->pool[i]; - if (pv->tt != IREP_TT_FLOAT) continue; - pv = &s->pool[i]; - f1 = pv->u.f; - f2 = mrb_float(val); - if (f1 == f2 && !signbit(f1) == !signbit(f2)) return i; - } - break; -#endif - case MRB_TT_INTEGER: - for (i=0; iirep->plen; i++) { - mrb_int v = mrb_integer(val); - pv = &s->pool[i]; - if (pv->tt == IREP_TT_INT32) { - if (v == pv->u.i32) return i; - } -#ifdef MRB_64BIT - else if (pv->tt == IREP_TT_INT64) { - if (v == pv->u.i64) return i; - } - continue; -#endif - } - break; - default: - /* should not happen */ - return 0; + for (i=0; iirep->plen; i++) { + pv = &s->pool[i]; + if (pv->tt & IREP_TT_NFLAG) continue; + mrb_int plen = pv->tt>>2; + if (len != plen) continue; + if (memcmp(pv->u.str, str, plen) == 0) + return i; } - if (s->irep->plen == s->pcapa) { - s->pcapa *= 2; - s->pool = (mrb_pool_value*)codegen_realloc(s, s->pool, sizeof(mrb_pool_value)*s->pcapa); + pv = lit_pool_extend(s); + + if (mrb_ro_data_p(str)) { + pv->tt = (uint32_t)(len<<2) | IREP_TT_SSTR; + pv->u.str = str; + } + else { + char *p; + pv->tt = (uint32_t)(len<<2) | IREP_TT_STR; + p = (char*)codegen_realloc(s, NULL, len+1); + memcpy(p, str, len); + p[len] = '\0'; + pv->u.str = p; } - pv = &s->pool[s->irep->plen]; - i = s->irep->plen++; - - switch (mrb_type(val)) { - case MRB_TT_STRING: - if (RSTR_NOFREE_P(RSTRING(val))) { - pv->tt = (uint32_t)(RSTRING_LEN(val)<<2) | IREP_TT_SSTR; - pv->u.str = RSTRING_PTR(val); - } - else { - char *p; - mrb_int len = RSTRING_LEN(val); - pv->tt = (uint32_t)(len<<2) | IREP_TT_STR; - p = (char*)codegen_realloc(s, NULL, len+1); - memcpy(p, RSTRING_PTR(val), len); - p[len] = '\0'; - pv->u.str = p; - } - break; - -#ifndef MRB_NO_FLOAT - case MRB_TT_FLOAT: - pv->tt = IREP_TT_FLOAT; - pv->u.f = mrb_float(val); - break; -#endif - case MRB_TT_INTEGER: -#ifdef MRB_INT64 - pv->tt = IREP_TT_INT64; - pv->u.i64 = mrb_integer(val); -#else - pv->tt = IREP_TT_INT32; - pv->u.i32 = mrb_integer(val); -#endif - break; - - default: - /* should not happen */ - break; - } return i; } +static int +new_lit_cstr(codegen_scope *s, const char *str) +{ + return new_lit_str(s, str, (mrb_int)strlen(str)); +} + +static int +new_lit_int(codegen_scope *s, mrb_int num) +{ + int i; + mrb_pool_value *pv; + + for (i=0; iirep->plen; i++) { + pv = &s->pool[i]; + if (pv->tt == IREP_TT_INT32) { + if (num == pv->u.i32) return i; + } +#ifdef MRB_64BIT + else if (pv->tt == IREP_TT_INT64) { + if (num == pv->u.i64) return i; + } + continue; +#endif + } + + pv = lit_pool_extend(s); + +#ifdef MRB_INT64 + pv->tt = IREP_TT_INT64; + pv->u.i64 = num; +#else + pv->tt = IREP_TT_INT32; + pv->u.i32 = num; +#endif + + return i; +} + +#ifndef MRB_NO_FLOAT +static int +new_lit_float(codegen_scope *s, mrb_float num) +{ + int i; + mrb_pool_value *pv; + + for (i=0; iirep->plen; i++) { + mrb_float f; + pv = &s->pool[i]; + if (pv->tt != IREP_TT_FLOAT) continue; + f = pv->u.f; + if (f == num && !signbit(f) == !signbit(num)) return i; + } + + pv = lit_pool_extend(s); + + pv->tt = IREP_TT_FLOAT; + pv->u.f = num; + + return i; +} +#endif + static int new_sym(codegen_scope *s, mrb_sym sym) { @@ -1153,7 +1183,7 @@ gen_int(codegen_scope *s, uint16_t dst, mrb_int i) else if (i <= INT32_MAX) genop_2SS(s, OP_LOADI32, dst, (uint32_t)i); else { int_lit: - genop_2(s, OP_LOADL, dst, new_lit(s, mrb_int_value(s->mrb, i))); + genop_2(s, OP_LOADL, dst, new_lit_int(s, i)); } } @@ -1275,10 +1305,10 @@ for_body(codegen_scope *s, node *tree) n2 = tree->car; genop_W(s, OP_ENTER, 0x40000); if (n2->car && !n2->car->cdr && !n2->cdr) { - gen_assignment(s, n2->car->car, 1, NOVAL); + gen_assignment(s, n2->car->car, NULL, 1, NOVAL); } else { - gen_vmassignment(s, n2, 1, VAL); + gen_massignment(s, n2, 1, VAL); } /* construct loop */ lp = loop_push(s, LOOP_FOR); @@ -1444,7 +1474,7 @@ lambda_body(codegen_scope *s, node *tree, int blk) pos = 1; while (n) { if (nint(n->car->car) == NODE_MASGN) { - gen_vmassignment(s, n->car->cdr->car, pos, NOVAL); + gen_massignment(s, n->car->cdr->car, pos, NOVAL); } pos++; n = n->cdr; @@ -1456,7 +1486,7 @@ lambda_body(codegen_scope *s, node *tree, int blk) pos = ma+oa+ra+1; while (n) { if (nint(n->car->car) == NODE_MASGN) { - gen_vmassignment(s, n->car->cdr->car, pos, NOVAL); + gen_massignment(s, n->car->cdr->car, pos, NOVAL); } pos++; n = n->cdr; @@ -1530,7 +1560,7 @@ attrsym(codegen_scope *s, mrb_sym a) #define GEN_VAL_STACK_MAX 99 static int -gen_values(codegen_scope *s, node *t, int val, int extra, int limit) +gen_values(codegen_scope *s, node *t, int val, int limit) { int n = 0; int first = 1; @@ -1551,7 +1581,7 @@ gen_values(codegen_scope *s, node *t, int val, int extra, int limit) while (t) { int is_splat = nint(t->car->car) == NODE_SPLAT; - if (is_splat || n+extra >= limit-1 || cursp() >= slimit) { /* flush stack */ + if (is_splat || cursp() >= slimit) { /* flush stack */ pop_n(n); if (first) { if (n == 0) { @@ -1590,6 +1620,11 @@ gen_values(codegen_scope *s, node *t, int val, int extra, int limit) } return -1; /* variable length */ } + else if (n > limit) { + pop_n(n); + genop_2(s, OP_ARRAY, cursp(), n); + return -1; + } return n; } @@ -1600,10 +1635,16 @@ gen_hash(codegen_scope *s, node *tree, int val, int limit) if (cursp() >= GEN_LIT_ARY_MAX) slimit = INT16_MAX; int len = 0; mrb_bool update = FALSE; + mrb_bool first = TRUE; while (tree) { if (nint(tree->car->car->car) == NODE_KW_REST_ARGS) { - if (val && len > 0) { + if (val && first) { + genop_2(s, OP_HASH, cursp(), 0); + push(); + update = TRUE; + } + else if (val && len > 0) { pop_n(len*2); if (!update) { genop_2(s, OP_HASH, cursp(), len); @@ -1642,6 +1683,13 @@ gen_hash(codegen_scope *s, node *tree, int val, int limit) update = TRUE; len = 0; } + first = FALSE; + } + if (val && len > limit) { + pop_n(len*2); + genop_2(s, OP_HASH, cursp(), len); + push(); + return -1; } if (update) { if (val && len > 0) { @@ -1655,10 +1703,10 @@ gen_hash(codegen_scope *s, node *tree, int val, int limit) } static void -gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe) +gen_call(codegen_scope *s, node *tree, int val, int safe) { - mrb_sym sym = name ? name : nsym(tree->cdr->car); - int skip = 0, n = 0, nk = 0, noop = 0, noself = 0, blk = 0, sp_save = cursp(); + mrb_sym sym = nsym(tree->cdr->car); + int skip = 0, n = 0, nk = 0, noop = no_optimize(s), noself = 0, blk = 0, sp_save = cursp(); if (!tree->car) { noself = noop = 1; @@ -1675,7 +1723,7 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe) tree = tree->cdr->cdr->car; if (tree) { if (tree->car) { /* positional arguments */ - n = gen_values(s, tree->car, VAL, sp?1:0, 14); + n = gen_values(s, tree->car, VAL, 14); if (n < 0) { /* variable length */ noop = 1; /* not operator */ n = 15; @@ -1688,32 +1736,6 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe) if (nk < 0) nk = 15; } } - if (sp) { /* last argument pushed (attr=, []=) */ - /* pack keyword arguments */ - if (nk > 0 && nk < 15) { - pop_n(nk*2); - genop_2(s, OP_HASH, cursp(), nk); - push(); - } - if (n == CALL_MAXARGS) { - if (nk > 0) { - pop(); pop(); - genop_2(s, OP_ARYPUSH, cursp(), 1); - push(); - } - gen_move(s, cursp(), sp, 0); - pop(); - genop_2(s, OP_ARYPUSH, cursp(), 1); - push(); - } - else { - gen_move(s, cursp(), sp, 0); - push(); - if (nk > 0) n++; - n++; - } - nk = 0; - } if (tree && tree->cdr && tree->cdr->cdr) { codegen(s, tree->cdr->cdr, VAL); pop(); @@ -1773,11 +1795,42 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe) } static void -gen_assignment(codegen_scope *s, node *tree, int sp, int val) +gen_assignment(codegen_scope *s, node *tree, node *rhs, int sp, int val) { int idx; int type = nint(tree->car); + switch (type) { + case NODE_GVAR: + case NODE_ARG: + case NODE_LVAR: + case NODE_IVAR: + case NODE_CVAR: + case NODE_CONST: + case NODE_NIL: + case NODE_MASGN: + if (rhs) { + codegen(s, rhs, VAL); + pop(); + sp = cursp(); + } + break; + + case NODE_COLON2: + case NODE_CALL: + case NODE_SCALL: + /* keep evaluation order */ + break; + + case NODE_NVAR: + codegen_error(s, "Can't assign to numbered parameter"); + break; + + default: + codegen_error(s, "unknown lhs"); + break; + } + tree = tree->cdr; switch (type) { case NODE_GVAR: @@ -1796,10 +1849,6 @@ gen_assignment(codegen_scope *s, node *tree, int sp, int val) gen_setupvar(s, sp, nsym(tree)); } break; - case NODE_NVAR: - idx = nint(tree); - codegen_error(s, "Can't assign to numbered parameter"); - break; case NODE_IVAR: gen_setxv(s, OP_SETIV, sp, nsym(tree), val); break; @@ -1810,9 +1859,16 @@ gen_assignment(codegen_scope *s, node *tree, int sp, int val) gen_setxv(s, OP_SETCONST, sp, nsym(tree), val); break; case NODE_COLON2: - gen_move(s, cursp(), sp, 0); + if (sp) { + gen_move(s, cursp(), sp, 0); + } + sp = cursp(); push(); codegen(s, tree->car, VAL); + if (rhs) { + codegen(s, rhs, VAL); pop(); + gen_move(s, sp, cursp(), 0); + } pop_n(2); idx = new_sym(s, nsym(tree->cdr)); genop_2(s, OP_SETMCNST, sp, idx); @@ -1820,17 +1876,91 @@ gen_assignment(codegen_scope *s, node *tree, int sp, int val) case NODE_CALL: case NODE_SCALL: - push(); - gen_call(s, tree, attrsym(s, nsym(tree->cdr->car)), sp, NOVAL, - type == NODE_SCALL); - pop(); - if (val && cursp() != sp) { - gen_move(s, cursp(), sp, 0); + { + int noself = 0, safe = (type == NODE_SCALL), skip = 0, top, call, n = 0; + mrb_sym mid = nsym(tree->cdr->car); + + top = cursp(); + if (val || sp == cursp()) { + push(); /* room for retval */ + } + call = cursp(); + if (!tree->car) { + noself = 1; + push(); + } + else { + codegen(s, tree->car, VAL); /* receiver */ + } + if (safe) { + int recv = cursp()-1; + gen_move(s, cursp(), recv, 1); + skip = genjmp2_0(s, OP_JMPNIL, cursp(), val); + } + tree = tree->cdr->cdr->car; + if (tree) { + if (tree->car) { /* positional arguments */ + n = gen_values(s, tree->car, VAL, (tree->cdr->car)?13:14); + if (n < 0) { /* variable length */ + n = 15; + push(); + } + } + if (tree->cdr->car) { /* keyword arguments */ + if (n == 13 || n == 14) { + pop_n(n); + genop_2(s, OP_ARRAY, cursp(), n); + push(); + n = 15; + } + gen_hash(s, tree->cdr->car->cdr, VAL, 0); + if (n < 14) { + n++; + } + else { + pop_n(2); + genop_2(s, OP_ARYPUSH, cursp(), 1); + } + push(); + } + } + if (rhs) { + codegen(s, rhs, VAL); + pop(); + } + else { + gen_move(s, cursp(), sp, 0); + } + if (val) { + gen_move(s, top, cursp(), 1); + } + if (n < 15) { + n++; + if (n == 15) { + pop_n(14); + genop_2(s, OP_ARRAY, cursp(), 15); + } + } + else { + pop(); + genop_2(s, OP_ARYPUSH, cursp(), 1); + } + s->sp = call; + if (mid == MRB_OPSYM_2(s->mrb, aref) && n == 2) { + genop_1(s, OP_SETIDX, cursp()); + } + else { + genop_3(s, noself ? OP_SSEND : OP_SEND, cursp(), new_sym(s, attrsym(s, mid)), n); + } + if (safe) { + dispatch(s, skip); + } + s->sp = top; } break; case NODE_MASGN: - gen_vmassignment(s, tree->car, sp, val); + gen_massignment(s, tree->car, sp, val); break; /* splat without assignment */ @@ -1845,7 +1975,7 @@ gen_assignment(codegen_scope *s, node *tree, int sp, int val) } static void -gen_vmassignment(codegen_scope *s, node *tree, int rhs, int val) +gen_massignment(codegen_scope *s, node *tree, int rhs, int val) { int n = 0, post = 0; node *t, *p; @@ -1858,7 +1988,7 @@ gen_vmassignment(codegen_scope *s, node *tree, int rhs, int val) genop_3(s, OP_AREF, sp, rhs, n); push(); - gen_assignment(s, t->car, sp, NOVAL); + gen_assignment(s, t->car, NULL, sp, NOVAL); pop(); n++; t = t->cdr; @@ -1879,12 +2009,12 @@ gen_vmassignment(codegen_scope *s, node *tree, int rhs, int val) genop_3(s, OP_APOST, cursp(), n, post); n = 1; if (t->car && t->car != (node*)-1) { /* rest */ - gen_assignment(s, t->car, cursp(), NOVAL); + gen_assignment(s, t->car, NULL, cursp(), NOVAL); } if (t->cdr && t->cdr->car) { t = t->cdr->car; while (t) { - gen_assignment(s, t->car, cursp()+n, NOVAL); + gen_assignment(s, t->car, NULL, cursp()+n, NOVAL); t = t->cdr; n++; } @@ -1989,7 +2119,7 @@ gen_literal_array(codegen_scope *s, node *tree, mrb_bool sym, int val) static void raise_error(codegen_scope *s, const char *msg) { - int idx = new_lit(s, mrb_str_new_cstr(s->mrb, msg)); + int idx = new_lit_cstr(s, msg); genop_1(s, OP_ERR, idx); } @@ -2204,7 +2334,7 @@ codegen(codegen_scope *s, node *tree, int val) pop(); if (n3->cdr->car) { - gen_assignment(s, n3->cdr->car, exc, NOVAL); + gen_assignment(s, n3->cdr->car, NULL, exc, NOVAL); } if (n3->cdr->cdr->car) { codegen(s, n3->cdr->cdr->car, val); @@ -2509,10 +2639,10 @@ codegen(codegen_scope *s, node *tree, int val) case NODE_FCALL: case NODE_CALL: - gen_call(s, tree, 0, 0, val, 0); + gen_call(s, tree, val, 0); break; case NODE_SCALL: - gen_call(s, tree, 0, 0, val, 1); + gen_call(s, tree, val, 1); break; case NODE_DOT2: @@ -2560,7 +2690,7 @@ codegen(codegen_scope *s, node *tree, int val) { int n; - n = gen_values(s, tree, val, 0, 0); + n = gen_values(s, tree, val, 0); if (val) { if (n >= 0) { pop_n(n); @@ -2588,9 +2718,7 @@ codegen(codegen_scope *s, node *tree, int val) break; case NODE_ASGN: - codegen(s, tree->cdr, VAL); - pop(); - gen_assignment(s, tree->car, cursp(), val); + gen_assignment(s, tree->car, tree->cdr, 0, val); break; case NODE_MASGN: @@ -2613,12 +2741,12 @@ codegen(codegen_scope *s, node *tree, int val) n = 0; while (t) { if (n < len) { - gen_assignment(s, t->car, rhs+n, NOVAL); + gen_assignment(s, t->car, NULL, rhs+n, NOVAL); n++; } else { genop_1(s, OP_LOADNIL, rhs+n); - gen_assignment(s, t->car, rhs+n, NOVAL); + gen_assignment(s, t->car, NULL, rhs+n, NOVAL); } t = t->cdr; } @@ -2641,14 +2769,25 @@ codegen(codegen_scope *s, node *tree, int val) else { rn = len - post - n; } - genop_3(s, OP_ARRAY2, cursp(), rhs+n, rn); - gen_assignment(s, t->car, cursp(), NOVAL); + if (cursp() == rhs+n) { + genop_2(s, OP_ARRAY, cursp(), rn); + } + else { + genop_3(s, OP_ARRAY2, cursp(), rhs+n, rn); + } + gen_assignment(s, t->car, NULL, cursp(), NOVAL); n += rn; } if (t->cdr && t->cdr->car) { t = t->cdr->car; - while (ncar, rhs+n, NOVAL); + while (t) { + if (ncar, NULL, rhs+n, NOVAL); + } + else { + genop_1(s, OP_LOADNIL, cursp()); + gen_assignment(s, t->car, NULL, cursp(), NOVAL); + } t = t->cdr; n++; } @@ -2663,7 +2802,7 @@ codegen(codegen_scope *s, node *tree, int val) else { /* variable rhs */ codegen(s, t, VAL); - gen_vmassignment(s, tree->car, rhs, val); + gen_massignment(s, tree->car, rhs, val); if (!val) { pop(); } @@ -2713,7 +2852,7 @@ codegen(codegen_scope *s, node *tree, int val) idx = new_sym(s, nsym(n->cdr->car)); base = cursp()-1; if (n->cdr->cdr->car) { - nargs = gen_values(s, n->cdr->cdr->car->car, VAL, 1, 14); + nargs = gen_values(s, n->cdr->cdr->car->car, VAL, 13); if (nargs >= 0) { callargs = nargs; } @@ -2769,7 +2908,7 @@ codegen(codegen_scope *s, node *tree, int val) genop_3(s, OP_SEND, cursp(), idx, callargs); } else { - gen_assignment(s, tree->car, cursp(), val); + gen_assignment(s, tree->car, NULL, cursp(), val); } dispatch(s, pos); goto exit; @@ -2807,7 +2946,7 @@ codegen(codegen_scope *s, node *tree, int val) genop_3(s, OP_SEND, cursp(), idx, 1); } if (callargs < 0) { - gen_assignment(s, tree->car, cursp(), val); + gen_assignment(s, tree->car, NULL, cursp(), val); } else { if (val && vsp >= 0) { @@ -2843,7 +2982,7 @@ codegen(codegen_scope *s, node *tree, int val) if (tree) { node *args = tree->car; if (args) { - st = n = gen_values(s, args, VAL, 0, 14); + st = n = gen_values(s, args, VAL, 14); if (n < 0) { st = 1; n = 15; push(); @@ -2884,7 +3023,7 @@ codegen(codegen_scope *s, node *tree, int val) { codegen_scope *s2 = s; int lv = 0; - size_t ainfo = 0; + uint16_t ainfo = 0; int n = CALL_MAXARGS; int sp = cursp(); @@ -2961,7 +3100,7 @@ codegen(codegen_scope *s, node *tree, int val) if (ainfo < 0) codegen_error(s, "invalid yield (SyntaxError)"); push(); if (tree) { - n = gen_values(s, tree, VAL, 0, 14); + n = gen_values(s, tree, VAL, 14); if (n < 0) { n = sendv = 1; push(); @@ -3156,7 +3295,7 @@ codegen(codegen_scope *s, node *tree, int val) if (val) { char *p = (char*)tree; mrb_float f = mrb_float_read(p, NULL); - int off = new_lit(s, mrb_float_value(s->mrb, f)); + int off = new_lit_float(s, f); genop_2(s, OP_LOADL, cursp(), off); push(); @@ -3173,7 +3312,7 @@ codegen(codegen_scope *s, node *tree, int val) if (val) { char *p = (char*)tree->cdr; mrb_float f = mrb_float_read(p, NULL); - int off = new_lit(s, mrb_float_value(s->mrb, -f)); + int off = new_lit_float(s, -f); genop_2(s, OP_LOADL, cursp(), off); push(); @@ -3222,11 +3361,9 @@ codegen(codegen_scope *s, node *tree, int val) case NODE_STR: if (val) { char *p = (char*)tree->car; - size_t len = (intptr_t)tree->cdr; - int ai = mrb_gc_arena_save(s->mrb); - int off = new_lit(s, mrb_str_new(s->mrb, p, len)); + mrb_int len = nint(tree->cdr); + int off = new_lit_str(s, p, len); - mrb_gc_arena_restore(s->mrb, ai); genop_2(s, OP_STRING, cursp(), off); push(); } @@ -3277,7 +3414,6 @@ codegen(codegen_scope *s, node *tree, int val) case NODE_DXSTR: { node *n; - int ai = mrb_gc_arena_save(s->mrb); int sym = new_sym(s, MRB_SYM_2(s->mrb, Kernel)); genop_1(s, OP_LOADSELF, cursp()); @@ -3300,16 +3436,14 @@ codegen(codegen_scope *s, node *tree, int val) sym = new_sym(s, MRB_OPSYM_2(s->mrb, tick)); /* ` */ genop_3(s, OP_SEND, cursp(), sym, 1); if (val) push(); - mrb_gc_arena_restore(s->mrb, ai); } break; case NODE_XSTR: { char *p = (char*)tree->car; - size_t len = (intptr_t)tree->cdr; - int ai = mrb_gc_arena_save(s->mrb); - int off = new_lit(s, mrb_str_new(s->mrb, p, len)); + mrb_int len = nint(tree->cdr); + int off = new_lit_str(s, p, len); int sym; genop_1(s, OP_LOADSELF, cursp()); @@ -3320,7 +3454,6 @@ codegen(codegen_scope *s, node *tree, int val) sym = new_sym(s, MRB_OPSYM_2(s->mrb, tick)); /* ` */ genop_3(s, OP_SEND, cursp(), sym, 1); if (val) push(); - mrb_gc_arena_restore(s->mrb, ai); } break; @@ -3329,9 +3462,8 @@ codegen(codegen_scope *s, node *tree, int val) char *p1 = (char*)tree->car; char *p2 = (char*)tree->cdr->car; char *p3 = (char*)tree->cdr->cdr; - int ai = mrb_gc_arena_save(s->mrb); int sym = new_sym(s, mrb_intern_lit(s->mrb, REGEXP_CLASS)); - int off = new_lit(s, mrb_str_new_cstr(s->mrb, p1)); + int off = new_lit_cstr(s, p1); int argc = 1; genop_1(s, OP_OCLASS, cursp()); @@ -3341,7 +3473,7 @@ codegen(codegen_scope *s, node *tree, int val) push(); if (p2 || p3) { if (p2) { /* opt */ - off = new_lit(s, mrb_str_new_cstr(s->mrb, p2)); + off = new_lit_cstr(s, p2); genop_2(s, OP_STRING, cursp(), off); } else { @@ -3350,7 +3482,7 @@ codegen(codegen_scope *s, node *tree, int val) push(); argc++; if (p3) { /* enc */ - off = new_lit(s, mrb_str_new(s->mrb, p3, 1)); + off = new_lit_str(s, p3, 1); genop_2(s, OP_STRING, cursp(), off); push(); argc++; @@ -3360,7 +3492,6 @@ codegen(codegen_scope *s, node *tree, int val) pop_n(argc+2); sym = new_sym(s, MRB_SYM_2(s->mrb, compile)); genop_3(s, OP_SEND, cursp(), sym, argc); - mrb_gc_arena_restore(s->mrb, ai); push(); } break; @@ -3368,7 +3499,6 @@ codegen(codegen_scope *s, node *tree, int val) case NODE_DREGX: if (val) { node *n = tree->car; - int ai = mrb_gc_arena_save(s->mrb); int sym = new_sym(s, mrb_intern_lit(s->mrb, REGEXP_CLASS)); int argc = 1; int off; @@ -3389,7 +3519,7 @@ codegen(codegen_scope *s, node *tree, int val) n = tree->cdr->cdr; if (n->car) { /* tail */ p = (char*)n->car; - off = new_lit(s, mrb_str_new_cstr(s->mrb, p)); + off = new_lit_cstr(s, p); codegen(s, tree->car, VAL); genop_2(s, OP_STRING, cursp(), off); pop(); @@ -3398,14 +3528,14 @@ codegen(codegen_scope *s, node *tree, int val) } if (n->cdr->car) { /* opt */ char *p2 = (char*)n->cdr->car; - off = new_lit(s, mrb_str_new_cstr(s->mrb, p2)); + off = new_lit_cstr(s, p2); genop_2(s, OP_STRING, cursp(), off); push(); argc++; } if (n->cdr->cdr) { /* enc */ char *p2 = (char*)n->cdr->cdr; - off = new_lit(s, mrb_str_new_cstr(s->mrb, p2)); + off = new_lit_cstr(s, p2); genop_2(s, OP_STRING, cursp(), off); push(); argc++; @@ -3414,7 +3544,6 @@ codegen(codegen_scope *s, node *tree, int val) pop_n(argc+2); sym = new_sym(s, MRB_SYM_2(s->mrb, compile)); genop_3(s, OP_SEND, cursp(), sym, argc); - mrb_gc_arena_restore(s->mrb, ai); push(); } else { diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y index 98b7cffbc..032673b9b 100644 --- a/mrbgems/mruby-compiler/core/parse.y +++ b/mrbgems/mruby-compiler/core/parse.y @@ -21,6 +21,7 @@ #include #include #include +#include #include #include "node.h" @@ -994,13 +995,13 @@ static node* new_imaginary(parser_state *p, node *imaginary) { return new_call(p, new_const(p, MRB_SYM_2(p->mrb, Kernel)), MRB_SYM_2(p->mrb, Complex), - new_callargs(p, list2(list3((node*)NODE_INT, (node*)strdup("0"), nint(10)), imaginary), 0, 0), 1); + new_callargs(p, list2(list3((node*)NODE_INT, (node*)strdup("0"), nint(10)), imaginary), 0, 0), '.'); } static node* new_rational(parser_state *p, node *rational) { - return new_call(p, new_const(p, MRB_SYM_2(p->mrb, Kernel)), MRB_SYM_2(p->mrb, Rational), new_callargs(p, list1(rational), 0, 0), 1); + return new_call(p, new_const(p, MRB_SYM_2(p->mrb, Kernel)), MRB_SYM_2(p->mrb, Rational), new_callargs(p, list1(rational), 0, 0), '.'); } /* (:int . i) */ @@ -1216,14 +1217,14 @@ static node* call_uni_op(parser_state *p, node *recv, const char *m) { void_expr_error(p, recv); - return new_call(p, recv, intern_cstr(m), 0, 1); + return new_call(p, recv, intern_cstr(m), 0, '.'); } /* (:call a op b) */ static node* call_bin_op(parser_state *p, node *recv, const char *m, node *arg1) { - return new_call(p, recv, intern_cstr(m), new_callargs(p, list1(arg1), 0, 0), 1); + return new_call(p, recv, intern_cstr(m), new_callargs(p, list1(arg1), 0, 0), '.'); } static void @@ -6933,7 +6934,7 @@ mrb_load_detect_file_cxt(mrb_state *mrb, FILE *fp, mrbc_context *c) return mrb_load_exec(mrb, mrb_parse_file_continue(mrb, fp, leading.b, bufsize, c), c); } else { - size_t binsize; + mrb_int binsize; uint8_t *bin; mrb_value bin_obj = mrb_nil_value(); /* temporary string object */ mrb_value result; @@ -6941,11 +6942,12 @@ mrb_load_detect_file_cxt(mrb_state *mrb, FILE *fp, mrbc_context *c) binsize = bin_to_uint32(leading.h.binary_size); bin_obj = mrb_str_new(mrb, NULL, binsize); bin = (uint8_t *)RSTRING_PTR(bin_obj); - memcpy(bin, leading.b, bufsize); - if (binsize > bufsize && - fread(bin + bufsize, binsize - bufsize, 1, fp) == 0) { - binsize = bufsize; - /* The error is reported by mrb_load_irep_buf_cxt() */ + if ((size_t)binsize > bufsize) { + memcpy(bin, leading.b, bufsize); + if (fread(bin + bufsize, binsize - bufsize, 1, fp) == 0) { + binsize = bufsize; + /* The error is reported by mrb_load_irep_buf_cxt() */ + } } result = mrb_load_irep_buf_cxt(mrb, bin, binsize, c); @@ -7417,12 +7419,10 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) } } n2 = n2->cdr; - if (n2) { - if (n2->car) { - dump_prefix(n2, offset+2); - printf("post:\n"); - dump_recur(mrb, n2->car, offset+3); - } + if (n2 && n2->car) { + dump_prefix(n2, offset+2); + printf("post:\n"); + dump_recur(mrb, n2->car, offset+3); } } } diff --git a/mrbgems/mruby-compiler/core/y.tab.c b/mrbgems/mruby-compiler/core/y.tab.c index 6c86c0ae3..cfbb3032c 100644 --- a/mrbgems/mruby-compiler/core/y.tab.c +++ b/mrbgems/mruby-compiler/core/y.tab.c @@ -84,6 +84,7 @@ #include #include #include +#include #include #include "node.h" @@ -1057,13 +1058,13 @@ static node* new_imaginary(parser_state *p, node *imaginary) { return new_call(p, new_const(p, MRB_SYM_2(p->mrb, Kernel)), MRB_SYM_2(p->mrb, Complex), - new_callargs(p, list2(list3((node*)NODE_INT, (node*)strdup("0"), nint(10)), imaginary), 0, 0), 1); + new_callargs(p, list2(list3((node*)NODE_INT, (node*)strdup("0"), nint(10)), imaginary), 0, 0), '.'); } static node* new_rational(parser_state *p, node *rational) { - return new_call(p, new_const(p, MRB_SYM_2(p->mrb, Kernel)), MRB_SYM_2(p->mrb, Rational), new_callargs(p, list1(rational), 0, 0), 1); + return new_call(p, new_const(p, MRB_SYM_2(p->mrb, Kernel)), MRB_SYM_2(p->mrb, Rational), new_callargs(p, list1(rational), 0, 0), '.'); } /* (:int . i) */ @@ -1279,14 +1280,14 @@ static node* call_uni_op(parser_state *p, node *recv, const char *m) { void_expr_error(p, recv); - return new_call(p, recv, intern_cstr(m), 0, 1); + return new_call(p, recv, intern_cstr(m), 0, '.'); } /* (:call a op b) */ static node* call_bin_op(parser_state *p, node *recv, const char *m, node *arg1) { - return new_call(p, recv, intern_cstr(m), new_callargs(p, list1(arg1), 0, 0), 1); + return new_call(p, recv, intern_cstr(m), new_callargs(p, list1(arg1), 0, 0), '.'); } static void @@ -1497,7 +1498,7 @@ heredoc_end(parser_state *p) /* xxx ----------------------------- */ -#line 1501 "mrbgems/mruby-compiler/core/y.tab.c" +#line 1502 "mrbgems/mruby-compiler/core/y.tab.c" # ifndef YY_CAST # ifdef __cplusplus @@ -1669,7 +1670,7 @@ extern int yydebug; #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { -#line 1443 "mrbgems/mruby-compiler/core/parse.y" +#line 1444 "mrbgems/mruby-compiler/core/parse.y" node *nd; mrb_sym id; @@ -1677,7 +1678,7 @@ union YYSTYPE stack_type stack; const struct vtable *vars; -#line 1681 "mrbgems/mruby-compiler/core/y.tab.c" +#line 1682 "mrbgems/mruby-compiler/core/y.tab.c" }; typedef union YYSTYPE YYSTYPE; @@ -2063,68 +2064,68 @@ static const yytype_uint8 yytranslate[] = /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int16 yyrline[] = { - 0, 1614, 1614, 1614, 1625, 1631, 1635, 1640, 1644, 1650, - 1652, 1651, 1665, 1692, 1698, 1702, 1707, 1711, 1717, 1717, - 1721, 1725, 1729, 1733, 1737, 1741, 1745, 1750, 1751, 1755, - 1759, 1763, 1767, 1773, 1776, 1780, 1784, 1788, 1792, 1796, - 1801, 1805, 1814, 1823, 1832, 1841, 1848, 1849, 1853, 1857, - 1858, 1862, 1866, 1870, 1874, 1878, 1888, 1887, 1902, 1911, - 1912, 1915, 1916, 1923, 1922, 1937, 1941, 1946, 1950, 1955, - 1959, 1964, 1968, 1972, 1976, 1980, 1986, 1990, 1996, 1997, - 2003, 2007, 2011, 2015, 2019, 2023, 2027, 2031, 2035, 2039, - 2045, 2046, 2052, 2056, 2062, 2066, 2072, 2076, 2080, 2084, - 2088, 2092, 2098, 2104, 2111, 2115, 2119, 2123, 2127, 2131, - 2137, 2143, 2148, 2154, 2158, 2161, 2165, 2169, 2176, 2177, - 2178, 2179, 2184, 2191, 2192, 2195, 2199, 2199, 2205, 2206, - 2207, 2208, 2209, 2210, 2211, 2212, 2213, 2214, 2215, 2216, - 2217, 2218, 2219, 2220, 2221, 2222, 2223, 2224, 2225, 2226, - 2227, 2228, 2229, 2230, 2231, 2232, 2233, 2234, 2237, 2237, - 2237, 2238, 2238, 2239, 2239, 2239, 2240, 2240, 2240, 2240, - 2241, 2241, 2241, 2242, 2242, 2242, 2243, 2243, 2243, 2243, - 2244, 2244, 2244, 2244, 2245, 2245, 2245, 2245, 2246, 2246, - 2246, 2246, 2247, 2247, 2247, 2247, 2248, 2248, 2251, 2255, - 2259, 2263, 2267, 2271, 2275, 2280, 2285, 2290, 2294, 2298, - 2302, 2306, 2310, 2314, 2318, 2322, 2326, 2330, 2334, 2338, - 2342, 2346, 2350, 2354, 2358, 2362, 2366, 2370, 2374, 2378, - 2382, 2386, 2390, 2394, 2398, 2402, 2406, 2410, 2414, 2418, - 2422, 2426, 2430, 2434, 2438, 2447, 2456, 2465, 2474, 2480, - 2481, 2486, 2490, 2497, 2501, 2508, 2512, 2521, 2538, 2539, - 2542, 2543, 2544, 2549, 2554, 2561, 2567, 2572, 2577, 2582, - 2589, 2589, 2600, 2604, 2610, 2614, 2620, 2623, 2629, 2634, - 2639, 2645, 2650, 2654, 2660, 2661, 2662, 2663, 2664, 2665, - 2666, 2667, 2671, 2676, 2675, 2687, 2691, 2686, 2696, 2696, - 2700, 2704, 2708, 2712, 2717, 2722, 2726, 2730, 2734, 2738, - 2742, 2743, 2749, 2756, 2748, 2769, 2777, 2785, 2785, 2785, - 2792, 2792, 2792, 2799, 2805, 2810, 2812, 2809, 2821, 2819, - 2837, 2842, 2835, 2859, 2857, 2873, 2883, 2894, 2898, 2902, - 2906, 2912, 2919, 2920, 2921, 2924, 2925, 2928, 2929, 2937, - 2938, 2944, 2948, 2951, 2955, 2959, 2963, 2968, 2972, 2976, - 2980, 2986, 2985, 2995, 2999, 3003, 3007, 3013, 3018, 3023, - 3027, 3031, 3035, 3039, 3043, 3047, 3051, 3055, 3059, 3063, - 3067, 3071, 3075, 3079, 3085, 3090, 3097, 3097, 3101, 3106, - 3113, 3117, 3123, 3124, 3127, 3132, 3135, 3139, 3145, 3149, - 3156, 3155, 3170, 3180, 3184, 3189, 3196, 3200, 3204, 3208, - 3212, 3216, 3220, 3224, 3228, 3235, 3234, 3249, 3248, 3264, - 3272, 3281, 3284, 3291, 3294, 3298, 3299, 3302, 3306, 3309, - 3313, 3316, 3317, 3318, 3319, 3322, 3323, 3329, 3330, 3331, - 3335, 3348, 3349, 3355, 3360, 3359, 3370, 3374, 3380, 3384, - 3397, 3401, 3407, 3410, 3411, 3414, 3420, 3426, 3427, 3430, - 3437, 3436, 3450, 3454, 3468, 3473, 3487, 3493, 3494, 3495, - 3496, 3497, 3501, 3507, 3511, 3521, 3522, 3523, 3527, 3533, - 3537, 3541, 3545, 3549, 3555, 3559, 3565, 3569, 3573, 3577, - 3581, 3585, 3593, 3600, 3606, 3607, 3611, 3615, 3614, 3631, - 3632, 3635, 3641, 3645, 3651, 3652, 3656, 3660, 3666, 3672, - 3678, 3685, 3691, 3698, 3702, 3708, 3712, 3718, 3719, 3722, - 3726, 3732, 3736, 3740, 3744, 3750, 3755, 3760, 3764, 3768, - 3772, 3776, 3780, 3784, 3788, 3792, 3796, 3800, 3804, 3808, - 3812, 3817, 3823, 3828, 3833, 3838, 3843, 3850, 3854, 3861, - 3866, 3865, 3877, 3881, 3887, 3895, 3903, 3911, 3915, 3921, - 3925, 3931, 3932, 3935, 3940, 3947, 3948, 3951, 3955, 3961, - 3965, 3971, 3976, 3976, 4001, 4002, 4008, 4013, 4019, 4025, - 4030, 4034, 4044, 4051, 4052, 4053, 4056, 4057, 4058, 4059, - 4062, 4063, 4064, 4067, 4068, 4071, 4075, 4081, 4082, 4088, - 4089, 4092, 4093, 4096, 4099, 4100, 4101, 4104, 4105, 4108, - 4113, 4116, 4117, 4121 + 0, 1615, 1615, 1615, 1626, 1632, 1636, 1641, 1645, 1651, + 1653, 1652, 1666, 1693, 1699, 1703, 1708, 1712, 1718, 1718, + 1722, 1726, 1730, 1734, 1738, 1742, 1746, 1751, 1752, 1756, + 1760, 1764, 1768, 1774, 1777, 1781, 1785, 1789, 1793, 1797, + 1802, 1806, 1815, 1824, 1833, 1842, 1849, 1850, 1854, 1858, + 1859, 1863, 1867, 1871, 1875, 1879, 1889, 1888, 1903, 1912, + 1913, 1916, 1917, 1924, 1923, 1938, 1942, 1947, 1951, 1956, + 1960, 1965, 1969, 1973, 1977, 1981, 1987, 1991, 1997, 1998, + 2004, 2008, 2012, 2016, 2020, 2024, 2028, 2032, 2036, 2040, + 2046, 2047, 2053, 2057, 2063, 2067, 2073, 2077, 2081, 2085, + 2089, 2093, 2099, 2105, 2112, 2116, 2120, 2124, 2128, 2132, + 2138, 2144, 2149, 2155, 2159, 2162, 2166, 2170, 2177, 2178, + 2179, 2180, 2185, 2192, 2193, 2196, 2200, 2200, 2206, 2207, + 2208, 2209, 2210, 2211, 2212, 2213, 2214, 2215, 2216, 2217, + 2218, 2219, 2220, 2221, 2222, 2223, 2224, 2225, 2226, 2227, + 2228, 2229, 2230, 2231, 2232, 2233, 2234, 2235, 2238, 2238, + 2238, 2239, 2239, 2240, 2240, 2240, 2241, 2241, 2241, 2241, + 2242, 2242, 2242, 2243, 2243, 2243, 2244, 2244, 2244, 2244, + 2245, 2245, 2245, 2245, 2246, 2246, 2246, 2246, 2247, 2247, + 2247, 2247, 2248, 2248, 2248, 2248, 2249, 2249, 2252, 2256, + 2260, 2264, 2268, 2272, 2276, 2281, 2286, 2291, 2295, 2299, + 2303, 2307, 2311, 2315, 2319, 2323, 2327, 2331, 2335, 2339, + 2343, 2347, 2351, 2355, 2359, 2363, 2367, 2371, 2375, 2379, + 2383, 2387, 2391, 2395, 2399, 2403, 2407, 2411, 2415, 2419, + 2423, 2427, 2431, 2435, 2439, 2448, 2457, 2466, 2475, 2481, + 2482, 2487, 2491, 2498, 2502, 2509, 2513, 2522, 2539, 2540, + 2543, 2544, 2545, 2550, 2555, 2562, 2568, 2573, 2578, 2583, + 2590, 2590, 2601, 2605, 2611, 2615, 2621, 2624, 2630, 2635, + 2640, 2646, 2651, 2655, 2661, 2662, 2663, 2664, 2665, 2666, + 2667, 2668, 2672, 2677, 2676, 2688, 2692, 2687, 2697, 2697, + 2701, 2705, 2709, 2713, 2718, 2723, 2727, 2731, 2735, 2739, + 2743, 2744, 2750, 2757, 2749, 2770, 2778, 2786, 2786, 2786, + 2793, 2793, 2793, 2800, 2806, 2811, 2813, 2810, 2822, 2820, + 2838, 2843, 2836, 2860, 2858, 2874, 2884, 2895, 2899, 2903, + 2907, 2913, 2920, 2921, 2922, 2925, 2926, 2929, 2930, 2938, + 2939, 2945, 2949, 2952, 2956, 2960, 2964, 2969, 2973, 2977, + 2981, 2987, 2986, 2996, 3000, 3004, 3008, 3014, 3019, 3024, + 3028, 3032, 3036, 3040, 3044, 3048, 3052, 3056, 3060, 3064, + 3068, 3072, 3076, 3080, 3086, 3091, 3098, 3098, 3102, 3107, + 3114, 3118, 3124, 3125, 3128, 3133, 3136, 3140, 3146, 3150, + 3157, 3156, 3171, 3181, 3185, 3190, 3197, 3201, 3205, 3209, + 3213, 3217, 3221, 3225, 3229, 3236, 3235, 3250, 3249, 3265, + 3273, 3282, 3285, 3292, 3295, 3299, 3300, 3303, 3307, 3310, + 3314, 3317, 3318, 3319, 3320, 3323, 3324, 3330, 3331, 3332, + 3336, 3349, 3350, 3356, 3361, 3360, 3371, 3375, 3381, 3385, + 3398, 3402, 3408, 3411, 3412, 3415, 3421, 3427, 3428, 3431, + 3438, 3437, 3451, 3455, 3469, 3474, 3488, 3494, 3495, 3496, + 3497, 3498, 3502, 3508, 3512, 3522, 3523, 3524, 3528, 3534, + 3538, 3542, 3546, 3550, 3556, 3560, 3566, 3570, 3574, 3578, + 3582, 3586, 3594, 3601, 3607, 3608, 3612, 3616, 3615, 3632, + 3633, 3636, 3642, 3646, 3652, 3653, 3657, 3661, 3667, 3673, + 3679, 3686, 3692, 3699, 3703, 3709, 3713, 3719, 3720, 3723, + 3727, 3733, 3737, 3741, 3745, 3751, 3756, 3761, 3765, 3769, + 3773, 3777, 3781, 3785, 3789, 3793, 3797, 3801, 3805, 3809, + 3813, 3818, 3824, 3829, 3834, 3839, 3844, 3851, 3855, 3862, + 3867, 3866, 3878, 3882, 3888, 3896, 3904, 3912, 3916, 3922, + 3926, 3932, 3933, 3936, 3941, 3948, 3949, 3952, 3956, 3962, + 3966, 3972, 3977, 3977, 4002, 4003, 4009, 4014, 4020, 4026, + 4031, 4035, 4045, 4052, 4053, 4054, 4057, 4058, 4059, 4060, + 4063, 4064, 4065, 4068, 4069, 4072, 4076, 4082, 4083, 4089, + 4090, 4093, 4094, 4097, 4100, 4101, 4102, 4105, 4106, 4109, + 4114, 4117, 4118, 4122 }; #endif @@ -6141,86 +6142,86 @@ yyreduce: switch (yyn) { case 2: -#line 1614 "mrbgems/mruby-compiler/core/parse.y" +#line 1615 "mrbgems/mruby-compiler/core/parse.y" { p->lstate = EXPR_BEG; if (!p->locals) p->locals = cons(0,0); } -#line 6150 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6151 "mrbgems/mruby-compiler/core/y.tab.c" break; case 3: -#line 1619 "mrbgems/mruby-compiler/core/parse.y" +#line 1620 "mrbgems/mruby-compiler/core/parse.y" { p->tree = new_scope(p, (yyvsp[0].nd)); NODE_LINENO(p->tree, (yyvsp[0].nd)); } -#line 6159 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6160 "mrbgems/mruby-compiler/core/y.tab.c" break; case 4: -#line 1626 "mrbgems/mruby-compiler/core/parse.y" +#line 1627 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 6167 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6168 "mrbgems/mruby-compiler/core/y.tab.c" break; case 5: -#line 1632 "mrbgems/mruby-compiler/core/parse.y" +#line 1633 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_begin(p, 0); } -#line 6175 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6176 "mrbgems/mruby-compiler/core/y.tab.c" break; case 6: -#line 1636 "mrbgems/mruby-compiler/core/parse.y" +#line 1637 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_begin(p, (yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 6184 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6185 "mrbgems/mruby-compiler/core/y.tab.c" break; case 7: -#line 1641 "mrbgems/mruby-compiler/core/parse.y" +#line 1642 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), newline_node((yyvsp[0].nd))); } -#line 6192 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6193 "mrbgems/mruby-compiler/core/y.tab.c" break; case 8: -#line 1645 "mrbgems/mruby-compiler/core/parse.y" +#line 1646 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_begin(p, 0); } -#line 6200 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6201 "mrbgems/mruby-compiler/core/y.tab.c" break; case 10: -#line 1652 "mrbgems/mruby-compiler/core/parse.y" +#line 1653 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = local_switch(p); nvars_block(p); } -#line 6209 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6210 "mrbgems/mruby-compiler/core/y.tab.c" break; case 11: -#line 1657 "mrbgems/mruby-compiler/core/parse.y" +#line 1658 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "BEGIN not supported"); local_resume(p, (yyvsp[-3].nd)); nvars_unnest(p); (yyval.nd) = 0; } -#line 6220 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6221 "mrbgems/mruby-compiler/core/y.tab.c" break; case 12: -#line 1669 "mrbgems/mruby-compiler/core/parse.y" +#line 1670 "mrbgems/mruby-compiler/core/parse.y" { if ((yyvsp[-2].nd)) { (yyval.nd) = new_rescue(p, (yyvsp[-3].nd), (yyvsp[-2].nd), (yyvsp[-1].nd)); @@ -6242,222 +6243,222 @@ yyreduce: } } } -#line 6246 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6247 "mrbgems/mruby-compiler/core/y.tab.c" break; case 13: -#line 1693 "mrbgems/mruby-compiler/core/parse.y" +#line 1694 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 6254 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6255 "mrbgems/mruby-compiler/core/y.tab.c" break; case 14: -#line 1699 "mrbgems/mruby-compiler/core/parse.y" +#line 1700 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_begin(p, 0); } -#line 6262 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6263 "mrbgems/mruby-compiler/core/y.tab.c" break; case 15: -#line 1703 "mrbgems/mruby-compiler/core/parse.y" +#line 1704 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_begin(p, (yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 6271 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6272 "mrbgems/mruby-compiler/core/y.tab.c" break; case 16: -#line 1708 "mrbgems/mruby-compiler/core/parse.y" +#line 1709 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), newline_node((yyvsp[0].nd))); } -#line 6279 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6280 "mrbgems/mruby-compiler/core/y.tab.c" break; case 17: -#line 1712 "mrbgems/mruby-compiler/core/parse.y" +#line 1713 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_begin(p, (yyvsp[0].nd)); } -#line 6287 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6288 "mrbgems/mruby-compiler/core/y.tab.c" break; case 18: -#line 1717 "mrbgems/mruby-compiler/core/parse.y" +#line 1718 "mrbgems/mruby-compiler/core/parse.y" {p->lstate = EXPR_FNAME;} -#line 6293 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6294 "mrbgems/mruby-compiler/core/y.tab.c" break; case 19: -#line 1718 "mrbgems/mruby-compiler/core/parse.y" +#line 1719 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_alias(p, (yyvsp[-2].id), (yyvsp[0].id)); } -#line 6301 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6302 "mrbgems/mruby-compiler/core/y.tab.c" break; case 20: -#line 1722 "mrbgems/mruby-compiler/core/parse.y" +#line 1723 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 6309 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6310 "mrbgems/mruby-compiler/core/y.tab.c" break; case 21: -#line 1726 "mrbgems/mruby-compiler/core/parse.y" +#line 1727 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_if(p, cond((yyvsp[0].nd)), (yyvsp[-2].nd), 0); } -#line 6317 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6318 "mrbgems/mruby-compiler/core/y.tab.c" break; case 22: -#line 1730 "mrbgems/mruby-compiler/core/parse.y" +#line 1731 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_unless(p, cond((yyvsp[0].nd)), (yyvsp[-2].nd), 0); } -#line 6325 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6326 "mrbgems/mruby-compiler/core/y.tab.c" break; case 23: -#line 1734 "mrbgems/mruby-compiler/core/parse.y" +#line 1735 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_while(p, cond((yyvsp[0].nd)), (yyvsp[-2].nd)); } -#line 6333 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6334 "mrbgems/mruby-compiler/core/y.tab.c" break; case 24: -#line 1738 "mrbgems/mruby-compiler/core/parse.y" +#line 1739 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_until(p, cond((yyvsp[0].nd)), (yyvsp[-2].nd)); } -#line 6341 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6342 "mrbgems/mruby-compiler/core/y.tab.c" break; case 25: -#line 1742 "mrbgems/mruby-compiler/core/parse.y" +#line 1743 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_mod_rescue(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6349 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6350 "mrbgems/mruby-compiler/core/y.tab.c" break; case 26: -#line 1746 "mrbgems/mruby-compiler/core/parse.y" +#line 1747 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "END not supported"); (yyval.nd) = new_postexe(p, (yyvsp[-1].nd)); } -#line 6358 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6359 "mrbgems/mruby-compiler/core/y.tab.c" break; case 28: -#line 1752 "mrbgems/mruby-compiler/core/parse.y" +#line 1753 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_masgn(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6366 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6367 "mrbgems/mruby-compiler/core/y.tab.c" break; case 29: -#line 1756 "mrbgems/mruby-compiler/core/parse.y" +#line 1757 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_asgn(p, (yyvsp[-2].nd), new_array(p, (yyvsp[0].nd))); } -#line 6374 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6375 "mrbgems/mruby-compiler/core/y.tab.c" break; case 30: -#line 1760 "mrbgems/mruby-compiler/core/parse.y" +#line 1761 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_masgn(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6382 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6383 "mrbgems/mruby-compiler/core/y.tab.c" break; case 31: -#line 1764 "mrbgems/mruby-compiler/core/parse.y" +#line 1765 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_masgn(p, (yyvsp[-2].nd), new_array(p, (yyvsp[0].nd))); } -#line 6390 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6391 "mrbgems/mruby-compiler/core/y.tab.c" break; case 32: -#line 1768 "mrbgems/mruby-compiler/core/parse.y" +#line 1769 "mrbgems/mruby-compiler/core/parse.y" { node *lhs = new_lvar(p, (yyvsp[0].id)); assignable(p, lhs); (yyval.nd) = new_asgn(p, lhs, (yyvsp[-2].nd)); } -#line 6400 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6401 "mrbgems/mruby-compiler/core/y.tab.c" break; case 34: -#line 1777 "mrbgems/mruby-compiler/core/parse.y" +#line 1778 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_asgn(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6408 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6409 "mrbgems/mruby-compiler/core/y.tab.c" break; case 35: -#line 1781 "mrbgems/mruby-compiler/core/parse.y" +#line 1782 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_op_asgn(p, (yyvsp[-2].nd), (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 6416 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6417 "mrbgems/mruby-compiler/core/y.tab.c" break; case 36: -#line 1785 "mrbgems/mruby-compiler/core/parse.y" +#line 1786 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_op_asgn(p, new_call(p, (yyvsp[-5].nd), intern_op(aref), (yyvsp[-3].nd), '.'), (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 6424 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6425 "mrbgems/mruby-compiler/core/y.tab.c" break; case 37: -#line 1789 "mrbgems/mruby-compiler/core/parse.y" +#line 1790 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_op_asgn(p, new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), 0, (yyvsp[-3].num)), (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 6432 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6433 "mrbgems/mruby-compiler/core/y.tab.c" break; case 38: -#line 1793 "mrbgems/mruby-compiler/core/parse.y" +#line 1794 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_op_asgn(p, new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), 0, (yyvsp[-3].num)), (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 6440 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6441 "mrbgems/mruby-compiler/core/y.tab.c" break; case 39: -#line 1797 "mrbgems/mruby-compiler/core/parse.y" +#line 1798 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "constant re-assignment"); (yyval.nd) = 0; } -#line 6449 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6450 "mrbgems/mruby-compiler/core/y.tab.c" break; case 40: -#line 1802 "mrbgems/mruby-compiler/core/parse.y" +#line 1803 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_op_asgn(p, new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), 0, tCOLON2), (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 6457 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6458 "mrbgems/mruby-compiler/core/y.tab.c" break; case 41: -#line 1806 "mrbgems/mruby-compiler/core/parse.y" +#line 1807 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-3].nd); endless_method_name(p, (yyvsp[-3].nd)); @@ -6466,11 +6467,11 @@ yyreduce: nvars_unnest(p); p->in_def--; } -#line 6470 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6471 "mrbgems/mruby-compiler/core/y.tab.c" break; case 42: -#line 1815 "mrbgems/mruby-compiler/core/parse.y" +#line 1816 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-5].nd); endless_method_name(p, (yyvsp[-5].nd)); @@ -6479,11 +6480,11 @@ yyreduce: nvars_unnest(p); p->in_def--; } -#line 6483 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6484 "mrbgems/mruby-compiler/core/y.tab.c" break; case 43: -#line 1824 "mrbgems/mruby-compiler/core/parse.y" +#line 1825 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-3].nd); void_expr_error(p, (yyvsp[0].nd)); @@ -6492,11 +6493,11 @@ yyreduce: p->in_def--; p->in_single--; } -#line 6496 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6497 "mrbgems/mruby-compiler/core/y.tab.c" break; case 44: -#line 1833 "mrbgems/mruby-compiler/core/parse.y" +#line 1834 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-5].nd); void_expr_error(p, (yyvsp[-2].nd)); @@ -6505,79 +6506,79 @@ yyreduce: p->in_def--; p->in_single--; } -#line 6509 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6510 "mrbgems/mruby-compiler/core/y.tab.c" break; case 45: -#line 1842 "mrbgems/mruby-compiler/core/parse.y" +#line 1843 "mrbgems/mruby-compiler/core/parse.y" { backref_error(p, (yyvsp[-2].nd)); (yyval.nd) = new_begin(p, 0); } -#line 6518 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6519 "mrbgems/mruby-compiler/core/y.tab.c" break; case 47: -#line 1850 "mrbgems/mruby-compiler/core/parse.y" +#line 1851 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_mod_rescue(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6526 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6527 "mrbgems/mruby-compiler/core/y.tab.c" break; case 50: -#line 1859 "mrbgems/mruby-compiler/core/parse.y" +#line 1860 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_and(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6534 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6535 "mrbgems/mruby-compiler/core/y.tab.c" break; case 51: -#line 1863 "mrbgems/mruby-compiler/core/parse.y" +#line 1864 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_or(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6542 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6543 "mrbgems/mruby-compiler/core/y.tab.c" break; case 52: -#line 1867 "mrbgems/mruby-compiler/core/parse.y" +#line 1868 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_uni_op(p, cond((yyvsp[0].nd)), "!"); } -#line 6550 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6551 "mrbgems/mruby-compiler/core/y.tab.c" break; case 53: -#line 1871 "mrbgems/mruby-compiler/core/parse.y" +#line 1872 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_uni_op(p, cond((yyvsp[0].nd)), "!"); } -#line 6558 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6559 "mrbgems/mruby-compiler/core/y.tab.c" break; case 55: -#line 1879 "mrbgems/mruby-compiler/core/parse.y" +#line 1880 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_def(p, (yyvsp[0].id), nint(p->cmdarg_stack), local_switch(p)); p->cmdarg_stack = 0; p->in_def++; nvars_block(p); } -#line 6569 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6570 "mrbgems/mruby-compiler/core/y.tab.c" break; case 56: -#line 1888 "mrbgems/mruby-compiler/core/parse.y" +#line 1889 "mrbgems/mruby-compiler/core/parse.y" { p->lstate = EXPR_FNAME; } -#line 6577 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6578 "mrbgems/mruby-compiler/core/y.tab.c" break; case 57: -#line 1892 "mrbgems/mruby-compiler/core/parse.y" +#line 1893 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_sdef(p, (yyvsp[-3].nd), (yyvsp[0].id), nint(p->cmdarg_stack), local_switch(p)); p->cmdarg_stack = 0; @@ -6586,1054 +6587,1054 @@ yyreduce: nvars_block(p); p->lstate = EXPR_ENDFN; /* force for args */ } -#line 6590 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6591 "mrbgems/mruby-compiler/core/y.tab.c" break; case 58: -#line 1903 "mrbgems/mruby-compiler/core/parse.y" +#line 1904 "mrbgems/mruby-compiler/core/parse.y" { if (!(yyvsp[0].nd)) (yyval.nd) = new_nil(p); else { (yyval.nd) = (yyvsp[0].nd); } } -#line 6601 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6602 "mrbgems/mruby-compiler/core/y.tab.c" break; case 62: -#line 1917 "mrbgems/mruby-compiler/core/parse.y" +#line 1918 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), (yyvsp[-2].num)); } -#line 6609 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6610 "mrbgems/mruby-compiler/core/y.tab.c" break; case 63: -#line 1923 "mrbgems/mruby-compiler/core/parse.y" +#line 1924 "mrbgems/mruby-compiler/core/parse.y" { local_nest(p); nvars_nest(p); } -#line 6618 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6619 "mrbgems/mruby-compiler/core/y.tab.c" break; case 64: -#line 1930 "mrbgems/mruby-compiler/core/parse.y" +#line 1931 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_block(p, (yyvsp[-2].nd), (yyvsp[-1].nd)); local_unnest(p); nvars_unnest(p); } -#line 6628 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6629 "mrbgems/mruby-compiler/core/y.tab.c" break; case 65: -#line 1938 "mrbgems/mruby-compiler/core/parse.y" +#line 1939 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_fcall(p, (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 6636 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6637 "mrbgems/mruby-compiler/core/y.tab.c" break; case 66: -#line 1942 "mrbgems/mruby-compiler/core/parse.y" +#line 1943 "mrbgems/mruby-compiler/core/parse.y" { args_with_block(p, (yyvsp[-1].nd), (yyvsp[0].nd)); (yyval.nd) = new_fcall(p, (yyvsp[-2].id), (yyvsp[-1].nd)); } -#line 6645 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6646 "mrbgems/mruby-compiler/core/y.tab.c" break; case 67: -#line 1947 "mrbgems/mruby-compiler/core/parse.y" +#line 1948 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), (yyvsp[-2].num)); } -#line 6653 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6654 "mrbgems/mruby-compiler/core/y.tab.c" break; case 68: -#line 1951 "mrbgems/mruby-compiler/core/parse.y" +#line 1952 "mrbgems/mruby-compiler/core/parse.y" { args_with_block(p, (yyvsp[-1].nd), (yyvsp[0].nd)); (yyval.nd) = new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), (yyvsp[-1].nd), (yyvsp[-3].num)); } -#line 6662 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6663 "mrbgems/mruby-compiler/core/y.tab.c" break; case 69: -#line 1956 "mrbgems/mruby-compiler/core/parse.y" +#line 1957 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), tCOLON2); } -#line 6670 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6671 "mrbgems/mruby-compiler/core/y.tab.c" break; case 70: -#line 1960 "mrbgems/mruby-compiler/core/parse.y" +#line 1961 "mrbgems/mruby-compiler/core/parse.y" { args_with_block(p, (yyvsp[-1].nd), (yyvsp[0].nd)); (yyval.nd) = new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), (yyvsp[-1].nd), tCOLON2); } -#line 6679 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6680 "mrbgems/mruby-compiler/core/y.tab.c" break; case 71: -#line 1965 "mrbgems/mruby-compiler/core/parse.y" +#line 1966 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_super(p, (yyvsp[0].nd)); } -#line 6687 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6688 "mrbgems/mruby-compiler/core/y.tab.c" break; case 72: -#line 1969 "mrbgems/mruby-compiler/core/parse.y" +#line 1970 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_yield(p, (yyvsp[0].nd)); } -#line 6695 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6696 "mrbgems/mruby-compiler/core/y.tab.c" break; case 73: -#line 1973 "mrbgems/mruby-compiler/core/parse.y" +#line 1974 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_return(p, ret_args(p, (yyvsp[0].nd))); } -#line 6703 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6704 "mrbgems/mruby-compiler/core/y.tab.c" break; case 74: -#line 1977 "mrbgems/mruby-compiler/core/parse.y" +#line 1978 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_break(p, ret_args(p, (yyvsp[0].nd))); } -#line 6711 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6712 "mrbgems/mruby-compiler/core/y.tab.c" break; case 75: -#line 1981 "mrbgems/mruby-compiler/core/parse.y" +#line 1982 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_next(p, ret_args(p, (yyvsp[0].nd))); } -#line 6719 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6720 "mrbgems/mruby-compiler/core/y.tab.c" break; case 76: -#line 1987 "mrbgems/mruby-compiler/core/parse.y" +#line 1988 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 6727 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6728 "mrbgems/mruby-compiler/core/y.tab.c" break; case 77: -#line 1991 "mrbgems/mruby-compiler/core/parse.y" +#line 1992 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 6735 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6736 "mrbgems/mruby-compiler/core/y.tab.c" break; case 79: -#line 1998 "mrbgems/mruby-compiler/core/parse.y" +#line 1999 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 6743 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6744 "mrbgems/mruby-compiler/core/y.tab.c" break; case 80: -#line 2004 "mrbgems/mruby-compiler/core/parse.y" +#line 2005 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 6751 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6752 "mrbgems/mruby-compiler/core/y.tab.c" break; case 81: -#line 2008 "mrbgems/mruby-compiler/core/parse.y" +#line 2009 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1(push((yyvsp[-1].nd),(yyvsp[0].nd))); } -#line 6759 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6760 "mrbgems/mruby-compiler/core/y.tab.c" break; case 82: -#line 2012 "mrbgems/mruby-compiler/core/parse.y" +#line 2013 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list2((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6767 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6768 "mrbgems/mruby-compiler/core/y.tab.c" break; case 83: -#line 2016 "mrbgems/mruby-compiler/core/parse.y" +#line 2017 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3((yyvsp[-4].nd), (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6775 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6776 "mrbgems/mruby-compiler/core/y.tab.c" break; case 84: -#line 2020 "mrbgems/mruby-compiler/core/parse.y" +#line 2021 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list2((yyvsp[-1].nd), new_nil(p)); } -#line 6783 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6784 "mrbgems/mruby-compiler/core/y.tab.c" break; case 85: -#line 2024 "mrbgems/mruby-compiler/core/parse.y" +#line 2025 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3((yyvsp[-3].nd), new_nil(p), (yyvsp[0].nd)); } -#line 6791 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6792 "mrbgems/mruby-compiler/core/y.tab.c" break; case 86: -#line 2028 "mrbgems/mruby-compiler/core/parse.y" +#line 2029 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list2(0, (yyvsp[0].nd)); } -#line 6799 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6800 "mrbgems/mruby-compiler/core/y.tab.c" break; case 87: -#line 2032 "mrbgems/mruby-compiler/core/parse.y" +#line 2033 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3(0, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6807 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6808 "mrbgems/mruby-compiler/core/y.tab.c" break; case 88: -#line 2036 "mrbgems/mruby-compiler/core/parse.y" +#line 2037 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list2(0, new_nil(p)); } -#line 6815 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6816 "mrbgems/mruby-compiler/core/y.tab.c" break; case 89: -#line 2040 "mrbgems/mruby-compiler/core/parse.y" +#line 2041 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3(0, new_nil(p), (yyvsp[0].nd)); } -#line 6823 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6824 "mrbgems/mruby-compiler/core/y.tab.c" break; case 91: -#line 2047 "mrbgems/mruby-compiler/core/parse.y" +#line 2048 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_masgn(p, (yyvsp[-1].nd), NULL); } -#line 6831 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6832 "mrbgems/mruby-compiler/core/y.tab.c" break; case 92: -#line 2053 "mrbgems/mruby-compiler/core/parse.y" +#line 2054 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[-1].nd)); } -#line 6839 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6840 "mrbgems/mruby-compiler/core/y.tab.c" break; case 93: -#line 2057 "mrbgems/mruby-compiler/core/parse.y" +#line 2058 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[-1].nd)); } -#line 6847 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6848 "mrbgems/mruby-compiler/core/y.tab.c" break; case 94: -#line 2063 "mrbgems/mruby-compiler/core/parse.y" +#line 2064 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 6855 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6856 "mrbgems/mruby-compiler/core/y.tab.c" break; case 95: -#line 2067 "mrbgems/mruby-compiler/core/parse.y" +#line 2068 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 6863 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6864 "mrbgems/mruby-compiler/core/y.tab.c" break; case 96: -#line 2073 "mrbgems/mruby-compiler/core/parse.y" +#line 2074 "mrbgems/mruby-compiler/core/parse.y" { assignable(p, (yyvsp[0].nd)); } -#line 6871 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6872 "mrbgems/mruby-compiler/core/y.tab.c" break; case 97: -#line 2077 "mrbgems/mruby-compiler/core/parse.y" +#line 2078 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), intern_op(aref), (yyvsp[-1].nd), '.'); } -#line 6879 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6880 "mrbgems/mruby-compiler/core/y.tab.c" break; case 98: -#line 2081 "mrbgems/mruby-compiler/core/parse.y" +#line 2082 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, (yyvsp[-1].num)); } -#line 6887 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6888 "mrbgems/mruby-compiler/core/y.tab.c" break; case 99: -#line 2085 "mrbgems/mruby-compiler/core/parse.y" +#line 2086 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, tCOLON2); } -#line 6895 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6896 "mrbgems/mruby-compiler/core/y.tab.c" break; case 100: -#line 2089 "mrbgems/mruby-compiler/core/parse.y" +#line 2090 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, (yyvsp[-1].num)); } -#line 6903 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6904 "mrbgems/mruby-compiler/core/y.tab.c" break; case 101: -#line 2093 "mrbgems/mruby-compiler/core/parse.y" +#line 2094 "mrbgems/mruby-compiler/core/parse.y" { if (p->in_def || p->in_single) yyerror(p, "dynamic constant assignment"); (yyval.nd) = new_colon2(p, (yyvsp[-2].nd), (yyvsp[0].id)); } -#line 6913 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6914 "mrbgems/mruby-compiler/core/y.tab.c" break; case 102: -#line 2099 "mrbgems/mruby-compiler/core/parse.y" +#line 2100 "mrbgems/mruby-compiler/core/parse.y" { if (p->in_def || p->in_single) yyerror(p, "dynamic constant assignment"); (yyval.nd) = new_colon3(p, (yyvsp[0].id)); } -#line 6923 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6924 "mrbgems/mruby-compiler/core/y.tab.c" break; case 103: -#line 2105 "mrbgems/mruby-compiler/core/parse.y" +#line 2106 "mrbgems/mruby-compiler/core/parse.y" { backref_error(p, (yyvsp[0].nd)); (yyval.nd) = 0; } -#line 6932 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6933 "mrbgems/mruby-compiler/core/y.tab.c" break; case 104: -#line 2112 "mrbgems/mruby-compiler/core/parse.y" +#line 2113 "mrbgems/mruby-compiler/core/parse.y" { assignable(p, (yyvsp[0].nd)); } -#line 6940 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6941 "mrbgems/mruby-compiler/core/y.tab.c" break; case 105: -#line 2116 "mrbgems/mruby-compiler/core/parse.y" +#line 2117 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), intern_op(aref), (yyvsp[-1].nd), '.'); } -#line 6948 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6949 "mrbgems/mruby-compiler/core/y.tab.c" break; case 106: -#line 2120 "mrbgems/mruby-compiler/core/parse.y" +#line 2121 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, (yyvsp[-1].num)); } -#line 6956 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6957 "mrbgems/mruby-compiler/core/y.tab.c" break; case 107: -#line 2124 "mrbgems/mruby-compiler/core/parse.y" +#line 2125 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, tCOLON2); } -#line 6964 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6965 "mrbgems/mruby-compiler/core/y.tab.c" break; case 108: -#line 2128 "mrbgems/mruby-compiler/core/parse.y" +#line 2129 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, (yyvsp[-1].num)); } -#line 6972 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6973 "mrbgems/mruby-compiler/core/y.tab.c" break; case 109: -#line 2132 "mrbgems/mruby-compiler/core/parse.y" +#line 2133 "mrbgems/mruby-compiler/core/parse.y" { if (p->in_def || p->in_single) yyerror(p, "dynamic constant assignment"); (yyval.nd) = new_colon2(p, (yyvsp[-2].nd), (yyvsp[0].id)); } -#line 6982 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6983 "mrbgems/mruby-compiler/core/y.tab.c" break; case 110: -#line 2138 "mrbgems/mruby-compiler/core/parse.y" +#line 2139 "mrbgems/mruby-compiler/core/parse.y" { if (p->in_def || p->in_single) yyerror(p, "dynamic constant assignment"); (yyval.nd) = new_colon3(p, (yyvsp[0].id)); } -#line 6992 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6993 "mrbgems/mruby-compiler/core/y.tab.c" break; case 111: -#line 2144 "mrbgems/mruby-compiler/core/parse.y" +#line 2145 "mrbgems/mruby-compiler/core/parse.y" { backref_error(p, (yyvsp[0].nd)); (yyval.nd) = 0; } -#line 7001 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7002 "mrbgems/mruby-compiler/core/y.tab.c" break; case 112: -#line 2149 "mrbgems/mruby-compiler/core/parse.y" +#line 2150 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "can't assign to numbered parameter"); } -#line 7009 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7010 "mrbgems/mruby-compiler/core/y.tab.c" break; case 113: -#line 2155 "mrbgems/mruby-compiler/core/parse.y" +#line 2156 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "class/module name must be CONSTANT"); } -#line 7017 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7018 "mrbgems/mruby-compiler/core/y.tab.c" break; case 115: -#line 2162 "mrbgems/mruby-compiler/core/parse.y" +#line 2163 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = cons(nint(1), nsym((yyvsp[0].id))); } -#line 7025 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7026 "mrbgems/mruby-compiler/core/y.tab.c" break; case 116: -#line 2166 "mrbgems/mruby-compiler/core/parse.y" +#line 2167 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = cons(nint(0), nsym((yyvsp[0].id))); } -#line 7033 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7034 "mrbgems/mruby-compiler/core/y.tab.c" break; case 117: -#line 2170 "mrbgems/mruby-compiler/core/parse.y" +#line 2171 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[-2].nd)); (yyval.nd) = cons((yyvsp[-2].nd), nsym((yyvsp[0].id))); } -#line 7042 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7043 "mrbgems/mruby-compiler/core/y.tab.c" break; case 121: -#line 2180 "mrbgems/mruby-compiler/core/parse.y" +#line 2181 "mrbgems/mruby-compiler/core/parse.y" { p->lstate = EXPR_ENDFN; (yyval.id) = (yyvsp[0].id); } -#line 7051 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7052 "mrbgems/mruby-compiler/core/y.tab.c" break; case 122: -#line 2185 "mrbgems/mruby-compiler/core/parse.y" +#line 2186 "mrbgems/mruby-compiler/core/parse.y" { p->lstate = EXPR_ENDFN; (yyval.id) = (yyvsp[0].id); } -#line 7060 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7061 "mrbgems/mruby-compiler/core/y.tab.c" break; case 125: -#line 2196 "mrbgems/mruby-compiler/core/parse.y" +#line 2197 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_undef(p, (yyvsp[0].id)); } -#line 7068 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7069 "mrbgems/mruby-compiler/core/y.tab.c" break; case 126: -#line 2199 "mrbgems/mruby-compiler/core/parse.y" +#line 2200 "mrbgems/mruby-compiler/core/parse.y" {p->lstate = EXPR_FNAME;} -#line 7074 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7075 "mrbgems/mruby-compiler/core/y.tab.c" break; case 127: -#line 2200 "mrbgems/mruby-compiler/core/parse.y" +#line 2201 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-3].nd), nsym((yyvsp[0].id))); } -#line 7082 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7083 "mrbgems/mruby-compiler/core/y.tab.c" break; case 128: -#line 2205 "mrbgems/mruby-compiler/core/parse.y" +#line 2206 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(or); } -#line 7088 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7089 "mrbgems/mruby-compiler/core/y.tab.c" break; case 129: -#line 2206 "mrbgems/mruby-compiler/core/parse.y" +#line 2207 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(xor); } -#line 7094 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7095 "mrbgems/mruby-compiler/core/y.tab.c" break; case 130: -#line 2207 "mrbgems/mruby-compiler/core/parse.y" +#line 2208 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(and); } -#line 7100 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7101 "mrbgems/mruby-compiler/core/y.tab.c" break; case 131: -#line 2208 "mrbgems/mruby-compiler/core/parse.y" +#line 2209 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(cmp); } -#line 7106 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7107 "mrbgems/mruby-compiler/core/y.tab.c" break; case 132: -#line 2209 "mrbgems/mruby-compiler/core/parse.y" +#line 2210 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(eq); } -#line 7112 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7113 "mrbgems/mruby-compiler/core/y.tab.c" break; case 133: -#line 2210 "mrbgems/mruby-compiler/core/parse.y" +#line 2211 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(eqq); } -#line 7118 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7119 "mrbgems/mruby-compiler/core/y.tab.c" break; case 134: -#line 2211 "mrbgems/mruby-compiler/core/parse.y" +#line 2212 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(match); } -#line 7124 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7125 "mrbgems/mruby-compiler/core/y.tab.c" break; case 135: -#line 2212 "mrbgems/mruby-compiler/core/parse.y" +#line 2213 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(nmatch); } -#line 7130 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7131 "mrbgems/mruby-compiler/core/y.tab.c" break; case 136: -#line 2213 "mrbgems/mruby-compiler/core/parse.y" +#line 2214 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(gt); } -#line 7136 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7137 "mrbgems/mruby-compiler/core/y.tab.c" break; case 137: -#line 2214 "mrbgems/mruby-compiler/core/parse.y" +#line 2215 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(ge); } -#line 7142 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7143 "mrbgems/mruby-compiler/core/y.tab.c" break; case 138: -#line 2215 "mrbgems/mruby-compiler/core/parse.y" +#line 2216 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(lt); } -#line 7148 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7149 "mrbgems/mruby-compiler/core/y.tab.c" break; case 139: -#line 2216 "mrbgems/mruby-compiler/core/parse.y" +#line 2217 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(le); } -#line 7154 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7155 "mrbgems/mruby-compiler/core/y.tab.c" break; case 140: -#line 2217 "mrbgems/mruby-compiler/core/parse.y" +#line 2218 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(neq); } -#line 7160 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7161 "mrbgems/mruby-compiler/core/y.tab.c" break; case 141: -#line 2218 "mrbgems/mruby-compiler/core/parse.y" +#line 2219 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(lshift); } -#line 7166 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7167 "mrbgems/mruby-compiler/core/y.tab.c" break; case 142: -#line 2219 "mrbgems/mruby-compiler/core/parse.y" +#line 2220 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(rshift); } -#line 7172 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7173 "mrbgems/mruby-compiler/core/y.tab.c" break; case 143: -#line 2220 "mrbgems/mruby-compiler/core/parse.y" +#line 2221 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(add); } -#line 7178 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7179 "mrbgems/mruby-compiler/core/y.tab.c" break; case 144: -#line 2221 "mrbgems/mruby-compiler/core/parse.y" +#line 2222 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(sub); } -#line 7184 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7185 "mrbgems/mruby-compiler/core/y.tab.c" break; case 145: -#line 2222 "mrbgems/mruby-compiler/core/parse.y" +#line 2223 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(mul); } -#line 7190 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7191 "mrbgems/mruby-compiler/core/y.tab.c" break; case 146: -#line 2223 "mrbgems/mruby-compiler/core/parse.y" +#line 2224 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(mul); } -#line 7196 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7197 "mrbgems/mruby-compiler/core/y.tab.c" break; case 147: -#line 2224 "mrbgems/mruby-compiler/core/parse.y" +#line 2225 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(div); } -#line 7202 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7203 "mrbgems/mruby-compiler/core/y.tab.c" break; case 148: -#line 2225 "mrbgems/mruby-compiler/core/parse.y" +#line 2226 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(mod); } -#line 7208 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7209 "mrbgems/mruby-compiler/core/y.tab.c" break; case 149: -#line 2226 "mrbgems/mruby-compiler/core/parse.y" +#line 2227 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(pow); } -#line 7214 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7215 "mrbgems/mruby-compiler/core/y.tab.c" break; case 150: -#line 2227 "mrbgems/mruby-compiler/core/parse.y" +#line 2228 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(pow); } -#line 7220 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7221 "mrbgems/mruby-compiler/core/y.tab.c" break; case 151: -#line 2228 "mrbgems/mruby-compiler/core/parse.y" +#line 2229 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(not); } -#line 7226 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7227 "mrbgems/mruby-compiler/core/y.tab.c" break; case 152: -#line 2229 "mrbgems/mruby-compiler/core/parse.y" +#line 2230 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(neg); } -#line 7232 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7233 "mrbgems/mruby-compiler/core/y.tab.c" break; case 153: -#line 2230 "mrbgems/mruby-compiler/core/parse.y" +#line 2231 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(plus); } -#line 7238 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7239 "mrbgems/mruby-compiler/core/y.tab.c" break; case 154: -#line 2231 "mrbgems/mruby-compiler/core/parse.y" +#line 2232 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(minus); } -#line 7244 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7245 "mrbgems/mruby-compiler/core/y.tab.c" break; case 155: -#line 2232 "mrbgems/mruby-compiler/core/parse.y" +#line 2233 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(aref); } -#line 7250 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7251 "mrbgems/mruby-compiler/core/y.tab.c" break; case 156: -#line 2233 "mrbgems/mruby-compiler/core/parse.y" +#line 2234 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(aset); } -#line 7256 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7257 "mrbgems/mruby-compiler/core/y.tab.c" break; case 157: -#line 2234 "mrbgems/mruby-compiler/core/parse.y" +#line 2235 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(tick); } -#line 7262 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7263 "mrbgems/mruby-compiler/core/y.tab.c" break; case 198: -#line 2252 "mrbgems/mruby-compiler/core/parse.y" +#line 2253 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_asgn(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7270 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7271 "mrbgems/mruby-compiler/core/y.tab.c" break; case 199: -#line 2256 "mrbgems/mruby-compiler/core/parse.y" +#line 2257 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_op_asgn(p, (yyvsp[-2].nd), (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 7278 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7279 "mrbgems/mruby-compiler/core/y.tab.c" break; case 200: -#line 2260 "mrbgems/mruby-compiler/core/parse.y" +#line 2261 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_op_asgn(p, new_call(p, (yyvsp[-5].nd), intern_op(aref), (yyvsp[-3].nd), '.'), (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 7286 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7287 "mrbgems/mruby-compiler/core/y.tab.c" break; case 201: -#line 2264 "mrbgems/mruby-compiler/core/parse.y" +#line 2265 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_op_asgn(p, new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), 0, (yyvsp[-3].num)), (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 7294 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7295 "mrbgems/mruby-compiler/core/y.tab.c" break; case 202: -#line 2268 "mrbgems/mruby-compiler/core/parse.y" +#line 2269 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_op_asgn(p, new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), 0, (yyvsp[-3].num)), (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 7302 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7303 "mrbgems/mruby-compiler/core/y.tab.c" break; case 203: -#line 2272 "mrbgems/mruby-compiler/core/parse.y" +#line 2273 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_op_asgn(p, new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), 0, tCOLON2), (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 7310 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7311 "mrbgems/mruby-compiler/core/y.tab.c" break; case 204: -#line 2276 "mrbgems/mruby-compiler/core/parse.y" +#line 2277 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "constant re-assignment"); (yyval.nd) = new_begin(p, 0); } -#line 7319 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7320 "mrbgems/mruby-compiler/core/y.tab.c" break; case 205: -#line 2281 "mrbgems/mruby-compiler/core/parse.y" +#line 2282 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "constant re-assignment"); (yyval.nd) = new_begin(p, 0); } -#line 7328 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7329 "mrbgems/mruby-compiler/core/y.tab.c" break; case 206: -#line 2286 "mrbgems/mruby-compiler/core/parse.y" +#line 2287 "mrbgems/mruby-compiler/core/parse.y" { backref_error(p, (yyvsp[-2].nd)); (yyval.nd) = new_begin(p, 0); } -#line 7337 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7338 "mrbgems/mruby-compiler/core/y.tab.c" break; case 207: -#line 2291 "mrbgems/mruby-compiler/core/parse.y" +#line 2292 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_dot2(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7345 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7346 "mrbgems/mruby-compiler/core/y.tab.c" break; case 208: -#line 2295 "mrbgems/mruby-compiler/core/parse.y" +#line 2296 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_dot2(p, (yyvsp[-1].nd), new_nil(p)); } -#line 7353 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7354 "mrbgems/mruby-compiler/core/y.tab.c" break; case 209: -#line 2299 "mrbgems/mruby-compiler/core/parse.y" +#line 2300 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_dot2(p, new_nil(p), (yyvsp[0].nd)); } -#line 7361 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7362 "mrbgems/mruby-compiler/core/y.tab.c" break; case 210: -#line 2303 "mrbgems/mruby-compiler/core/parse.y" +#line 2304 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_dot3(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7369 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7370 "mrbgems/mruby-compiler/core/y.tab.c" break; case 211: -#line 2307 "mrbgems/mruby-compiler/core/parse.y" +#line 2308 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_dot3(p, (yyvsp[-1].nd), new_nil(p)); } -#line 7377 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7378 "mrbgems/mruby-compiler/core/y.tab.c" break; case 212: -#line 2311 "mrbgems/mruby-compiler/core/parse.y" +#line 2312 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_dot3(p, new_nil(p), (yyvsp[0].nd)); } -#line 7385 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7386 "mrbgems/mruby-compiler/core/y.tab.c" break; case 213: -#line 2315 "mrbgems/mruby-compiler/core/parse.y" +#line 2316 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "+", (yyvsp[0].nd)); } -#line 7393 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7394 "mrbgems/mruby-compiler/core/y.tab.c" break; case 214: -#line 2319 "mrbgems/mruby-compiler/core/parse.y" +#line 2320 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "-", (yyvsp[0].nd)); } -#line 7401 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7402 "mrbgems/mruby-compiler/core/y.tab.c" break; case 215: -#line 2323 "mrbgems/mruby-compiler/core/parse.y" +#line 2324 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "*", (yyvsp[0].nd)); } -#line 7409 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7410 "mrbgems/mruby-compiler/core/y.tab.c" break; case 216: -#line 2327 "mrbgems/mruby-compiler/core/parse.y" +#line 2328 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "/", (yyvsp[0].nd)); } -#line 7417 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7418 "mrbgems/mruby-compiler/core/y.tab.c" break; case 217: -#line 2331 "mrbgems/mruby-compiler/core/parse.y" +#line 2332 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "%", (yyvsp[0].nd)); } -#line 7425 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7426 "mrbgems/mruby-compiler/core/y.tab.c" break; case 218: -#line 2335 "mrbgems/mruby-compiler/core/parse.y" +#line 2336 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "**", (yyvsp[0].nd)); } -#line 7433 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7434 "mrbgems/mruby-compiler/core/y.tab.c" break; case 219: -#line 2339 "mrbgems/mruby-compiler/core/parse.y" +#line 2340 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_negate(p, call_bin_op(p, (yyvsp[-2].nd), "**", (yyvsp[0].nd))); } -#line 7441 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7442 "mrbgems/mruby-compiler/core/y.tab.c" break; case 220: -#line 2343 "mrbgems/mruby-compiler/core/parse.y" +#line 2344 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_negate(p, call_bin_op(p, (yyvsp[-2].nd), "**", (yyvsp[0].nd))); } -#line 7449 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7450 "mrbgems/mruby-compiler/core/y.tab.c" break; case 221: -#line 2347 "mrbgems/mruby-compiler/core/parse.y" +#line 2348 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_uni_op(p, (yyvsp[0].nd), "+@"); } -#line 7457 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7458 "mrbgems/mruby-compiler/core/y.tab.c" break; case 222: -#line 2351 "mrbgems/mruby-compiler/core/parse.y" +#line 2352 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_negate(p, (yyvsp[0].nd)); } -#line 7465 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7466 "mrbgems/mruby-compiler/core/y.tab.c" break; case 223: -#line 2355 "mrbgems/mruby-compiler/core/parse.y" +#line 2356 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "|", (yyvsp[0].nd)); } -#line 7473 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7474 "mrbgems/mruby-compiler/core/y.tab.c" break; case 224: -#line 2359 "mrbgems/mruby-compiler/core/parse.y" +#line 2360 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "^", (yyvsp[0].nd)); } -#line 7481 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7482 "mrbgems/mruby-compiler/core/y.tab.c" break; case 225: -#line 2363 "mrbgems/mruby-compiler/core/parse.y" +#line 2364 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "&", (yyvsp[0].nd)); } -#line 7489 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7490 "mrbgems/mruby-compiler/core/y.tab.c" break; case 226: -#line 2367 "mrbgems/mruby-compiler/core/parse.y" +#line 2368 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "<=>", (yyvsp[0].nd)); } -#line 7497 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7498 "mrbgems/mruby-compiler/core/y.tab.c" break; case 227: -#line 2371 "mrbgems/mruby-compiler/core/parse.y" +#line 2372 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), ">", (yyvsp[0].nd)); } -#line 7505 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7506 "mrbgems/mruby-compiler/core/y.tab.c" break; case 228: -#line 2375 "mrbgems/mruby-compiler/core/parse.y" +#line 2376 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), ">=", (yyvsp[0].nd)); } -#line 7513 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7514 "mrbgems/mruby-compiler/core/y.tab.c" break; case 229: -#line 2379 "mrbgems/mruby-compiler/core/parse.y" +#line 2380 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "<", (yyvsp[0].nd)); } -#line 7521 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7522 "mrbgems/mruby-compiler/core/y.tab.c" break; case 230: -#line 2383 "mrbgems/mruby-compiler/core/parse.y" +#line 2384 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "<=", (yyvsp[0].nd)); } -#line 7529 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7530 "mrbgems/mruby-compiler/core/y.tab.c" break; case 231: -#line 2387 "mrbgems/mruby-compiler/core/parse.y" +#line 2388 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "==", (yyvsp[0].nd)); } -#line 7537 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7538 "mrbgems/mruby-compiler/core/y.tab.c" break; case 232: -#line 2391 "mrbgems/mruby-compiler/core/parse.y" +#line 2392 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "===", (yyvsp[0].nd)); } -#line 7545 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7546 "mrbgems/mruby-compiler/core/y.tab.c" break; case 233: -#line 2395 "mrbgems/mruby-compiler/core/parse.y" +#line 2396 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "!=", (yyvsp[0].nd)); } -#line 7553 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7554 "mrbgems/mruby-compiler/core/y.tab.c" break; case 234: -#line 2399 "mrbgems/mruby-compiler/core/parse.y" +#line 2400 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "=~", (yyvsp[0].nd)); } -#line 7561 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7562 "mrbgems/mruby-compiler/core/y.tab.c" break; case 235: -#line 2403 "mrbgems/mruby-compiler/core/parse.y" +#line 2404 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "!~", (yyvsp[0].nd)); } -#line 7569 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7570 "mrbgems/mruby-compiler/core/y.tab.c" break; case 236: -#line 2407 "mrbgems/mruby-compiler/core/parse.y" +#line 2408 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_uni_op(p, cond((yyvsp[0].nd)), "!"); } -#line 7577 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7578 "mrbgems/mruby-compiler/core/y.tab.c" break; case 237: -#line 2411 "mrbgems/mruby-compiler/core/parse.y" +#line 2412 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_uni_op(p, cond((yyvsp[0].nd)), "~"); } -#line 7585 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7586 "mrbgems/mruby-compiler/core/y.tab.c" break; case 238: -#line 2415 "mrbgems/mruby-compiler/core/parse.y" +#line 2416 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "<<", (yyvsp[0].nd)); } -#line 7593 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7594 "mrbgems/mruby-compiler/core/y.tab.c" break; case 239: -#line 2419 "mrbgems/mruby-compiler/core/parse.y" +#line 2420 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), ">>", (yyvsp[0].nd)); } -#line 7601 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7602 "mrbgems/mruby-compiler/core/y.tab.c" break; case 240: -#line 2423 "mrbgems/mruby-compiler/core/parse.y" +#line 2424 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_and(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7609 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7610 "mrbgems/mruby-compiler/core/y.tab.c" break; case 241: -#line 2427 "mrbgems/mruby-compiler/core/parse.y" +#line 2428 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_or(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7617 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7618 "mrbgems/mruby-compiler/core/y.tab.c" break; case 242: -#line 2431 "mrbgems/mruby-compiler/core/parse.y" +#line 2432 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_if(p, cond((yyvsp[-5].nd)), (yyvsp[-3].nd), (yyvsp[0].nd)); } -#line 7625 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7626 "mrbgems/mruby-compiler/core/y.tab.c" break; case 243: -#line 2435 "mrbgems/mruby-compiler/core/parse.y" +#line 2436 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_if(p, cond((yyvsp[-5].nd)), (yyvsp[-3].nd), (yyvsp[0].nd)); } -#line 7633 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7634 "mrbgems/mruby-compiler/core/y.tab.c" break; case 244: -#line 2439 "mrbgems/mruby-compiler/core/parse.y" +#line 2440 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-3].nd); endless_method_name(p, (yyvsp[-3].nd)); @@ -7642,11 +7643,11 @@ yyreduce: nvars_unnest(p); p->in_def--; } -#line 7646 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7647 "mrbgems/mruby-compiler/core/y.tab.c" break; case 245: -#line 2448 "mrbgems/mruby-compiler/core/parse.y" +#line 2449 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-5].nd); endless_method_name(p, (yyvsp[-5].nd)); @@ -7655,11 +7656,11 @@ yyreduce: nvars_unnest(p); p->in_def--; } -#line 7659 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7660 "mrbgems/mruby-compiler/core/y.tab.c" break; case 246: -#line 2457 "mrbgems/mruby-compiler/core/parse.y" +#line 2458 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-3].nd); void_expr_error(p, (yyvsp[0].nd)); @@ -7668,11 +7669,11 @@ yyreduce: p->in_def--; p->in_single--; } -#line 7672 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7673 "mrbgems/mruby-compiler/core/y.tab.c" break; case 247: -#line 2466 "mrbgems/mruby-compiler/core/parse.y" +#line 2467 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-5].nd); void_expr_error(p, (yyvsp[-2].nd)); @@ -7681,70 +7682,70 @@ yyreduce: p->in_def--; p->in_single--; } -#line 7685 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7686 "mrbgems/mruby-compiler/core/y.tab.c" break; case 248: -#line 2475 "mrbgems/mruby-compiler/core/parse.y" +#line 2476 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 7693 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7694 "mrbgems/mruby-compiler/core/y.tab.c" break; case 250: -#line 2482 "mrbgems/mruby-compiler/core/parse.y" +#line 2483 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 7702 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7703 "mrbgems/mruby-compiler/core/y.tab.c" break; case 251: -#line 2487 "mrbgems/mruby-compiler/core/parse.y" +#line 2488 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-3].nd), new_hash(p, (yyvsp[-1].nd))); } -#line 7710 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7711 "mrbgems/mruby-compiler/core/y.tab.c" break; case 252: -#line 2491 "mrbgems/mruby-compiler/core/parse.y" +#line 2492 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = cons(new_kw_hash(p, (yyvsp[-1].nd)), 0); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 7719 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7720 "mrbgems/mruby-compiler/core/y.tab.c" break; case 253: -#line 2498 "mrbgems/mruby-compiler/core/parse.y" +#line 2499 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 7727 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7728 "mrbgems/mruby-compiler/core/y.tab.c" break; case 254: -#line 2502 "mrbgems/mruby-compiler/core/parse.y" +#line 2503 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[-2].nd)); (yyval.nd) = new_mod_rescue(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7736 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7737 "mrbgems/mruby-compiler/core/y.tab.c" break; case 255: -#line 2509 "mrbgems/mruby-compiler/core/parse.y" +#line 2510 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 7744 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7745 "mrbgems/mruby-compiler/core/y.tab.c" break; case 256: -#line 2513 "mrbgems/mruby-compiler/core/parse.y" +#line 2514 "mrbgems/mruby-compiler/core/parse.y" { mrb_sym r = intern_op(mul); mrb_sym k = intern_op(pow); @@ -7753,11 +7754,11 @@ yyreduce: new_kw_hash(p, list1(cons(new_kw_rest_args(p, 0), new_lvar(p, k)))), new_block_arg(p, new_lvar(p, b))); } -#line 7757 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7758 "mrbgems/mruby-compiler/core/y.tab.c" break; case 257: -#line 2522 "mrbgems/mruby-compiler/core/parse.y" +#line 2523 "mrbgems/mruby-compiler/core/parse.y" { mrb_sym r = intern_op(mul); mrb_sym k = intern_op(pow); @@ -7772,378 +7773,378 @@ yyreduce: (yyval.nd) = 0; } } -#line 7776 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7777 "mrbgems/mruby-compiler/core/y.tab.c" break; case 262: -#line 2545 "mrbgems/mruby-compiler/core/parse.y" +#line 2546 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_callargs(p,(yyvsp[-1].nd),0,0); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 7785 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7786 "mrbgems/mruby-compiler/core/y.tab.c" break; case 263: -#line 2550 "mrbgems/mruby-compiler/core/parse.y" +#line 2551 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_callargs(p,(yyvsp[-3].nd),new_kw_hash(p,(yyvsp[-1].nd)),0); NODE_LINENO((yyval.nd), (yyvsp[-3].nd)); } -#line 7794 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7795 "mrbgems/mruby-compiler/core/y.tab.c" break; case 264: -#line 2555 "mrbgems/mruby-compiler/core/parse.y" +#line 2556 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_callargs(p,0,new_kw_hash(p,(yyvsp[-1].nd)),0); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 7803 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7804 "mrbgems/mruby-compiler/core/y.tab.c" break; case 265: -#line 2562 "mrbgems/mruby-compiler/core/parse.y" +#line 2563 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = new_callargs(p, list1((yyvsp[0].nd)), 0, 0); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 7813 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7814 "mrbgems/mruby-compiler/core/y.tab.c" break; case 266: -#line 2568 "mrbgems/mruby-compiler/core/parse.y" +#line 2569 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_callargs(p, (yyvsp[-1].nd), 0, (yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 7822 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7823 "mrbgems/mruby-compiler/core/y.tab.c" break; case 267: -#line 2573 "mrbgems/mruby-compiler/core/parse.y" +#line 2574 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_callargs(p, 0, new_kw_hash(p, (yyvsp[-1].nd)), (yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 7831 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7832 "mrbgems/mruby-compiler/core/y.tab.c" break; case 268: -#line 2578 "mrbgems/mruby-compiler/core/parse.y" +#line 2579 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_callargs(p, (yyvsp[-3].nd), new_kw_hash(p, (yyvsp[-1].nd)), (yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[-3].nd)); } -#line 7840 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7841 "mrbgems/mruby-compiler/core/y.tab.c" break; case 269: -#line 2583 "mrbgems/mruby-compiler/core/parse.y" +#line 2584 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_callargs(p, 0, 0, (yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 7849 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7850 "mrbgems/mruby-compiler/core/y.tab.c" break; case 270: -#line 2589 "mrbgems/mruby-compiler/core/parse.y" +#line 2590 "mrbgems/mruby-compiler/core/parse.y" { (yyval.stack) = p->cmdarg_stack; CMDARG_PUSH(1); } -#line 7858 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7859 "mrbgems/mruby-compiler/core/y.tab.c" break; case 271: -#line 2594 "mrbgems/mruby-compiler/core/parse.y" +#line 2595 "mrbgems/mruby-compiler/core/parse.y" { p->cmdarg_stack = (yyvsp[-1].stack); (yyval.nd) = (yyvsp[0].nd); } -#line 7867 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7868 "mrbgems/mruby-compiler/core/y.tab.c" break; case 272: -#line 2601 "mrbgems/mruby-compiler/core/parse.y" +#line 2602 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_block_arg(p, (yyvsp[0].nd)); } -#line 7875 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7876 "mrbgems/mruby-compiler/core/y.tab.c" break; case 273: -#line 2605 "mrbgems/mruby-compiler/core/parse.y" +#line 2606 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_block_arg(p, 0); } -#line 7883 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7884 "mrbgems/mruby-compiler/core/y.tab.c" break; case 274: -#line 2611 "mrbgems/mruby-compiler/core/parse.y" +#line 2612 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 7891 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7892 "mrbgems/mruby-compiler/core/y.tab.c" break; case 275: -#line 2615 "mrbgems/mruby-compiler/core/parse.y" +#line 2616 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = 0; } -#line 7899 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7900 "mrbgems/mruby-compiler/core/y.tab.c" break; case 277: -#line 2624 "mrbgems/mruby-compiler/core/parse.y" +#line 2625 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = list1((yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 7909 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7910 "mrbgems/mruby-compiler/core/y.tab.c" break; case 278: -#line 2630 "mrbgems/mruby-compiler/core/parse.y" +#line 2631 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1(new_splat(p, (yyvsp[0].nd))); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 7918 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7919 "mrbgems/mruby-compiler/core/y.tab.c" break; case 279: -#line 2635 "mrbgems/mruby-compiler/core/parse.y" +#line 2636 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7927 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7928 "mrbgems/mruby-compiler/core/y.tab.c" break; case 280: -#line 2640 "mrbgems/mruby-compiler/core/parse.y" +#line 2641 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-3].nd), new_splat(p, (yyvsp[0].nd))); } -#line 7935 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7936 "mrbgems/mruby-compiler/core/y.tab.c" break; case 281: -#line 2646 "mrbgems/mruby-compiler/core/parse.y" +#line 2647 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7944 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7945 "mrbgems/mruby-compiler/core/y.tab.c" break; case 282: -#line 2651 "mrbgems/mruby-compiler/core/parse.y" +#line 2652 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-3].nd), new_splat(p, (yyvsp[0].nd))); } -#line 7952 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7953 "mrbgems/mruby-compiler/core/y.tab.c" break; case 283: -#line 2655 "mrbgems/mruby-compiler/core/parse.y" +#line 2656 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1(new_splat(p, (yyvsp[0].nd))); } -#line 7960 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7961 "mrbgems/mruby-compiler/core/y.tab.c" break; case 291: -#line 2668 "mrbgems/mruby-compiler/core/parse.y" +#line 2669 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_nvar(p, (yyvsp[0].num)); } -#line 7968 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7969 "mrbgems/mruby-compiler/core/y.tab.c" break; case 292: -#line 2672 "mrbgems/mruby-compiler/core/parse.y" +#line 2673 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_fcall(p, (yyvsp[0].id), 0); } -#line 7976 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7977 "mrbgems/mruby-compiler/core/y.tab.c" break; case 293: -#line 2676 "mrbgems/mruby-compiler/core/parse.y" +#line 2677 "mrbgems/mruby-compiler/core/parse.y" { (yyval.stack) = p->cmdarg_stack; p->cmdarg_stack = 0; } -#line 7985 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7986 "mrbgems/mruby-compiler/core/y.tab.c" break; case 294: -#line 2682 "mrbgems/mruby-compiler/core/parse.y" +#line 2683 "mrbgems/mruby-compiler/core/parse.y" { p->cmdarg_stack = (yyvsp[-2].stack); (yyval.nd) = (yyvsp[-1].nd); } -#line 7994 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7995 "mrbgems/mruby-compiler/core/y.tab.c" break; case 295: -#line 2687 "mrbgems/mruby-compiler/core/parse.y" +#line 2688 "mrbgems/mruby-compiler/core/parse.y" { (yyval.stack) = p->cmdarg_stack; p->cmdarg_stack = 0; } -#line 8003 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8004 "mrbgems/mruby-compiler/core/y.tab.c" break; case 296: -#line 2691 "mrbgems/mruby-compiler/core/parse.y" +#line 2692 "mrbgems/mruby-compiler/core/parse.y" {p->lstate = EXPR_ENDARG;} -#line 8009 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8010 "mrbgems/mruby-compiler/core/y.tab.c" break; case 297: -#line 2692 "mrbgems/mruby-compiler/core/parse.y" +#line 2693 "mrbgems/mruby-compiler/core/parse.y" { p->cmdarg_stack = (yyvsp[-3].stack); (yyval.nd) = (yyvsp[-2].nd); } -#line 8018 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8019 "mrbgems/mruby-compiler/core/y.tab.c" break; case 298: -#line 2696 "mrbgems/mruby-compiler/core/parse.y" +#line 2697 "mrbgems/mruby-compiler/core/parse.y" {p->lstate = EXPR_ENDARG;} -#line 8024 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8025 "mrbgems/mruby-compiler/core/y.tab.c" break; case 299: -#line 2697 "mrbgems/mruby-compiler/core/parse.y" +#line 2698 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_nil(p); } -#line 8032 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8033 "mrbgems/mruby-compiler/core/y.tab.c" break; case 300: -#line 2701 "mrbgems/mruby-compiler/core/parse.y" +#line 2702 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 8040 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8041 "mrbgems/mruby-compiler/core/y.tab.c" break; case 301: -#line 2705 "mrbgems/mruby-compiler/core/parse.y" +#line 2706 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_colon2(p, (yyvsp[-2].nd), (yyvsp[0].id)); } -#line 8048 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8049 "mrbgems/mruby-compiler/core/y.tab.c" break; case 302: -#line 2709 "mrbgems/mruby-compiler/core/parse.y" +#line 2710 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_colon3(p, (yyvsp[0].id)); } -#line 8056 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8057 "mrbgems/mruby-compiler/core/y.tab.c" break; case 303: -#line 2713 "mrbgems/mruby-compiler/core/parse.y" +#line 2714 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_array(p, (yyvsp[-1].nd)); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 8065 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8066 "mrbgems/mruby-compiler/core/y.tab.c" break; case 304: -#line 2718 "mrbgems/mruby-compiler/core/parse.y" +#line 2719 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_hash(p, (yyvsp[-1].nd)); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 8074 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8075 "mrbgems/mruby-compiler/core/y.tab.c" break; case 305: -#line 2723 "mrbgems/mruby-compiler/core/parse.y" +#line 2724 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_return(p, 0); } -#line 8082 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8083 "mrbgems/mruby-compiler/core/y.tab.c" break; case 306: -#line 2727 "mrbgems/mruby-compiler/core/parse.y" +#line 2728 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_yield(p, (yyvsp[0].nd)); } -#line 8090 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8091 "mrbgems/mruby-compiler/core/y.tab.c" break; case 307: -#line 2731 "mrbgems/mruby-compiler/core/parse.y" +#line 2732 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_uni_op(p, cond((yyvsp[-1].nd)), "!"); } -#line 8098 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8099 "mrbgems/mruby-compiler/core/y.tab.c" break; case 308: -#line 2735 "mrbgems/mruby-compiler/core/parse.y" +#line 2736 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_uni_op(p, new_nil(p), "!"); } -#line 8106 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8107 "mrbgems/mruby-compiler/core/y.tab.c" break; case 309: -#line 2739 "mrbgems/mruby-compiler/core/parse.y" +#line 2740 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_fcall(p, (yyvsp[-1].id), new_callargs(p, 0, 0, (yyvsp[0].nd))); } -#line 8114 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8115 "mrbgems/mruby-compiler/core/y.tab.c" break; case 311: -#line 2744 "mrbgems/mruby-compiler/core/parse.y" +#line 2745 "mrbgems/mruby-compiler/core/parse.y" { call_with_block(p, (yyvsp[-1].nd), (yyvsp[0].nd)); (yyval.nd) = (yyvsp[-1].nd); } -#line 8123 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8124 "mrbgems/mruby-compiler/core/y.tab.c" break; case 312: -#line 2749 "mrbgems/mruby-compiler/core/parse.y" +#line 2750 "mrbgems/mruby-compiler/core/parse.y" { local_nest(p); nvars_nest(p); (yyval.num) = p->lpar_beg; p->lpar_beg = ++p->paren_nest; } -#line 8134 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8135 "mrbgems/mruby-compiler/core/y.tab.c" break; case 313: -#line 2756 "mrbgems/mruby-compiler/core/parse.y" +#line 2757 "mrbgems/mruby-compiler/core/parse.y" { (yyval.stack) = p->cmdarg_stack; p->cmdarg_stack = 0; } -#line 8143 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8144 "mrbgems/mruby-compiler/core/y.tab.c" break; case 314: -#line 2761 "mrbgems/mruby-compiler/core/parse.y" +#line 2762 "mrbgems/mruby-compiler/core/parse.y" { p->lpar_beg = (yyvsp[-3].num); (yyval.nd) = new_lambda(p, (yyvsp[-2].nd), (yyvsp[0].nd)); @@ -8152,149 +8153,149 @@ yyreduce: p->cmdarg_stack = (yyvsp[-1].stack); CMDARG_LEXPOP(); } -#line 8156 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8157 "mrbgems/mruby-compiler/core/y.tab.c" break; case 315: -#line 2773 "mrbgems/mruby-compiler/core/parse.y" +#line 2774 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_if(p, cond((yyvsp[-4].nd)), (yyvsp[-2].nd), (yyvsp[-1].nd)); SET_LINENO((yyval.nd), (yyvsp[-5].num)); } -#line 8165 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8166 "mrbgems/mruby-compiler/core/y.tab.c" break; case 316: -#line 2781 "mrbgems/mruby-compiler/core/parse.y" +#line 2782 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_unless(p, cond((yyvsp[-4].nd)), (yyvsp[-2].nd), (yyvsp[-1].nd)); SET_LINENO((yyval.nd), (yyvsp[-5].num)); } -#line 8174 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8175 "mrbgems/mruby-compiler/core/y.tab.c" break; case 317: -#line 2785 "mrbgems/mruby-compiler/core/parse.y" +#line 2786 "mrbgems/mruby-compiler/core/parse.y" {COND_PUSH(1);} -#line 8180 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8181 "mrbgems/mruby-compiler/core/y.tab.c" break; case 318: -#line 2785 "mrbgems/mruby-compiler/core/parse.y" +#line 2786 "mrbgems/mruby-compiler/core/parse.y" {COND_POP();} -#line 8186 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8187 "mrbgems/mruby-compiler/core/y.tab.c" break; case 319: -#line 2788 "mrbgems/mruby-compiler/core/parse.y" +#line 2789 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_while(p, cond((yyvsp[-4].nd)), (yyvsp[-1].nd)); SET_LINENO((yyval.nd), (yyvsp[-6].num)); } -#line 8195 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8196 "mrbgems/mruby-compiler/core/y.tab.c" break; case 320: -#line 2792 "mrbgems/mruby-compiler/core/parse.y" +#line 2793 "mrbgems/mruby-compiler/core/parse.y" {COND_PUSH(1);} -#line 8201 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8202 "mrbgems/mruby-compiler/core/y.tab.c" break; case 321: -#line 2792 "mrbgems/mruby-compiler/core/parse.y" +#line 2793 "mrbgems/mruby-compiler/core/parse.y" {COND_POP();} -#line 8207 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8208 "mrbgems/mruby-compiler/core/y.tab.c" break; case 322: -#line 2795 "mrbgems/mruby-compiler/core/parse.y" +#line 2796 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_until(p, cond((yyvsp[-4].nd)), (yyvsp[-1].nd)); SET_LINENO((yyval.nd), (yyvsp[-6].num)); } -#line 8216 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8217 "mrbgems/mruby-compiler/core/y.tab.c" break; case 323: -#line 2802 "mrbgems/mruby-compiler/core/parse.y" +#line 2803 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_case(p, (yyvsp[-3].nd), (yyvsp[-1].nd)); } -#line 8224 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8225 "mrbgems/mruby-compiler/core/y.tab.c" break; case 324: -#line 2806 "mrbgems/mruby-compiler/core/parse.y" +#line 2807 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_case(p, 0, (yyvsp[-1].nd)); } -#line 8232 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8233 "mrbgems/mruby-compiler/core/y.tab.c" break; case 325: -#line 2810 "mrbgems/mruby-compiler/core/parse.y" +#line 2811 "mrbgems/mruby-compiler/core/parse.y" {COND_PUSH(1);} -#line 8238 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8239 "mrbgems/mruby-compiler/core/y.tab.c" break; case 326: -#line 2812 "mrbgems/mruby-compiler/core/parse.y" +#line 2813 "mrbgems/mruby-compiler/core/parse.y" {COND_POP();} -#line 8244 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8245 "mrbgems/mruby-compiler/core/y.tab.c" break; case 327: -#line 2815 "mrbgems/mruby-compiler/core/parse.y" +#line 2816 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_for(p, (yyvsp[-7].nd), (yyvsp[-4].nd), (yyvsp[-1].nd)); SET_LINENO((yyval.nd), (yyvsp[-8].num)); } -#line 8253 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8254 "mrbgems/mruby-compiler/core/y.tab.c" break; case 328: -#line 2821 "mrbgems/mruby-compiler/core/parse.y" +#line 2822 "mrbgems/mruby-compiler/core/parse.y" { if (p->in_def || p->in_single) yyerror(p, "class definition in method body"); (yyval.nd) = local_switch(p); nvars_block(p); } -#line 8264 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8265 "mrbgems/mruby-compiler/core/y.tab.c" break; case 329: -#line 2829 "mrbgems/mruby-compiler/core/parse.y" +#line 2830 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_class(p, (yyvsp[-4].nd), (yyvsp[-3].nd), (yyvsp[-1].nd)); SET_LINENO((yyval.nd), (yyvsp[-5].num)); local_resume(p, (yyvsp[-2].nd)); nvars_unnest(p); } -#line 8275 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8276 "mrbgems/mruby-compiler/core/y.tab.c" break; case 330: -#line 2837 "mrbgems/mruby-compiler/core/parse.y" +#line 2838 "mrbgems/mruby-compiler/core/parse.y" { (yyval.num) = p->in_def; p->in_def = 0; } -#line 8284 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8285 "mrbgems/mruby-compiler/core/y.tab.c" break; case 331: -#line 2842 "mrbgems/mruby-compiler/core/parse.y" +#line 2843 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = cons(local_switch(p), nint(p->in_single)); nvars_block(p); p->in_single = 0; } -#line 8294 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8295 "mrbgems/mruby-compiler/core/y.tab.c" break; case 332: -#line 2849 "mrbgems/mruby-compiler/core/parse.y" +#line 2850 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_sclass(p, (yyvsp[-5].nd), (yyvsp[-1].nd)); SET_LINENO((yyval.nd), (yyvsp[-7].num)); @@ -8303,44 +8304,44 @@ yyreduce: p->in_def = (yyvsp[-4].num); p->in_single = intn((yyvsp[-2].nd)->cdr); } -#line 8307 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8308 "mrbgems/mruby-compiler/core/y.tab.c" break; case 333: -#line 2859 "mrbgems/mruby-compiler/core/parse.y" +#line 2860 "mrbgems/mruby-compiler/core/parse.y" { if (p->in_def || p->in_single) yyerror(p, "module definition in method body"); (yyval.nd) = local_switch(p); nvars_block(p); } -#line 8318 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8319 "mrbgems/mruby-compiler/core/y.tab.c" break; case 334: -#line 2867 "mrbgems/mruby-compiler/core/parse.y" +#line 2868 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_module(p, (yyvsp[-3].nd), (yyvsp[-1].nd)); SET_LINENO((yyval.nd), (yyvsp[-4].num)); local_resume(p, (yyvsp[-2].nd)); nvars_unnest(p); } -#line 8329 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8330 "mrbgems/mruby-compiler/core/y.tab.c" break; case 335: -#line 2877 "mrbgems/mruby-compiler/core/parse.y" +#line 2878 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-3].nd); defn_setup(p, (yyval.nd), (yyvsp[-2].nd), (yyvsp[-1].nd)); nvars_unnest(p); p->in_def--; } -#line 8340 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8341 "mrbgems/mruby-compiler/core/y.tab.c" break; case 336: -#line 2887 "mrbgems/mruby-compiler/core/parse.y" +#line 2888 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-3].nd); defs_setup(p, (yyval.nd), (yyvsp[-2].nd), (yyvsp[-1].nd)); @@ -8348,451 +8349,451 @@ yyreduce: p->in_def--; p->in_single--; } -#line 8352 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8353 "mrbgems/mruby-compiler/core/y.tab.c" break; case 337: -#line 2895 "mrbgems/mruby-compiler/core/parse.y" +#line 2896 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_break(p, 0); } -#line 8360 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8361 "mrbgems/mruby-compiler/core/y.tab.c" break; case 338: -#line 2899 "mrbgems/mruby-compiler/core/parse.y" +#line 2900 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_next(p, 0); } -#line 8368 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8369 "mrbgems/mruby-compiler/core/y.tab.c" break; case 339: -#line 2903 "mrbgems/mruby-compiler/core/parse.y" +#line 2904 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_redo(p); } -#line 8376 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8377 "mrbgems/mruby-compiler/core/y.tab.c" break; case 340: -#line 2907 "mrbgems/mruby-compiler/core/parse.y" +#line 2908 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_retry(p); } -#line 8384 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8385 "mrbgems/mruby-compiler/core/y.tab.c" break; case 341: -#line 2913 "mrbgems/mruby-compiler/core/parse.y" +#line 2914 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); if (!(yyval.nd)) (yyval.nd) = new_nil(p); } -#line 8393 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8394 "mrbgems/mruby-compiler/core/y.tab.c" break; case 348: -#line 2932 "mrbgems/mruby-compiler/core/parse.y" +#line 2933 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_if(p, cond((yyvsp[-3].nd)), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 8401 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8402 "mrbgems/mruby-compiler/core/y.tab.c" break; case 350: -#line 2939 "mrbgems/mruby-compiler/core/parse.y" +#line 2940 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 8409 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8410 "mrbgems/mruby-compiler/core/y.tab.c" break; case 351: -#line 2945 "mrbgems/mruby-compiler/core/parse.y" +#line 2946 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1(list1((yyvsp[0].nd))); } -#line 8417 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8418 "mrbgems/mruby-compiler/core/y.tab.c" break; case 353: -#line 2952 "mrbgems/mruby-compiler/core/parse.y" +#line 2953 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3((yyvsp[0].nd),0,0); } -#line 8425 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8426 "mrbgems/mruby-compiler/core/y.tab.c" break; case 354: -#line 2956 "mrbgems/mruby-compiler/core/parse.y" +#line 2957 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3((yyvsp[-3].nd), new_arg(p, (yyvsp[0].id)), 0); } -#line 8433 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8434 "mrbgems/mruby-compiler/core/y.tab.c" break; case 355: -#line 2960 "mrbgems/mruby-compiler/core/parse.y" +#line 2961 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3((yyvsp[-5].nd), new_arg(p, (yyvsp[-2].id)), (yyvsp[0].nd)); } -#line 8441 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8442 "mrbgems/mruby-compiler/core/y.tab.c" break; case 356: -#line 2964 "mrbgems/mruby-compiler/core/parse.y" +#line 2965 "mrbgems/mruby-compiler/core/parse.y" { local_add_f(p, intern_op(mul)); (yyval.nd) = list3((yyvsp[-2].nd), nint(-1), 0); } -#line 8450 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8451 "mrbgems/mruby-compiler/core/y.tab.c" break; case 357: -#line 2969 "mrbgems/mruby-compiler/core/parse.y" +#line 2970 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3((yyvsp[-4].nd), nint(-1), (yyvsp[0].nd)); } -#line 8458 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8459 "mrbgems/mruby-compiler/core/y.tab.c" break; case 358: -#line 2973 "mrbgems/mruby-compiler/core/parse.y" +#line 2974 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3(0, new_arg(p, (yyvsp[0].id)), 0); } -#line 8466 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8467 "mrbgems/mruby-compiler/core/y.tab.c" break; case 359: -#line 2977 "mrbgems/mruby-compiler/core/parse.y" +#line 2978 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3(0, new_arg(p, (yyvsp[-2].id)), (yyvsp[0].nd)); } -#line 8474 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8475 "mrbgems/mruby-compiler/core/y.tab.c" break; case 360: -#line 2981 "mrbgems/mruby-compiler/core/parse.y" +#line 2982 "mrbgems/mruby-compiler/core/parse.y" { local_add_f(p, intern_op(mul)); (yyval.nd) = list3(0, nint(-1), 0); } -#line 8483 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8484 "mrbgems/mruby-compiler/core/y.tab.c" break; case 361: -#line 2986 "mrbgems/mruby-compiler/core/parse.y" +#line 2987 "mrbgems/mruby-compiler/core/parse.y" { local_add_f(p, intern_op(mul)); } -#line 8491 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8492 "mrbgems/mruby-compiler/core/y.tab.c" break; case 362: -#line 2990 "mrbgems/mruby-compiler/core/parse.y" +#line 2991 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3(0, nint(-1), (yyvsp[0].nd)); } -#line 8499 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8500 "mrbgems/mruby-compiler/core/y.tab.c" break; case 363: -#line 2996 "mrbgems/mruby-compiler/core/parse.y" +#line 2997 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, (yyvsp[-3].nd), (yyvsp[-1].nd), (yyvsp[0].id)); } -#line 8507 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8508 "mrbgems/mruby-compiler/core/y.tab.c" break; case 364: -#line 3000 "mrbgems/mruby-compiler/core/parse.y" +#line 3001 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, (yyvsp[-1].nd), 0, (yyvsp[0].id)); } -#line 8515 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8516 "mrbgems/mruby-compiler/core/y.tab.c" break; case 365: -#line 3004 "mrbgems/mruby-compiler/core/parse.y" +#line 3005 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, 0, (yyvsp[-1].nd), (yyvsp[0].id)); } -#line 8523 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8524 "mrbgems/mruby-compiler/core/y.tab.c" break; case 366: -#line 3008 "mrbgems/mruby-compiler/core/parse.y" +#line 3009 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, 0, 0, (yyvsp[0].id)); } -#line 8531 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8532 "mrbgems/mruby-compiler/core/y.tab.c" break; case 367: -#line 3014 "mrbgems/mruby-compiler/core/parse.y" +#line 3015 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 8539 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8540 "mrbgems/mruby-compiler/core/y.tab.c" break; case 368: -#line 3018 "mrbgems/mruby-compiler/core/parse.y" +#line 3019 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, 0, 0, 0); } -#line 8547 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8548 "mrbgems/mruby-compiler/core/y.tab.c" break; case 369: -#line 3024 "mrbgems/mruby-compiler/core/parse.y" +#line 3025 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-5].nd), (yyvsp[-3].nd), (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 8555 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8556 "mrbgems/mruby-compiler/core/y.tab.c" break; case 370: -#line 3028 "mrbgems/mruby-compiler/core/parse.y" +#line 3029 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-7].nd), (yyvsp[-5].nd), (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 8563 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8564 "mrbgems/mruby-compiler/core/y.tab.c" break; case 371: -#line 3032 "mrbgems/mruby-compiler/core/parse.y" +#line 3033 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-3].nd), (yyvsp[-1].nd), 0, 0, (yyvsp[0].nd)); } -#line 8571 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8572 "mrbgems/mruby-compiler/core/y.tab.c" break; case 372: -#line 3036 "mrbgems/mruby-compiler/core/parse.y" +#line 3037 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-5].nd), (yyvsp[-3].nd), 0, (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 8579 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8580 "mrbgems/mruby-compiler/core/y.tab.c" break; case 373: -#line 3040 "mrbgems/mruby-compiler/core/parse.y" +#line 3041 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-3].nd), 0, (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 8587 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8588 "mrbgems/mruby-compiler/core/y.tab.c" break; case 374: -#line 3044 "mrbgems/mruby-compiler/core/parse.y" +#line 3045 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-2].nd), 0, 0, 0, (yyvsp[0].nd)); } -#line 8595 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8596 "mrbgems/mruby-compiler/core/y.tab.c" break; case 375: -#line 3048 "mrbgems/mruby-compiler/core/parse.y" +#line 3049 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-5].nd), 0, (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 8603 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8604 "mrbgems/mruby-compiler/core/y.tab.c" break; case 376: -#line 3052 "mrbgems/mruby-compiler/core/parse.y" +#line 3053 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-1].nd), 0, 0, 0, (yyvsp[0].nd)); } -#line 8611 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8612 "mrbgems/mruby-compiler/core/y.tab.c" break; case 377: -#line 3056 "mrbgems/mruby-compiler/core/parse.y" +#line 3057 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, (yyvsp[-3].nd), (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 8619 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8620 "mrbgems/mruby-compiler/core/y.tab.c" break; case 378: -#line 3060 "mrbgems/mruby-compiler/core/parse.y" +#line 3061 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, (yyvsp[-5].nd), (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 8627 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8628 "mrbgems/mruby-compiler/core/y.tab.c" break; case 379: -#line 3064 "mrbgems/mruby-compiler/core/parse.y" +#line 3065 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, (yyvsp[-1].nd), 0, 0, (yyvsp[0].nd)); } -#line 8635 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8636 "mrbgems/mruby-compiler/core/y.tab.c" break; case 380: -#line 3068 "mrbgems/mruby-compiler/core/parse.y" +#line 3069 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, (yyvsp[-3].nd), 0, (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 8643 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8644 "mrbgems/mruby-compiler/core/y.tab.c" break; case 381: -#line 3072 "mrbgems/mruby-compiler/core/parse.y" +#line 3073 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, 0, (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 8651 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8652 "mrbgems/mruby-compiler/core/y.tab.c" break; case 382: -#line 3076 "mrbgems/mruby-compiler/core/parse.y" +#line 3077 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, 0, (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 8659 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8660 "mrbgems/mruby-compiler/core/y.tab.c" break; case 383: -#line 3080 "mrbgems/mruby-compiler/core/parse.y" +#line 3081 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, 0, 0, 0, (yyvsp[0].nd)); } -#line 8667 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8668 "mrbgems/mruby-compiler/core/y.tab.c" break; case 384: -#line 3086 "mrbgems/mruby-compiler/core/parse.y" +#line 3087 "mrbgems/mruby-compiler/core/parse.y" { local_add_blk(p, 0); (yyval.nd) = 0; } -#line 8676 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8677 "mrbgems/mruby-compiler/core/y.tab.c" break; case 385: -#line 3091 "mrbgems/mruby-compiler/core/parse.y" +#line 3092 "mrbgems/mruby-compiler/core/parse.y" { p->cmd_start = TRUE; (yyval.nd) = (yyvsp[0].nd); } -#line 8685 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8686 "mrbgems/mruby-compiler/core/y.tab.c" break; case 386: -#line 3097 "mrbgems/mruby-compiler/core/parse.y" +#line 3098 "mrbgems/mruby-compiler/core/parse.y" {local_add_blk(p, 0);} -#line 8691 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8692 "mrbgems/mruby-compiler/core/y.tab.c" break; case 387: -#line 3098 "mrbgems/mruby-compiler/core/parse.y" +#line 3099 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = 0; } -#line 8699 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8700 "mrbgems/mruby-compiler/core/y.tab.c" break; case 388: -#line 3102 "mrbgems/mruby-compiler/core/parse.y" +#line 3103 "mrbgems/mruby-compiler/core/parse.y" { local_add_blk(p, 0); (yyval.nd) = 0; } -#line 8708 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8709 "mrbgems/mruby-compiler/core/y.tab.c" break; case 389: -#line 3107 "mrbgems/mruby-compiler/core/parse.y" +#line 3108 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-2].nd); } -#line 8716 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8717 "mrbgems/mruby-compiler/core/y.tab.c" break; case 390: -#line 3114 "mrbgems/mruby-compiler/core/parse.y" +#line 3115 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = 0; } -#line 8724 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8725 "mrbgems/mruby-compiler/core/y.tab.c" break; case 391: -#line 3118 "mrbgems/mruby-compiler/core/parse.y" +#line 3119 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = 0; } -#line 8732 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8733 "mrbgems/mruby-compiler/core/y.tab.c" break; case 394: -#line 3128 "mrbgems/mruby-compiler/core/parse.y" +#line 3129 "mrbgems/mruby-compiler/core/parse.y" { local_add_f(p, (yyvsp[0].id)); new_bv(p, (yyvsp[0].id)); } -#line 8741 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8742 "mrbgems/mruby-compiler/core/y.tab.c" break; case 396: -#line 3136 "mrbgems/mruby-compiler/core/parse.y" +#line 3137 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-2].nd); } -#line 8749 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8750 "mrbgems/mruby-compiler/core/y.tab.c" break; case 397: -#line 3140 "mrbgems/mruby-compiler/core/parse.y" +#line 3141 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 8757 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8758 "mrbgems/mruby-compiler/core/y.tab.c" break; case 398: -#line 3146 "mrbgems/mruby-compiler/core/parse.y" +#line 3147 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 8765 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8766 "mrbgems/mruby-compiler/core/y.tab.c" break; case 399: -#line 3150 "mrbgems/mruby-compiler/core/parse.y" +#line 3151 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 8773 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8774 "mrbgems/mruby-compiler/core/y.tab.c" break; case 400: -#line 3156 "mrbgems/mruby-compiler/core/parse.y" +#line 3157 "mrbgems/mruby-compiler/core/parse.y" { local_nest(p); nvars_nest(p); } -#line 8782 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8783 "mrbgems/mruby-compiler/core/y.tab.c" break; case 401: -#line 3163 "mrbgems/mruby-compiler/core/parse.y" +#line 3164 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_block(p,(yyvsp[-2].nd),(yyvsp[-1].nd)); local_unnest(p); nvars_unnest(p); } -#line 8792 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8793 "mrbgems/mruby-compiler/core/y.tab.c" break; case 402: -#line 3171 "mrbgems/mruby-compiler/core/parse.y" +#line 3172 "mrbgems/mruby-compiler/core/parse.y" { if (typen((yyvsp[-1].nd)->car) == NODE_YIELD) { yyerror(p, "block given to yield"); @@ -8802,159 +8803,159 @@ yyreduce: } (yyval.nd) = (yyvsp[-1].nd); } -#line 8806 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8807 "mrbgems/mruby-compiler/core/y.tab.c" break; case 403: -#line 3181 "mrbgems/mruby-compiler/core/parse.y" +#line 3182 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), (yyvsp[-2].num)); } -#line 8814 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8815 "mrbgems/mruby-compiler/core/y.tab.c" break; case 404: -#line 3185 "mrbgems/mruby-compiler/core/parse.y" +#line 3186 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), (yyvsp[-1].nd), (yyvsp[-3].num)); call_with_block(p, (yyval.nd), (yyvsp[0].nd)); } -#line 8823 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8824 "mrbgems/mruby-compiler/core/y.tab.c" break; case 405: -#line 3190 "mrbgems/mruby-compiler/core/parse.y" +#line 3191 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), (yyvsp[-1].nd), (yyvsp[-3].num)); call_with_block(p, (yyval.nd), (yyvsp[0].nd)); } -#line 8832 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8833 "mrbgems/mruby-compiler/core/y.tab.c" break; case 406: -#line 3197 "mrbgems/mruby-compiler/core/parse.y" +#line 3198 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_fcall(p, (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 8840 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8841 "mrbgems/mruby-compiler/core/y.tab.c" break; case 407: -#line 3201 "mrbgems/mruby-compiler/core/parse.y" +#line 3202 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), (yyvsp[-2].num)); } -#line 8848 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8849 "mrbgems/mruby-compiler/core/y.tab.c" break; case 408: -#line 3205 "mrbgems/mruby-compiler/core/parse.y" +#line 3206 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), tCOLON2); } -#line 8856 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8857 "mrbgems/mruby-compiler/core/y.tab.c" break; case 409: -#line 3209 "mrbgems/mruby-compiler/core/parse.y" +#line 3210 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, tCOLON2); } -#line 8864 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8865 "mrbgems/mruby-compiler/core/y.tab.c" break; case 410: -#line 3213 "mrbgems/mruby-compiler/core/parse.y" +#line 3214 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-2].nd), MRB_SYM_2(p->mrb, call), (yyvsp[0].nd), (yyvsp[-1].num)); } -#line 8872 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8873 "mrbgems/mruby-compiler/core/y.tab.c" break; case 411: -#line 3217 "mrbgems/mruby-compiler/core/parse.y" +#line 3218 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-2].nd), MRB_SYM_2(p->mrb, call), (yyvsp[0].nd), tCOLON2); } -#line 8880 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8881 "mrbgems/mruby-compiler/core/y.tab.c" break; case 412: -#line 3221 "mrbgems/mruby-compiler/core/parse.y" +#line 3222 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_super(p, (yyvsp[0].nd)); } -#line 8888 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8889 "mrbgems/mruby-compiler/core/y.tab.c" break; case 413: -#line 3225 "mrbgems/mruby-compiler/core/parse.y" +#line 3226 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_zsuper(p); } -#line 8896 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8897 "mrbgems/mruby-compiler/core/y.tab.c" break; case 414: -#line 3229 "mrbgems/mruby-compiler/core/parse.y" +#line 3230 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), intern_op(aref), (yyvsp[-1].nd), '.'); } -#line 8904 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8905 "mrbgems/mruby-compiler/core/y.tab.c" break; case 415: -#line 3235 "mrbgems/mruby-compiler/core/parse.y" +#line 3236 "mrbgems/mruby-compiler/core/parse.y" { local_nest(p); nvars_nest(p); (yyval.num) = p->lineno; } -#line 8914 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8915 "mrbgems/mruby-compiler/core/y.tab.c" break; case 416: -#line 3242 "mrbgems/mruby-compiler/core/parse.y" +#line 3243 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_block(p,(yyvsp[-2].nd),(yyvsp[-1].nd)); SET_LINENO((yyval.nd), (yyvsp[-3].num)); local_unnest(p); nvars_unnest(p); } -#line 8925 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8926 "mrbgems/mruby-compiler/core/y.tab.c" break; case 417: -#line 3249 "mrbgems/mruby-compiler/core/parse.y" +#line 3250 "mrbgems/mruby-compiler/core/parse.y" { local_nest(p); nvars_nest(p); (yyval.num) = p->lineno; } -#line 8935 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8936 "mrbgems/mruby-compiler/core/y.tab.c" break; case 418: -#line 3256 "mrbgems/mruby-compiler/core/parse.y" +#line 3257 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_block(p,(yyvsp[-2].nd),(yyvsp[-1].nd)); SET_LINENO((yyval.nd), (yyvsp[-3].num)); local_unnest(p); nvars_unnest(p); } -#line 8946 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8947 "mrbgems/mruby-compiler/core/y.tab.c" break; case 419: -#line 3267 "mrbgems/mruby-compiler/core/parse.y" +#line 3268 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = cons(cons((yyvsp[-3].nd), (yyvsp[-1].nd)), (yyvsp[0].nd)); } -#line 8954 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8955 "mrbgems/mruby-compiler/core/y.tab.c" break; case 420: -#line 3273 "mrbgems/mruby-compiler/core/parse.y" +#line 3274 "mrbgems/mruby-compiler/core/parse.y" { if ((yyvsp[0].nd)) { (yyval.nd) = cons(cons(0, (yyvsp[0].nd)), 0); @@ -8963,60 +8964,60 @@ yyreduce: (yyval.nd) = 0; } } -#line 8967 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8968 "mrbgems/mruby-compiler/core/y.tab.c" break; case 422: -#line 3287 "mrbgems/mruby-compiler/core/parse.y" +#line 3288 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1(list3((yyvsp[-4].nd), (yyvsp[-3].nd), (yyvsp[-1].nd))); if ((yyvsp[0].nd)) (yyval.nd) = append((yyval.nd), (yyvsp[0].nd)); } -#line 8976 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8977 "mrbgems/mruby-compiler/core/y.tab.c" break; case 424: -#line 3295 "mrbgems/mruby-compiler/core/parse.y" +#line 3296 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 8984 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8985 "mrbgems/mruby-compiler/core/y.tab.c" break; case 427: -#line 3303 "mrbgems/mruby-compiler/core/parse.y" +#line 3304 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 8992 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8993 "mrbgems/mruby-compiler/core/y.tab.c" break; case 429: -#line 3310 "mrbgems/mruby-compiler/core/parse.y" +#line 3311 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 9000 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9001 "mrbgems/mruby-compiler/core/y.tab.c" break; case 436: -#line 3324 "mrbgems/mruby-compiler/core/parse.y" +#line 3325 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = concat_string(p, (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 9008 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9009 "mrbgems/mruby-compiler/core/y.tab.c" break; case 439: -#line 3332 "mrbgems/mruby-compiler/core/parse.y" +#line 3333 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 9016 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9017 "mrbgems/mruby-compiler/core/y.tab.c" break; case 440: -#line 3336 "mrbgems/mruby-compiler/core/parse.y" +#line 3337 "mrbgems/mruby-compiler/core/parse.y" { node *n = (yyvsp[-1].nd); if (intn((yyvsp[0].nd)->cdr->cdr) > 0) { @@ -9027,69 +9028,69 @@ yyreduce: } (yyval.nd) = new_dstr(p, n); } -#line 9031 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9032 "mrbgems/mruby-compiler/core/y.tab.c" break; case 442: -#line 3350 "mrbgems/mruby-compiler/core/parse.y" +#line 3351 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = append((yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 9039 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9040 "mrbgems/mruby-compiler/core/y.tab.c" break; case 443: -#line 3356 "mrbgems/mruby-compiler/core/parse.y" +#line 3357 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 9047 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9048 "mrbgems/mruby-compiler/core/y.tab.c" break; case 444: -#line 3360 "mrbgems/mruby-compiler/core/parse.y" +#line 3361 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = p->lex_strterm; p->lex_strterm = NULL; } -#line 9056 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9057 "mrbgems/mruby-compiler/core/y.tab.c" break; case 445: -#line 3366 "mrbgems/mruby-compiler/core/parse.y" +#line 3367 "mrbgems/mruby-compiler/core/parse.y" { p->lex_strterm = (yyvsp[-2].nd); (yyval.nd) = list2((yyvsp[-3].nd), (yyvsp[-1].nd)); } -#line 9065 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9066 "mrbgems/mruby-compiler/core/y.tab.c" break; case 446: -#line 3371 "mrbgems/mruby-compiler/core/parse.y" +#line 3372 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1(new_literal_delim(p)); } -#line 9073 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9074 "mrbgems/mruby-compiler/core/y.tab.c" break; case 447: -#line 3375 "mrbgems/mruby-compiler/core/parse.y" +#line 3376 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1(new_literal_delim(p)); } -#line 9081 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9082 "mrbgems/mruby-compiler/core/y.tab.c" break; case 448: -#line 3381 "mrbgems/mruby-compiler/core/parse.y" +#line 3382 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 9089 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9090 "mrbgems/mruby-compiler/core/y.tab.c" break; case 449: -#line 3385 "mrbgems/mruby-compiler/core/parse.y" +#line 3386 "mrbgems/mruby-compiler/core/parse.y" { node *n = (yyvsp[-1].nd); if (intn((yyvsp[0].nd)->cdr->cdr) > 0) { @@ -9100,82 +9101,82 @@ yyreduce: } (yyval.nd) = new_dxstr(p, n); } -#line 9104 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9105 "mrbgems/mruby-compiler/core/y.tab.c" break; case 450: -#line 3398 "mrbgems/mruby-compiler/core/parse.y" +#line 3399 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 9112 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9113 "mrbgems/mruby-compiler/core/y.tab.c" break; case 451: -#line 3402 "mrbgems/mruby-compiler/core/parse.y" +#line 3403 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_dregx(p, (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 9120 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9121 "mrbgems/mruby-compiler/core/y.tab.c" break; case 455: -#line 3415 "mrbgems/mruby-compiler/core/parse.y" +#line 3416 "mrbgems/mruby-compiler/core/parse.y" { parser_heredoc_info * inf = parsing_heredoc_inf(p); inf->doc = push(inf->doc, new_str(p, "", 0)); heredoc_end(p); } -#line 9130 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9131 "mrbgems/mruby-compiler/core/y.tab.c" break; case 456: -#line 3421 "mrbgems/mruby-compiler/core/parse.y" +#line 3422 "mrbgems/mruby-compiler/core/parse.y" { heredoc_end(p); } -#line 9138 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9139 "mrbgems/mruby-compiler/core/y.tab.c" break; case 459: -#line 3431 "mrbgems/mruby-compiler/core/parse.y" +#line 3432 "mrbgems/mruby-compiler/core/parse.y" { parser_heredoc_info * inf = parsing_heredoc_inf(p); inf->doc = push(inf->doc, (yyvsp[0].nd)); heredoc_treat_nextline(p); } -#line 9148 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9149 "mrbgems/mruby-compiler/core/y.tab.c" break; case 460: -#line 3437 "mrbgems/mruby-compiler/core/parse.y" +#line 3438 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = p->lex_strterm; p->lex_strterm = NULL; } -#line 9157 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9158 "mrbgems/mruby-compiler/core/y.tab.c" break; case 461: -#line 3443 "mrbgems/mruby-compiler/core/parse.y" +#line 3444 "mrbgems/mruby-compiler/core/parse.y" { parser_heredoc_info * inf = parsing_heredoc_inf(p); p->lex_strterm = (yyvsp[-2].nd); inf->doc = push(push(inf->doc, (yyvsp[-3].nd)), (yyvsp[-1].nd)); } -#line 9167 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9168 "mrbgems/mruby-compiler/core/y.tab.c" break; case 462: -#line 3451 "mrbgems/mruby-compiler/core/parse.y" +#line 3452 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_words(p, list1((yyvsp[0].nd))); } -#line 9175 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9176 "mrbgems/mruby-compiler/core/y.tab.c" break; case 463: -#line 3455 "mrbgems/mruby-compiler/core/parse.y" +#line 3456 "mrbgems/mruby-compiler/core/parse.y" { node *n = (yyvsp[-1].nd); if (intn((yyvsp[0].nd)->cdr->cdr) > 0) { @@ -9186,20 +9187,20 @@ yyreduce: } (yyval.nd) = new_words(p, n); } -#line 9190 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9191 "mrbgems/mruby-compiler/core/y.tab.c" break; case 464: -#line 3469 "mrbgems/mruby-compiler/core/parse.y" +#line 3470 "mrbgems/mruby-compiler/core/parse.y" { p->lstate = EXPR_ENDARG; (yyval.nd) = new_sym(p, (yyvsp[0].id)); } -#line 9199 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9200 "mrbgems/mruby-compiler/core/y.tab.c" break; case 465: -#line 3474 "mrbgems/mruby-compiler/core/parse.y" +#line 3475 "mrbgems/mruby-compiler/core/parse.y" { node *n = (yyvsp[-1].nd); p->lstate = EXPR_ENDARG; @@ -9211,43 +9212,43 @@ yyreduce: } (yyval.nd) = new_dsym(p, new_dstr(p, n)); } -#line 9215 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9216 "mrbgems/mruby-compiler/core/y.tab.c" break; case 466: -#line 3488 "mrbgems/mruby-compiler/core/parse.y" +#line 3489 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = (yyvsp[0].id); } -#line 9223 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9224 "mrbgems/mruby-compiler/core/y.tab.c" break; case 471: -#line 3498 "mrbgems/mruby-compiler/core/parse.y" +#line 3499 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = new_strsym(p, (yyvsp[0].nd)); } -#line 9231 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9232 "mrbgems/mruby-compiler/core/y.tab.c" break; case 472: -#line 3502 "mrbgems/mruby-compiler/core/parse.y" +#line 3503 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = new_strsym(p, (yyvsp[0].nd)); } -#line 9239 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9240 "mrbgems/mruby-compiler/core/y.tab.c" break; case 473: -#line 3508 "mrbgems/mruby-compiler/core/parse.y" +#line 3509 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_symbols(p, list1((yyvsp[0].nd))); } -#line 9247 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9248 "mrbgems/mruby-compiler/core/y.tab.c" break; case 474: -#line 3512 "mrbgems/mruby-compiler/core/parse.y" +#line 3513 "mrbgems/mruby-compiler/core/parse.y" { node *n = (yyvsp[-1].nd); if (intn((yyvsp[0].nd)->cdr->cdr) > 0) { @@ -9255,123 +9256,123 @@ yyreduce: } (yyval.nd) = new_symbols(p, n); } -#line 9259 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9260 "mrbgems/mruby-compiler/core/y.tab.c" break; case 477: -#line 3524 "mrbgems/mruby-compiler/core/parse.y" +#line 3525 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_negate(p, (yyvsp[0].nd)); } -#line 9267 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9268 "mrbgems/mruby-compiler/core/y.tab.c" break; case 478: -#line 3528 "mrbgems/mruby-compiler/core/parse.y" +#line 3529 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_negate(p, (yyvsp[0].nd)); } -#line 9275 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9276 "mrbgems/mruby-compiler/core/y.tab.c" break; case 479: -#line 3534 "mrbgems/mruby-compiler/core/parse.y" +#line 3535 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_lvar(p, (yyvsp[0].id)); } -#line 9283 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9284 "mrbgems/mruby-compiler/core/y.tab.c" break; case 480: -#line 3538 "mrbgems/mruby-compiler/core/parse.y" +#line 3539 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_ivar(p, (yyvsp[0].id)); } -#line 9291 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9292 "mrbgems/mruby-compiler/core/y.tab.c" break; case 481: -#line 3542 "mrbgems/mruby-compiler/core/parse.y" +#line 3543 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_gvar(p, (yyvsp[0].id)); } -#line 9299 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9300 "mrbgems/mruby-compiler/core/y.tab.c" break; case 482: -#line 3546 "mrbgems/mruby-compiler/core/parse.y" +#line 3547 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_cvar(p, (yyvsp[0].id)); } -#line 9307 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9308 "mrbgems/mruby-compiler/core/y.tab.c" break; case 483: -#line 3550 "mrbgems/mruby-compiler/core/parse.y" +#line 3551 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_const(p, (yyvsp[0].id)); } -#line 9315 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9316 "mrbgems/mruby-compiler/core/y.tab.c" break; case 484: -#line 3556 "mrbgems/mruby-compiler/core/parse.y" +#line 3557 "mrbgems/mruby-compiler/core/parse.y" { assignable(p, (yyvsp[0].nd)); } -#line 9323 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9324 "mrbgems/mruby-compiler/core/y.tab.c" break; case 485: -#line 3560 "mrbgems/mruby-compiler/core/parse.y" +#line 3561 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "can't assign to numbered parameter"); } -#line 9331 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9332 "mrbgems/mruby-compiler/core/y.tab.c" break; case 486: -#line 3566 "mrbgems/mruby-compiler/core/parse.y" +#line 3567 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = var_reference(p, (yyvsp[0].nd)); } -#line 9339 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9340 "mrbgems/mruby-compiler/core/y.tab.c" break; case 487: -#line 3570 "mrbgems/mruby-compiler/core/parse.y" +#line 3571 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_nil(p); } -#line 9347 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9348 "mrbgems/mruby-compiler/core/y.tab.c" break; case 488: -#line 3574 "mrbgems/mruby-compiler/core/parse.y" +#line 3575 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_self(p); } -#line 9355 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9356 "mrbgems/mruby-compiler/core/y.tab.c" break; case 489: -#line 3578 "mrbgems/mruby-compiler/core/parse.y" +#line 3579 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_true(p); } -#line 9363 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9364 "mrbgems/mruby-compiler/core/y.tab.c" break; case 490: -#line 3582 "mrbgems/mruby-compiler/core/parse.y" +#line 3583 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_false(p); } -#line 9371 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9372 "mrbgems/mruby-compiler/core/y.tab.c" break; case 491: -#line 3586 "mrbgems/mruby-compiler/core/parse.y" +#line 3587 "mrbgems/mruby-compiler/core/parse.y" { const char *fn = mrb_sym_name_len(p->mrb, p->filename_sym, NULL); if (!fn) { @@ -9379,599 +9380,599 @@ yyreduce: } (yyval.nd) = new_str(p, fn, strlen(fn)); } -#line 9383 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9384 "mrbgems/mruby-compiler/core/y.tab.c" break; case 492: -#line 3594 "mrbgems/mruby-compiler/core/parse.y" +#line 3595 "mrbgems/mruby-compiler/core/parse.y" { char buf[16]; dump_int(p->lineno, buf); (yyval.nd) = new_int(p, buf, 10, 0); } -#line 9394 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9395 "mrbgems/mruby-compiler/core/y.tab.c" break; case 493: -#line 3601 "mrbgems/mruby-compiler/core/parse.y" +#line 3602 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_fcall(p, MRB_SYM_2(p->mrb, __ENCODING__), 0); } -#line 9402 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9403 "mrbgems/mruby-compiler/core/y.tab.c" break; case 496: -#line 3611 "mrbgems/mruby-compiler/core/parse.y" +#line 3612 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = 0; } -#line 9410 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9411 "mrbgems/mruby-compiler/core/y.tab.c" break; case 497: -#line 3615 "mrbgems/mruby-compiler/core/parse.y" +#line 3616 "mrbgems/mruby-compiler/core/parse.y" { p->lstate = EXPR_BEG; p->cmd_start = TRUE; } -#line 9419 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9420 "mrbgems/mruby-compiler/core/y.tab.c" break; case 498: -#line 3620 "mrbgems/mruby-compiler/core/parse.y" +#line 3621 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 9427 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9428 "mrbgems/mruby-compiler/core/y.tab.c" break; case 501: -#line 3636 "mrbgems/mruby-compiler/core/parse.y" +#line 3637 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); p->lstate = EXPR_BEG; p->cmd_start = TRUE; } -#line 9437 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9438 "mrbgems/mruby-compiler/core/y.tab.c" break; case 502: -#line 3642 "mrbgems/mruby-compiler/core/parse.y" +#line 3643 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_dots(p, (yyvsp[-3].nd)); } -#line 9445 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9446 "mrbgems/mruby-compiler/core/y.tab.c" break; case 503: -#line 3646 "mrbgems/mruby-compiler/core/parse.y" +#line 3647 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_dots(p, 0); } -#line 9453 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9454 "mrbgems/mruby-compiler/core/y.tab.c" break; case 505: -#line 3653 "mrbgems/mruby-compiler/core/parse.y" +#line 3654 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 9461 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9462 "mrbgems/mruby-compiler/core/y.tab.c" break; case 506: -#line 3657 "mrbgems/mruby-compiler/core/parse.y" +#line 3658 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_dots(p, (yyvsp[-3].nd)); } -#line 9469 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9470 "mrbgems/mruby-compiler/core/y.tab.c" break; case 507: -#line 3661 "mrbgems/mruby-compiler/core/parse.y" +#line 3662 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_dots(p, 0); } -#line 9477 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9478 "mrbgems/mruby-compiler/core/y.tab.c" break; case 508: -#line 3667 "mrbgems/mruby-compiler/core/parse.y" +#line 3668 "mrbgems/mruby-compiler/core/parse.y" { local_nest(p); } -#line 9485 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9486 "mrbgems/mruby-compiler/core/y.tab.c" break; case 509: -#line 3673 "mrbgems/mruby-compiler/core/parse.y" +#line 3674 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = new_kw_arg(p, (yyvsp[-1].id), cons((yyvsp[0].nd), locals_node(p))); local_unnest(p); } -#line 9495 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9496 "mrbgems/mruby-compiler/core/y.tab.c" break; case 510: -#line 3679 "mrbgems/mruby-compiler/core/parse.y" +#line 3680 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_kw_arg(p, (yyvsp[0].id), 0); local_unnest(p); } -#line 9504 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9505 "mrbgems/mruby-compiler/core/y.tab.c" break; case 511: -#line 3686 "mrbgems/mruby-compiler/core/parse.y" +#line 3687 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = new_kw_arg(p, (yyvsp[-1].id), cons((yyvsp[0].nd), locals_node(p))); local_unnest(p); } -#line 9514 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9515 "mrbgems/mruby-compiler/core/y.tab.c" break; case 512: -#line 3692 "mrbgems/mruby-compiler/core/parse.y" +#line 3693 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_kw_arg(p, (yyvsp[0].id), 0); local_unnest(p); } -#line 9523 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9524 "mrbgems/mruby-compiler/core/y.tab.c" break; case 513: -#line 3699 "mrbgems/mruby-compiler/core/parse.y" +#line 3700 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 9531 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9532 "mrbgems/mruby-compiler/core/y.tab.c" break; case 514: -#line 3703 "mrbgems/mruby-compiler/core/parse.y" +#line 3704 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 9539 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9540 "mrbgems/mruby-compiler/core/y.tab.c" break; case 515: -#line 3709 "mrbgems/mruby-compiler/core/parse.y" +#line 3710 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 9547 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9548 "mrbgems/mruby-compiler/core/y.tab.c" break; case 516: -#line 3713 "mrbgems/mruby-compiler/core/parse.y" +#line 3714 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 9555 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9556 "mrbgems/mruby-compiler/core/y.tab.c" break; case 519: -#line 3723 "mrbgems/mruby-compiler/core/parse.y" +#line 3724 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_kw_rest_args(p, nsym((yyvsp[0].id))); } -#line 9563 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9564 "mrbgems/mruby-compiler/core/y.tab.c" break; case 520: -#line 3727 "mrbgems/mruby-compiler/core/parse.y" +#line 3728 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_kw_rest_args(p, 0); } -#line 9571 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9572 "mrbgems/mruby-compiler/core/y.tab.c" break; case 521: -#line 3733 "mrbgems/mruby-compiler/core/parse.y" +#line 3734 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, (yyvsp[-3].nd), (yyvsp[-1].nd), (yyvsp[0].id)); } -#line 9579 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9580 "mrbgems/mruby-compiler/core/y.tab.c" break; case 522: -#line 3737 "mrbgems/mruby-compiler/core/parse.y" +#line 3738 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, (yyvsp[-1].nd), 0, (yyvsp[0].id)); } -#line 9587 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9588 "mrbgems/mruby-compiler/core/y.tab.c" break; case 523: -#line 3741 "mrbgems/mruby-compiler/core/parse.y" +#line 3742 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, 0, (yyvsp[-1].nd), (yyvsp[0].id)); } -#line 9595 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9596 "mrbgems/mruby-compiler/core/y.tab.c" break; case 524: -#line 3745 "mrbgems/mruby-compiler/core/parse.y" +#line 3746 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, 0, 0, (yyvsp[0].id)); } -#line 9603 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9604 "mrbgems/mruby-compiler/core/y.tab.c" break; case 525: -#line 3751 "mrbgems/mruby-compiler/core/parse.y" +#line 3752 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 9611 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9612 "mrbgems/mruby-compiler/core/y.tab.c" break; case 526: -#line 3755 "mrbgems/mruby-compiler/core/parse.y" +#line 3756 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, 0, 0, 0); } -#line 9619 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9620 "mrbgems/mruby-compiler/core/y.tab.c" break; case 527: -#line 3761 "mrbgems/mruby-compiler/core/parse.y" +#line 3762 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-5].nd), (yyvsp[-3].nd), (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 9627 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9628 "mrbgems/mruby-compiler/core/y.tab.c" break; case 528: -#line 3765 "mrbgems/mruby-compiler/core/parse.y" +#line 3766 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-7].nd), (yyvsp[-5].nd), (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 9635 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9636 "mrbgems/mruby-compiler/core/y.tab.c" break; case 529: -#line 3769 "mrbgems/mruby-compiler/core/parse.y" +#line 3770 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-3].nd), (yyvsp[-1].nd), 0, 0, (yyvsp[0].nd)); } -#line 9643 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9644 "mrbgems/mruby-compiler/core/y.tab.c" break; case 530: -#line 3773 "mrbgems/mruby-compiler/core/parse.y" +#line 3774 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-5].nd), (yyvsp[-3].nd), 0, (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 9651 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9652 "mrbgems/mruby-compiler/core/y.tab.c" break; case 531: -#line 3777 "mrbgems/mruby-compiler/core/parse.y" +#line 3778 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-3].nd), 0, (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 9659 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9660 "mrbgems/mruby-compiler/core/y.tab.c" break; case 532: -#line 3781 "mrbgems/mruby-compiler/core/parse.y" +#line 3782 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-5].nd), 0, (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 9667 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9668 "mrbgems/mruby-compiler/core/y.tab.c" break; case 533: -#line 3785 "mrbgems/mruby-compiler/core/parse.y" +#line 3786 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-1].nd), 0, 0, 0, (yyvsp[0].nd)); } -#line 9675 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9676 "mrbgems/mruby-compiler/core/y.tab.c" break; case 534: -#line 3789 "mrbgems/mruby-compiler/core/parse.y" +#line 3790 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, (yyvsp[-3].nd), (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 9683 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9684 "mrbgems/mruby-compiler/core/y.tab.c" break; case 535: -#line 3793 "mrbgems/mruby-compiler/core/parse.y" +#line 3794 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, (yyvsp[-5].nd), (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 9691 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9692 "mrbgems/mruby-compiler/core/y.tab.c" break; case 536: -#line 3797 "mrbgems/mruby-compiler/core/parse.y" +#line 3798 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, (yyvsp[-1].nd), 0, 0, (yyvsp[0].nd)); } -#line 9699 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9700 "mrbgems/mruby-compiler/core/y.tab.c" break; case 537: -#line 3801 "mrbgems/mruby-compiler/core/parse.y" +#line 3802 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, (yyvsp[-3].nd), 0, (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 9707 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9708 "mrbgems/mruby-compiler/core/y.tab.c" break; case 538: -#line 3805 "mrbgems/mruby-compiler/core/parse.y" +#line 3806 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, 0, (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 9715 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9716 "mrbgems/mruby-compiler/core/y.tab.c" break; case 539: -#line 3809 "mrbgems/mruby-compiler/core/parse.y" +#line 3810 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, 0, (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 9723 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9724 "mrbgems/mruby-compiler/core/y.tab.c" break; case 540: -#line 3813 "mrbgems/mruby-compiler/core/parse.y" +#line 3814 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, 0, 0, 0, (yyvsp[0].nd)); } -#line 9731 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9732 "mrbgems/mruby-compiler/core/y.tab.c" break; case 541: -#line 3817 "mrbgems/mruby-compiler/core/parse.y" +#line 3818 "mrbgems/mruby-compiler/core/parse.y" { local_add_f(p, intern_op(and)); (yyval.nd) = new_args(p, 0, 0, 0, 0, 0); } -#line 9740 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9741 "mrbgems/mruby-compiler/core/y.tab.c" break; case 542: -#line 3824 "mrbgems/mruby-compiler/core/parse.y" +#line 3825 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "formal argument cannot be a constant"); (yyval.nd) = 0; } -#line 9749 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9750 "mrbgems/mruby-compiler/core/y.tab.c" break; case 543: -#line 3829 "mrbgems/mruby-compiler/core/parse.y" +#line 3830 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "formal argument cannot be an instance variable"); (yyval.nd) = 0; } -#line 9758 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9759 "mrbgems/mruby-compiler/core/y.tab.c" break; case 544: -#line 3834 "mrbgems/mruby-compiler/core/parse.y" +#line 3835 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "formal argument cannot be a global variable"); (yyval.nd) = 0; } -#line 9767 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9768 "mrbgems/mruby-compiler/core/y.tab.c" break; case 545: -#line 3839 "mrbgems/mruby-compiler/core/parse.y" +#line 3840 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "formal argument cannot be a class variable"); (yyval.nd) = 0; } -#line 9776 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9777 "mrbgems/mruby-compiler/core/y.tab.c" break; case 546: -#line 3844 "mrbgems/mruby-compiler/core/parse.y" +#line 3845 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "formal argument cannot be a numbered parameter"); (yyval.nd) = 0; } -#line 9785 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9786 "mrbgems/mruby-compiler/core/y.tab.c" break; case 547: -#line 3851 "mrbgems/mruby-compiler/core/parse.y" +#line 3852 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = 0; } -#line 9793 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9794 "mrbgems/mruby-compiler/core/y.tab.c" break; case 548: -#line 3855 "mrbgems/mruby-compiler/core/parse.y" +#line 3856 "mrbgems/mruby-compiler/core/parse.y" { local_add_f(p, (yyvsp[0].id)); (yyval.id) = (yyvsp[0].id); } -#line 9802 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9803 "mrbgems/mruby-compiler/core/y.tab.c" break; case 549: -#line 3862 "mrbgems/mruby-compiler/core/parse.y" +#line 3863 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_arg(p, (yyvsp[0].id)); } -#line 9810 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9811 "mrbgems/mruby-compiler/core/y.tab.c" break; case 550: -#line 3866 "mrbgems/mruby-compiler/core/parse.y" +#line 3867 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = local_switch(p); } -#line 9818 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9819 "mrbgems/mruby-compiler/core/y.tab.c" break; case 551: -#line 3870 "mrbgems/mruby-compiler/core/parse.y" +#line 3871 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_masgn_param(p, (yyvsp[-1].nd), p->locals->car); local_resume(p, (yyvsp[-2].nd)); local_add_f(p, 0); } -#line 9828 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9829 "mrbgems/mruby-compiler/core/y.tab.c" break; case 552: -#line 3878 "mrbgems/mruby-compiler/core/parse.y" +#line 3879 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 9836 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9837 "mrbgems/mruby-compiler/core/y.tab.c" break; case 553: -#line 3882 "mrbgems/mruby-compiler/core/parse.y" +#line 3883 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 9844 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9845 "mrbgems/mruby-compiler/core/y.tab.c" break; case 554: -#line 3888 "mrbgems/mruby-compiler/core/parse.y" +#line 3889 "mrbgems/mruby-compiler/core/parse.y" { local_add_f(p, (yyvsp[-1].id)); local_nest(p); (yyval.id) = (yyvsp[-1].id); } -#line 9854 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9855 "mrbgems/mruby-compiler/core/y.tab.c" break; case 555: -#line 3896 "mrbgems/mruby-compiler/core/parse.y" +#line 3897 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = cons(nsym((yyvsp[-1].id)), cons((yyvsp[0].nd), locals_node(p))); local_unnest(p); } -#line 9864 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9865 "mrbgems/mruby-compiler/core/y.tab.c" break; case 556: -#line 3904 "mrbgems/mruby-compiler/core/parse.y" +#line 3905 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = cons(nsym((yyvsp[-1].id)), cons((yyvsp[0].nd), locals_node(p))); local_unnest(p); } -#line 9874 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9875 "mrbgems/mruby-compiler/core/y.tab.c" break; case 557: -#line 3912 "mrbgems/mruby-compiler/core/parse.y" +#line 3913 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 9882 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9883 "mrbgems/mruby-compiler/core/y.tab.c" break; case 558: -#line 3916 "mrbgems/mruby-compiler/core/parse.y" +#line 3917 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 9890 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9891 "mrbgems/mruby-compiler/core/y.tab.c" break; case 559: -#line 3922 "mrbgems/mruby-compiler/core/parse.y" +#line 3923 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 9898 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9899 "mrbgems/mruby-compiler/core/y.tab.c" break; case 560: -#line 3926 "mrbgems/mruby-compiler/core/parse.y" +#line 3927 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 9906 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9907 "mrbgems/mruby-compiler/core/y.tab.c" break; case 563: -#line 3936 "mrbgems/mruby-compiler/core/parse.y" +#line 3937 "mrbgems/mruby-compiler/core/parse.y" { local_add_f(p, (yyvsp[0].id)); (yyval.id) = (yyvsp[0].id); } -#line 9915 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9916 "mrbgems/mruby-compiler/core/y.tab.c" break; case 564: -#line 3941 "mrbgems/mruby-compiler/core/parse.y" +#line 3942 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(mul); local_add_f(p, (yyval.id)); } -#line 9924 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9925 "mrbgems/mruby-compiler/core/y.tab.c" break; case 567: -#line 3952 "mrbgems/mruby-compiler/core/parse.y" +#line 3953 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = (yyvsp[0].id); } -#line 9932 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9933 "mrbgems/mruby-compiler/core/y.tab.c" break; case 568: -#line 3956 "mrbgems/mruby-compiler/core/parse.y" +#line 3957 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(and); } -#line 9940 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9941 "mrbgems/mruby-compiler/core/y.tab.c" break; case 569: -#line 3962 "mrbgems/mruby-compiler/core/parse.y" +#line 3963 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = (yyvsp[0].id); } -#line 9948 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9949 "mrbgems/mruby-compiler/core/y.tab.c" break; case 570: -#line 3966 "mrbgems/mruby-compiler/core/parse.y" +#line 3967 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = 0; } -#line 9956 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9957 "mrbgems/mruby-compiler/core/y.tab.c" break; case 571: -#line 3972 "mrbgems/mruby-compiler/core/parse.y" +#line 3973 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); if (!(yyval.nd)) (yyval.nd) = new_nil(p); } -#line 9965 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9966 "mrbgems/mruby-compiler/core/y.tab.c" break; case 572: -#line 3976 "mrbgems/mruby-compiler/core/parse.y" +#line 3977 "mrbgems/mruby-compiler/core/parse.y" {p->lstate = EXPR_BEG;} -#line 9971 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9972 "mrbgems/mruby-compiler/core/y.tab.c" break; case 573: -#line 3977 "mrbgems/mruby-compiler/core/parse.y" +#line 3978 "mrbgems/mruby-compiler/core/parse.y" { if ((yyvsp[-1].nd) == 0) { yyerror(p, "can't define singleton method for ()."); @@ -9994,63 +9995,63 @@ yyreduce: } (yyval.nd) = (yyvsp[-1].nd); } -#line 9998 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9999 "mrbgems/mruby-compiler/core/y.tab.c" break; case 575: -#line 4003 "mrbgems/mruby-compiler/core/parse.y" +#line 4004 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 10006 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10007 "mrbgems/mruby-compiler/core/y.tab.c" break; case 576: -#line 4009 "mrbgems/mruby-compiler/core/parse.y" +#line 4010 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 10015 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10016 "mrbgems/mruby-compiler/core/y.tab.c" break; case 577: -#line 4014 "mrbgems/mruby-compiler/core/parse.y" +#line 4015 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 10023 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10024 "mrbgems/mruby-compiler/core/y.tab.c" break; case 578: -#line 4020 "mrbgems/mruby-compiler/core/parse.y" +#line 4021 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[-2].nd)); void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = cons((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 10033 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10034 "mrbgems/mruby-compiler/core/y.tab.c" break; case 579: -#line 4026 "mrbgems/mruby-compiler/core/parse.y" +#line 4027 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = cons(new_sym(p, (yyvsp[-2].id)), (yyvsp[0].nd)); } -#line 10042 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10043 "mrbgems/mruby-compiler/core/y.tab.c" break; case 580: -#line 4031 "mrbgems/mruby-compiler/core/parse.y" +#line 4032 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = cons(new_sym(p, (yyvsp[-1].id)), label_reference(p, (yyvsp[-1].id))); } -#line 10050 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10051 "mrbgems/mruby-compiler/core/y.tab.c" break; case 581: -#line 4035 "mrbgems/mruby-compiler/core/parse.y" +#line 4036 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); if (typen((yyvsp[-2].nd)->car) == NODE_DSTR) { @@ -10060,67 +10061,67 @@ yyreduce: (yyval.nd) = cons(new_sym(p, new_strsym(p, (yyvsp[-2].nd))), (yyvsp[0].nd)); } } -#line 10064 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10065 "mrbgems/mruby-compiler/core/y.tab.c" break; case 582: -#line 4045 "mrbgems/mruby-compiler/core/parse.y" +#line 4046 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = cons(new_kw_rest_args(p, 0), (yyvsp[0].nd)); } -#line 10073 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10074 "mrbgems/mruby-compiler/core/y.tab.c" break; case 595: -#line 4072 "mrbgems/mruby-compiler/core/parse.y" +#line 4073 "mrbgems/mruby-compiler/core/parse.y" { (yyval.num) = '.'; } -#line 10081 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10082 "mrbgems/mruby-compiler/core/y.tab.c" break; case 596: -#line 4076 "mrbgems/mruby-compiler/core/parse.y" +#line 4077 "mrbgems/mruby-compiler/core/parse.y" { (yyval.num) = 0; } -#line 10089 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10090 "mrbgems/mruby-compiler/core/y.tab.c" break; case 598: -#line 4083 "mrbgems/mruby-compiler/core/parse.y" +#line 4084 "mrbgems/mruby-compiler/core/parse.y" { (yyval.num) = tCOLON2; } -#line 10097 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10098 "mrbgems/mruby-compiler/core/y.tab.c" break; case 607: -#line 4104 "mrbgems/mruby-compiler/core/parse.y" +#line 4105 "mrbgems/mruby-compiler/core/parse.y" {yyerrok;} -#line 10103 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10104 "mrbgems/mruby-compiler/core/y.tab.c" break; case 609: -#line 4109 "mrbgems/mruby-compiler/core/parse.y" +#line 4110 "mrbgems/mruby-compiler/core/parse.y" { p->lineno += (yyvsp[0].num); p->column = 0; } -#line 10112 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10113 "mrbgems/mruby-compiler/core/y.tab.c" break; case 613: -#line 4121 "mrbgems/mruby-compiler/core/parse.y" +#line 4122 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = 0; } -#line 10120 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10121 "mrbgems/mruby-compiler/core/y.tab.c" break; -#line 10124 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10125 "mrbgems/mruby-compiler/core/y.tab.c" default: break; } @@ -10352,7 +10353,7 @@ yyreturn: #endif return yyresult; } -#line 4125 "mrbgems/mruby-compiler/core/parse.y" +#line 4126 "mrbgems/mruby-compiler/core/parse.y" #define pylval (*((YYSTYPE*)(p->ylval))) @@ -12660,16 +12661,17 @@ parser_yylex(parser_state *p) nvars = nvars->cdr; } nvar = intn(p->nvars->car); - if (nvar == -1) { - yywarning(p, "numbered parameter used in inner block"); + if (nvar != -2) { /* numbered parameters never appear on toplevel */ + if (nvar == -1) { + yywarning(p, "numbered parameter used in inner block"); + } + else { + p->nvars->car = nint(nvar > n ? nvar : n); + } + pylval.num = n; + p->lstate = EXPR_END; + return tNUMPARAM; } - else { - int nvars = intn(p->nvars->car); - p->nvars->car = nint(nvars > n ? nvars : n); - } - pylval.num = n; - p->lstate = EXPR_END; - return tNUMPARAM; } } /* fall through */ @@ -13163,7 +13165,7 @@ mrb_load_detect_file_cxt(mrb_state *mrb, FILE *fp, mrbc_context *c) return mrb_load_exec(mrb, mrb_parse_file_continue(mrb, fp, leading.b, bufsize, c), c); } else { - size_t binsize; + mrb_int binsize; uint8_t *bin; mrb_value bin_obj = mrb_nil_value(); /* temporary string object */ mrb_value result; @@ -13171,11 +13173,12 @@ mrb_load_detect_file_cxt(mrb_state *mrb, FILE *fp, mrbc_context *c) binsize = bin_to_uint32(leading.h.binary_size); bin_obj = mrb_str_new(mrb, NULL, binsize); bin = (uint8_t *)RSTRING_PTR(bin_obj); - memcpy(bin, leading.b, bufsize); - if (binsize > bufsize && - fread(bin + bufsize, binsize - bufsize, 1, fp) == 0) { - binsize = bufsize; - /* The error is reported by mrb_load_irep_buf_cxt() */ + if ((size_t)binsize > bufsize) { + memcpy(bin, leading.b, bufsize); + if (fread(bin + bufsize, binsize - bufsize, 1, fp) == 0) { + binsize = bufsize; + /* The error is reported by mrb_load_irep_buf_cxt() */ + } } result = mrb_load_irep_buf_cxt(mrb, bin, binsize, c); @@ -13647,12 +13650,10 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) } } n2 = n2->cdr; - if (n2) { - if (n2->car) { - dump_prefix(n2, offset+2); - printf("post:\n"); - dump_recur(mrb, n2->car, offset+3); - } + if (n2 && n2->car) { + dump_prefix(n2, offset+2); + printf("post:\n"); + dump_recur(mrb, n2->car, offset+3); } } } diff --git a/mrbgems/mruby-complex/src/complex.c b/mrbgems/mruby-complex/src/complex.c index 6a02b1e93..9e89e002d 100644 --- a/mrbgems/mruby-complex/src/complex.c +++ b/mrbgems/mruby-complex/src/complex.c @@ -168,10 +168,9 @@ complex_eq(mrb_state *mrb, mrb_value x) return mrb_bool_value(mrb_complex_eq(mrb, x, y)); } -static mrb_value -complex_add(mrb_state *mrb, mrb_value x) +mrb_value +mrb_complex_add(mrb_state *mrb, mrb_value x, mrb_value y) { - mrb_value y = mrb_get_arg1(mrb); struct mrb_complex *p1 = complex_ptr(mrb, x); switch (mrb_type(y)) { @@ -190,9 +189,15 @@ complex_add(mrb_state *mrb, mrb_value x) } static mrb_value -complex_sub(mrb_state *mrb, mrb_value x) +complex_add(mrb_state *mrb, mrb_value x) { mrb_value y = mrb_get_arg1(mrb); + return mrb_complex_add(mrb, x, y); +} + +mrb_value +mrb_complex_sub(mrb_state *mrb, mrb_value x, mrb_value y) +{ struct mrb_complex *p1 = complex_ptr(mrb, x); switch (mrb_type(y)) { @@ -211,9 +216,15 @@ complex_sub(mrb_state *mrb, mrb_value x) } static mrb_value -complex_mul(mrb_state *mrb, mrb_value x) +complex_sub(mrb_state *mrb, mrb_value x) { mrb_value y = mrb_get_arg1(mrb); + return mrb_complex_sub(mrb, x, y); +} + +mrb_value +mrb_complex_mul(mrb_state *mrb, mrb_value x, mrb_value y) +{ struct mrb_complex *p1 = complex_ptr(mrb, x); switch (mrb_type(y)) { @@ -232,6 +243,13 @@ complex_mul(mrb_state *mrb, mrb_value x) } } +static mrb_value +complex_mul(mrb_state *mrb, mrb_value x) +{ + mrb_value y = mrb_get_arg1(mrb); + return mrb_complex_mul(mrb, x, y); +} + /* Arithmetic on (significand, exponent) pairs avoids premature overflow in complex division */ struct float_pair { @@ -272,11 +290,10 @@ div_pair(struct float_pair *q, struct float_pair const *a, q->x = a->x - b->x; } -static mrb_value -complex_div(mrb_state *mrb, mrb_value self) +mrb_value +mrb_complex_div(mrb_state *mrb, mrb_value self, mrb_value rhs) { struct mrb_complex *a, *b; - mrb_value rhs = mrb_get_arg1(mrb); a = complex_ptr(mrb, self); if (mrb_type(rhs) != MRB_TT_COMPLEX) { @@ -324,78 +341,11 @@ complex_div(mrb_state *mrb, mrb_value self) return complex_new(mrb, F(ldexp)(zr.s, zr.x), F(ldexp)(zi.s, zi.x)); } -mrb_int mrb_div_int(mrb_state *mrb, mrb_int x, mrb_int y); -mrb_value mrb_rational_new(mrb_state *mrb, mrb_int n, mrb_int d); -mrb_value mrb_rational_div(mrb_state *mrb, mrb_value x); - -/* 15.2.8.3.4 */ -/* - * redefine Integer#/ - */ static mrb_value -cpx_int_div(mrb_state *mrb, mrb_value x) +complex_div(mrb_state *mrb, mrb_value x) { mrb_value y = mrb_get_arg1(mrb); - mrb_int a = mrb_integer(x); - - if (mrb_integer_p(y)) { - mrb_int div = mrb_div_int(mrb, a, mrb_integer(y)); - return mrb_int_value(mrb, div); - } - switch (mrb_type(y)) { -#ifdef MRB_USE_RATIONAL - case MRB_TT_RATIONAL: - return mrb_rational_div(mrb, mrb_rational_new(mrb, a, 1)); -#endif - case MRB_TT_COMPLEX: - x = complex_new(mrb, (mrb_float)a, 0); - return complex_div(mrb, x); - default: - return mrb_float_value(mrb, mrb_div_float((mrb_float)a, mrb_as_float(mrb, y))); - } -} - -/* 15.2.9.3.19(x) */ -/* - * redefine Integer#quo - */ - -static mrb_value -cpx_int_quo(mrb_state *mrb, mrb_value x) -{ - mrb_value y = mrb_get_arg1(mrb); - mrb_int a = mrb_integer(x); - - switch (mrb_type(y)) { -#ifdef MRB_USE_RATIONAL - case MRB_TT_RATIONAL: - x = mrb_rational_new(mrb, a, 1); - return mrb_funcall_id(mrb, x, MRB_OPSYM(div), 1, y); -#endif - case MRB_TT_COMPLEX: - x = complex_new(mrb, (mrb_float)a, 0); - return complex_div(mrb, x); - default: - return mrb_float_value(mrb, mrb_div_float((mrb_float)a, mrb_as_float(mrb, y))); - } -} - -static mrb_value -cpx_flo_div(mrb_state *mrb, mrb_value x) -{ - mrb_float a = mrb_float(x); - mrb_value y = mrb_get_arg1(mrb); - - switch(mrb_type(y)) { - case MRB_TT_COMPLEX: - return complex_div(mrb, complex_new(mrb, a, 0)); - case MRB_TT_FLOAT: - a = mrb_div_float(a, mrb_float(y)); - return mrb_float_value(mrb, a); - default: - a = mrb_div_float(a, mrb_as_float(mrb, y)); - return mrb_float_value(mrb, a); - } + return mrb_complex_div(mrb, x, y); } void mrb_mruby_complex_gem_init(mrb_state *mrb) @@ -424,10 +374,6 @@ void mrb_mruby_complex_gem_init(mrb_state *mrb) mrb_define_method(mrb, comp, "/", complex_div, MRB_ARGS_REQ(1)); mrb_define_method(mrb, comp, "quo", complex_div, MRB_ARGS_REQ(1)); mrb_define_method(mrb, comp, "==", complex_eq, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, mrb->integer_class, "/", cpx_int_div, MRB_ARGS_REQ(1)); /* override */ - mrb_define_method(mrb, mrb->integer_class, "quo", cpx_int_quo, MRB_ARGS_REQ(1)); /* override */ - mrb_define_method(mrb, mrb->float_class, "/", cpx_flo_div, MRB_ARGS_REQ(1)); /* override */ - mrb_define_method(mrb, mrb->float_class, "quo", cpx_flo_div, MRB_ARGS_REQ(1)); /* override */ } void diff --git a/mrbgems/mruby-errno/.gitignore b/mrbgems/mruby-errno/.gitignore new file mode 100644 index 000000000..ceeb05b41 --- /dev/null +++ b/mrbgems/mruby-errno/.gitignore @@ -0,0 +1 @@ +/tmp diff --git a/mrbgems/mruby-errno/.travis.yml b/mrbgems/mruby-errno/.travis.yml new file mode 100644 index 000000000..ffe227284 --- /dev/null +++ b/mrbgems/mruby-errno/.travis.yml @@ -0,0 +1,2 @@ +script: + - "ruby run_test.rb all test" diff --git a/mrbgems/mruby-errno/README.md b/mrbgems/mruby-errno/README.md new file mode 100644 index 000000000..aa9a782b5 --- /dev/null +++ b/mrbgems/mruby-errno/README.md @@ -0,0 +1,25 @@ +# mruby-errno + +Errno module for mruby + +## License + +Copyright (c) 2013 Internet Initiative Japan Inc. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/mrbgems/mruby-errno/mrbgem.rake b/mrbgems/mruby-errno/mrbgem.rake new file mode 100644 index 000000000..ba3d60dae --- /dev/null +++ b/mrbgems/mruby-errno/mrbgem.rake @@ -0,0 +1,6 @@ +MRuby::Gem::Specification.new('mruby-errno') do |spec| + spec.license = 'MIT' + spec.authors = 'Internet Initiative Japan Inc.' + + spec.cc.include_paths << "#{build.root}/src" +end diff --git a/mrbgems/mruby-errno/run_test.rb b/mrbgems/mruby-errno/run_test.rb new file mode 100644 index 000000000..d9566a2a6 --- /dev/null +++ b/mrbgems/mruby-errno/run_test.rb @@ -0,0 +1,26 @@ +#!/usr/bin/env ruby +# +# mrbgems test runner +# + +gemname = File.basename(File.dirname(File.expand_path __FILE__)) + +if __FILE__ == $0 + repository, dir = 'https://github.com/mruby/mruby.git', 'tmp/mruby' + build_args = ARGV + build_args = ['all', 'test'] if build_args.nil? or build_args.empty? + + Dir.mkdir 'tmp' unless File.exist?('tmp') + unless File.exist?(dir) + system "git clone #{repository} #{dir}" + end + + exit system(%Q[cd #{dir}; MRUBY_CONFIG=#{File.expand_path __FILE__} ruby minirake #{build_args.join(' ')}]) +end + +MRuby::Build.new do |conf| + toolchain :gcc + conf.gembox 'default' + + conf.gem File.expand_path(File.dirname(__FILE__)) +end diff --git a/mrbgems/mruby-errno/src/errno.c b/mrbgems/mruby-errno/src/errno.c new file mode 100644 index 000000000..e96d321a3 --- /dev/null +++ b/mrbgems/mruby-errno/src/errno.c @@ -0,0 +1,191 @@ +#include "mruby.h" +#include "mruby/array.h" +#include "mruby/class.h" +#include "mruby/error.h" +#include "mruby/hash.h" +#include "mruby/numeric.h" +#include "mruby/string.h" +#include "mruby/variable.h" +#include "mruby/internal.h" +#include +#include +#include + +static const struct { +#ifdef MRB_NO_PRESYM +#define itsdefined(name, sym) { #name, name }, + const char *name; +#else +#define itsdefined(name, sym) { sym, name }, + mrb_sym sym; +#endif + int eno; +} e2c[] = { +#define itsnotdefined(name, sym) +#include "known_errors_def.cstub" +#undef itsdefined +#undef itsnotdefined +}; + +#ifdef MRB_NO_PRESYM +#define ENTRY_SYM(e) mrb_intern_static(mrb, (e).name, strlen((e).name)) +#else +#define ENTRY_SYM(e) (e).sym +#endif + +#define E2C_LEN (sizeof(e2c) / sizeof(e2c[0])) + +static void +mrb_sce_init(mrb_state *mrb, mrb_value self, mrb_value m, int n) +{ + mrb_value str; + struct RClass *m_errno; + int no_errno = (n < 0); + char buf[20]; + + m_errno = mrb_module_get_id(mrb, MRB_SYM(Errno)); + if (!no_errno) { + size_t i; + + for (i=0; i < E2C_LEN; i++) { + if (e2c[i].eno == n) { + mrb_basic_ptr(self)->c = mrb_class_get_under_id(mrb, m_errno, ENTRY_SYM(e2c[i])); + str = mrb_str_new_cstr(mrb, strerror(n)); + break; + } + } + if (i == E2C_LEN) { + mrb_iv_set(mrb, self, MRB_SYM(errno), mrb_fixnum_value(n)); + str = mrb_str_new_cstr(mrb, "Unknown error: "); + char *bp = mrb_int_to_cstr(buf, sizeof(buf), n, 10); + mrb_str_cat2(mrb, str, bp); + } + } + else { + str = mrb_str_new_cstr(mrb, "unknown error"); + } + if (!mrb_nil_p(m)) { + mrb_str_cat2(mrb, str, " - "); + mrb_str_append(mrb, str, m); + } + mrb_exc_mesg_set(mrb, mrb_exc_ptr(self), str); +} + +static mrb_value +mrb_sce_init_m(mrb_state *mrb, mrb_value self) +{ + mrb_value m; + mrb_int n; + + if (mrb_get_args(mrb, "o|i", &m, &n) == 1) { + if (mrb_fixnum_p(m)) { + n = mrb_fixnum(m); + m = mrb_nil_value(); + } + else { + n = -1; + } + } + mrb_sce_init(mrb, self, m, (int)n); + return self; +} + +static mrb_value +mrb_sce_errno(mrb_state *mrb, mrb_value self) +{ + struct RClass *c; + mrb_sym sym; + + c = mrb_class(mrb, self); + sym = MRB_SYM(Errno); + if (mrb_const_defined_at(mrb, mrb_obj_value(c), sym)) { + return mrb_const_get(mrb, mrb_obj_value(c), sym); + } else { + sym = MRB_SYM(errno); + return mrb_attr_get(mrb, self, sym); + } +} + +static mrb_value +mrb_sce_sys_fail(mrb_state *mrb, mrb_value cls) +{ + struct RClass *sce; + mrb_value msg; + mrb_int no = -1; + mrb_int argc; + + mrb->c->ci->mid = 0; + sce = mrb_class_get_id(mrb, MRB_SYM(SystemCallError)); + argc = mrb_get_args(mrb, "i|S", &no, &msg); + + struct RBasic* e = mrb_obj_alloc(mrb, MRB_TT_EXCEPTION, sce); + mrb_value exc = mrb_obj_value(e); + if (argc == 1) { + msg = mrb_nil_value(); + } + exc = mrb_obj_value(e); + mrb_sce_init(mrb, exc, msg, (int)no); + mrb_exc_raise(mrb, exc); + return mrb_nil_value(); /* NOTREACHED */ +} + +static mrb_value +mrb_exxx_init(mrb_state *mrb, mrb_value self) +{ + mrb_value m, no, str; + + no = mrb_const_get(mrb, mrb_obj_value(mrb_class(mrb, self)), MRB_SYM(Errno)); + str = mrb_str_new_cstr(mrb, strerror((int)mrb_fixnum(no))); + + m = mrb_nil_value(); + mrb_get_args(mrb, "|S", &m); + if (!mrb_nil_p(m)) { + mrb_str_cat2(mrb, str, " - "); + mrb_str_append(mrb, str, m); + } + mrb_exc_mesg_set(mrb, mrb_exc_ptr(self), str); + return self; +} + +void +mrb_mruby_errno_gem_init(mrb_state *mrb) +{ + struct RClass *e, *eno, *sce, *ste; + mrb_value noerror; + + ste = mrb_class_get_id(mrb, MRB_SYM(StandardError)); + + sce = mrb_define_class(mrb, "SystemCallError", ste); + mrb_define_class_method(mrb, sce, "_sys_fail", mrb_sce_sys_fail, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, sce, "errno", mrb_sce_errno, MRB_ARGS_NONE()); + mrb_define_method(mrb, sce, "initialize", mrb_sce_init_m, MRB_ARGS_ARG(1, 1)); + + eno = mrb_define_module_id(mrb, MRB_SYM(Errno)); + + e = mrb_define_class_under_id(mrb, eno, MRB_SYM(NOERROR), sce); + mrb_define_const_id(mrb, e, MRB_SYM(Errno), mrb_fixnum_value(0)); + mrb_define_method(mrb, e, "initialize", mrb_exxx_init, MRB_ARGS_OPT(1)); + //mrb_define_method(mrb, e, "===", mrb_exxx_cmp, MRB_ARGS_REQ(1)); + noerror = mrb_obj_value(e); + +#define itsdefined(name, sym) \ + do { \ + int ai = mrb_gc_arena_save(mrb); \ + e = mrb_define_class_under_id(mrb, eno, sym, sce); \ + mrb_define_const_id(mrb, e, MRB_SYM(Errno), mrb_fixnum_value(name)); \ + mrb_define_method(mrb, e, "initialize", mrb_exxx_init, MRB_ARGS_OPT(1)); \ + mrb_gc_arena_restore(mrb, ai); \ + } while (0); + +#define itsnotdefined(name, sym) \ + do { \ + mrb_define_const_id(mrb, eno, sym, noerror); \ + } while (0); + +#include "known_errors_def.cstub" +} + +void +mrb_mruby_errno_gem_final(mrb_state *mrb) +{ +} diff --git a/mrbgems/mruby-errno/src/gen.rb b/mrbgems/mruby-errno/src/gen.rb new file mode 100755 index 000000000..a9a6c8ee0 --- /dev/null +++ b/mrbgems/mruby-errno/src/gen.rb @@ -0,0 +1,18 @@ +#!/usr/bin/env ruby + +Dir.chdir(File.dirname($0)) + +d = File.open("known_errors_def.cstub", "w") + +IO.readlines("known_errors.def").each { |name| + next if name =~ /^#/ + name.strip! + + d.write <cibase->n = len; + c->cibase->n = (uint8_t)len; value = c->stbase[0] = MRB_PROC_ENV(c->cibase->proc)->stack[0]; } else { diff --git a/mrbgems/mruby-io/README.md b/mrbgems/mruby-io/README.md index c07a6e89b..3e601b62a 100644 --- a/mrbgems/mruby-io/README.md +++ b/mrbgems/mruby-io/README.md @@ -16,158 +16,158 @@ Add the line below to your build configuration. * -| method | mruby-io | memo | -| ------------------------- | -------- | ---- | -| IO.binread | | | -| IO.binwrite | | | -| IO.copy_stream | | | -| IO.new, IO.for_fd, IO.open | o | | -| IO.foreach | | | -| IO.pipe | o | | -| IO.popen | o | | -| IO.read | o | | -| IO.readlines | | | -| IO.select | o | | -| IO.sysopen | o | | -| IO.try_convert | | | -| IO.write | | | -| IO#<< | | | -| IO#advise | | | -| IO#autoclose= | | | -| IO#autoclose? | | | -| IO#binmode | | | -| IO#binmode? | | | +| method | mruby-io | memo | +|----------------------------|----------|----------| +| IO.binread | | | +| IO.binwrite | | | +| IO.copy_stream | | | +| IO.new, IO.for_fd, IO.open | o | | +| IO.foreach | | | +| IO.pipe | o | | +| IO.popen | o | | +| IO.read | o | | +| IO.readlines | | | +| IO.select | o | | +| IO.sysopen | o | | +| IO.try_convert | | | +| IO.write | | | +| IO#<< | | | +| IO#advise | | | +| IO#autoclose= | | | +| IO#autoclose? | | | +| IO#binmode | | | +| IO#binmode? | | | | IO#bytes | | obsolete | | IO#chars | | obsolete | -| IO#clone, IO#dup | o | | -| IO#close | o | | -| IO#close_on_exec= | o | | -| IO#close_on_exec? | o | | -| IO#close_read | | | -| IO#close_write | | | -| IO#closed? | o | | +| IO#clone, IO#dup | o | | +| IO#close | o | | +| IO#close_on_exec= | o | | +| IO#close_on_exec? | o | | +| IO#close_read | | | +| IO#close_write | | | +| IO#closed? | o | | | IO#codepoints | | obsolete | -| IO#each_byte | o | | -| IO#each_char | o | | -| IO#each_codepoint | | | -| IO#each_line | o | | -| IO#eof, IO#eof? | o | | -| IO#external_encoding | | | -| IO#fcntl | | | -| IO#fdatasync | | | -| IO#fileno, IO#to_i | o | | -| IO#flush | o | | -| IO#fsync | | | -| IO#getbyte | o | | -| IO#getc | o | | -| IO#gets | o | | -| IO#internal_encoding | | | -| IO#ioctl | | | -| IO#isatty, IO#tty? | o | | -| IO#lineno | | | -| IO#lineno= | | | +| IO#each_byte | o | | +| IO#each_char | o | | +| IO#each_codepoint | | | +| IO#each_line | o | | +| IO#eof, IO#eof? | o | | +| IO#external_encoding | | | +| IO#fcntl | | | +| IO#fdatasync | | | +| IO#fileno, IO#to_i | o | | +| IO#flush | o | | +| IO#fsync | | | +| IO#getbyte | o | | +| IO#getc | o | | +| IO#gets | o | | +| IO#internal_encoding | | | +| IO#ioctl | | | +| IO#isatty, IO#tty? | o | | +| IO#lineno | | | +| IO#lineno= | | | | IO#lines | | obsolete | -| IO#pid | o | | -| IO#pos, IO#tell | o | | -| IO#pos= | o | | -| IO#print | o | | -| IO#printf | o | | -| IO#putc | | | -| IO#puts | o | | -| IO#read | o | | -| IO#read_nonblock | | | -| IO#readbyte | o | | -| IO#readchar | o | | -| IO#readline | o | | -| IO#readlines | o | | -| IO#readpartial | | | -| IO#reopen | | | -| IO#rewind | | | -| IO#seek | o | | -| IO#set_encoding | | | -| IO#stat | | | -| IO#sync | o | | -| IO#sync= | o | | -| IO#sysread | o | | -| IO#sysseek | o | | -| IO#syswrite | o | | -| IO#to_io | | | -| IO#ungetbyte | o | | -| IO#ungetc | o | | -| IO#write | o | | -| IO#write_nonblock | | | +| IO#pid | o | | +| IO#pos, IO#tell | o | | +| IO#pos= | o | | +| IO#print | o | | +| IO#printf | o | | +| IO#putc | | | +| IO#puts | o | | +| IO#read | o | | +| IO#read_nonblock | | | +| IO#readbyte | o | | +| IO#readchar | o | | +| IO#readline | o | | +| IO#readlines | o | | +| IO#readpartial | | | +| IO#reopen | | | +| IO#rewind | | | +| IO#seek | o | | +| IO#set_encoding | | | +| IO#stat | | | +| IO#sync | o | | +| IO#sync= | o | | +| IO#sysread | o | | +| IO#sysseek | o | | +| IO#syswrite | o | | +| IO#to_io | | | +| IO#ungetbyte | o | | +| IO#ungetc | o | | +| IO#write | o | | +| IO#write_nonblock | | | ### File * -| method | mruby-io | memo | -| --------------------------- | -------- | ---- | -| File.absolute_path | | | -| File.atime | | | -| File.basename | o | | +| method | mruby-io | memo | +|-----------------------------|----------|----------| +| File.absolute_path | | | +| File.atime | | | +| File.basename | o | | | File.blockdev? | | FileTest | | File.chardev? | | FileTest | -| File.chmod | o | | -| File.chown | | | -| File.ctime | | | -| File.delete, File.unlink | o | | -| File.directory? | o | FileTest | -| File.dirname | o | | +| File.chmod | o | | +| File.chown | | | +| File.ctime | | | +| File.delete, File.unlink | o | | +| File.directory? | o | FileTest | +| File.dirname | o | | | File.executable? | | FileTest | | File.executable_real? | | FileTest | -| File.exist?, exists? | o | FileTest | -| File.expand_path | o | | -| File.extname | o | | -| File.file? | o | FileTest | -| File.fnmatch, File.fnmatch? | | | -| File.ftype | | | +| File.exist?, exists? | o | FileTest | +| File.expand_path | o | | +| File.extname | o | | +| File.file? | o | FileTest | +| File.fnmatch, File.fnmatch? | | | +| File.ftype | | | | File.grpowned? | | FileTest | | File.identical? | | FileTest | -| File.join | o | | -| File.lchmod | | | -| File.lchown | | | -| File.link | | | -| File.lstat | | | -| File.mtime | | | -| File.new, File.open | o | | +| File.join | o | | +| File.lchmod | | | +| File.lchown | | | +| File.link | | | +| File.lstat | | | +| File.mtime | | | +| File.new, File.open | o | | | File.owned? | | FileTest | -| File.path | | | -| File.pipe? | o | FileTest | +| File.path | | | +| File.pipe? | o | FileTest | | File.readable? | | FileTest | | File.readable_real? | | FileTest | -| File.readlink | o | | -| File.realdirpath | | | -| File.realpath | o | | -| File.rename | o | | +| File.readlink | o | | +| File.realdirpath | | | +| File.realpath | o | | +| File.rename | o | | | File.setgid? | | FileTest | | File.setuid? | | FileTest | -| File.size | o | | -| File.size? | o | FileTest | -| File.socket? | o | FileTest | -| File.split | | | -| File.stat | | | +| File.size | o | | +| File.size? | o | FileTest | +| File.socket? | o | FileTest | +| File.split | | | +| File.stat | | | | File.sticky? | | FileTest | -| File.symlink | | | -| File.symlink? | o | FileTest | -| File.truncate | | | -| File.umask | o | | -| File.utime | | | -| File.world_readable? | | | -| File.world_writable? | | | +| File.symlink | | | +| File.symlink? | o | FileTest | +| File.truncate | | | +| File.umask | o | | +| File.utime | | | +| File.world_readable? | | | +| File.world_writable? | | | | File.writable? | | FileTest | | File.writable_real? | | FileTest | -| File.zero? | o | FileTest | -| File#atime | | | -| File#chmod | | | -| File#chown | | | -| File#ctime | | | -| File#flock | o | | -| File#lstat | | | -| File#mtime | | | -| File#path, File#to_path | o | | -| File#size | | | -| File#truncate | | | +| File.zero? | o | FileTest | +| File#atime | | | +| File#chmod | | | +| File#chown | | | +| File#ctime | | | +| File#flock | o | | +| File#lstat | | | +| File#mtime | | | +| File#path, File#to_path | o | | +| File#size | | | +| File#truncate | | | ## License diff --git a/mrbgems/mruby-io/src/io.c b/mrbgems/mruby-io/src/io.c index 765dc9051..209a37f31 100644 --- a/mrbgems/mruby-io/src/io.c +++ b/mrbgems/mruby-io/src/io.c @@ -11,6 +11,7 @@ #include "mruby/variable.h" #include "mruby/ext/io.h" #include "mruby/error.h" +#include "mruby/internal.h" #include "mruby/presym.h" #include diff --git a/mrbgems/mruby-kernel-ext/src/kernel.c b/mrbgems/mruby-kernel-ext/src/kernel.c index 976615f6e..a0c274dcf 100644 --- a/mrbgems/mruby-kernel-ext/src/kernel.c +++ b/mrbgems/mruby-kernel-ext/src/kernel.c @@ -6,6 +6,7 @@ #include #include #include +#include #include static mrb_value @@ -166,7 +167,7 @@ arg_error: mrb_raise(mrb, E_ARGUMENT_ERROR, "base specified for non string value"); } /* to raise TypeError */ - return mrb_to_integer(mrb, val); + return mrb_ensure_integer_type(mrb, val); } #ifndef MRB_NO_FLOAT @@ -190,7 +191,7 @@ mrb_f_float(mrb_state *mrb, mrb_value self) if (mrb_string_p(arg)) { return mrb_float_value(mrb, mrb_str_to_dbl(mrb, arg, TRUE)); } - return mrb_to_float(mrb, arg); + return mrb_ensure_float_type(mrb, arg); } #endif diff --git a/mrbgems/mruby-metaprog/src/metaprog.c b/mrbgems/mruby-metaprog/src/metaprog.c index 4bf31cbeb..70da56c47 100644 --- a/mrbgems/mruby-metaprog/src/metaprog.c +++ b/mrbgems/mruby-metaprog/src/metaprog.c @@ -5,6 +5,7 @@ #include "mruby/proc.h" #include "mruby/class.h" #include "mruby/string.h" +#include #include "mruby/presym.h" typedef enum { @@ -575,6 +576,39 @@ mrb_mod_instance_methods(mrb_state *mrb, mrb_value mod) return mrb_class_instance_method_list(mrb, recur, c); } +static int +undefined_method_i(mrb_state *mrb, mrb_sym mid, mrb_method_t m, void *p) +{ + mrb_value ary = *(mrb_value*)p; + + if (MRB_METHOD_UNDEF_P(m)) { + mrb_ary_push(mrb, ary, mrb_symbol_value(mid)); + } + return 0; +} + +/* + * call-seq: + * mod.undefined_methods() -> array + * + * Returns an array containing the names of the undefined methods of the module/class. + */ +static mrb_value +mrb_mod_undefined_methods(mrb_state *mrb, mrb_value mod) +{ + struct RClass *m = mrb_class_ptr(mod); + mrb_get_args(mrb, ""); /* no argument */ + + mrb_value ary = mrb_ary_new(mrb); + + if (m->flags & MRB_FL_CLASS_IS_PREPENDED) { + MRB_CLASS_ORIGIN(m); + } + mrb_mt_foreach(mrb, m, undefined_method_i, (void*)&ary); + + return ary; +} + /* 15.2.2.4.41 */ /* * call-seq: @@ -663,6 +697,7 @@ mrb_mruby_metaprog_gem_init(mrb_state* mrb) mrb_define_method(mrb, mod, "class_variable_set", mrb_mod_cvar_set, MRB_ARGS_REQ(2)); /* 15.2.2.4.18 */ mrb_define_method(mrb, mod, "included_modules", mrb_mod_included_modules, MRB_ARGS_NONE()); /* 15.2.2.4.30 */ mrb_define_method(mrb, mod, "instance_methods", mrb_mod_instance_methods, MRB_ARGS_ANY()); /* 15.2.2.4.33 */ + mrb_define_method(mrb, mod, "undefined_instance_methods", mrb_mod_undefined_methods, MRB_ARGS_NONE()); mrb_define_method(mrb, mod, "remove_method", mrb_mod_remove_method, MRB_ARGS_ANY()); /* 15.2.2.4.41 */ mrb_define_method(mrb, mod, "method_removed", mrb_f_nil, MRB_ARGS_REQ(1)); mrb_define_method(mrb, mod, "constants", mrb_mod_constants, MRB_ARGS_OPT(1)); /* 15.2.2.4.24 */ diff --git a/mrbgems/mruby-method/src/method.c b/mrbgems/mruby-method/src/method.c index 85e8872e2..093d4c5a0 100644 --- a/mrbgems/mruby-method/src/method.c +++ b/mrbgems/mruby-method/src/method.c @@ -4,6 +4,7 @@ #include "mruby/variable.h" #include "mruby/proc.h" #include "mruby/string.h" +#include "mruby/internal.h" #include "mruby/presym.h" mrb_noreturn void mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args); diff --git a/mrbgems/mruby-numeric-ext/src/numeric_ext.c b/mrbgems/mruby-numeric-ext/src/numeric_ext.c index 2f2a6c755..7ea0e9772 100644 --- a/mrbgems/mruby-numeric-ext/src/numeric_ext.c +++ b/mrbgems/mruby-numeric-ext/src/numeric_ext.c @@ -1,7 +1,39 @@ #include #include +#include #include +#ifdef MRB_USE_BIGINT +static mrb_value +bint_allbits(mrb_state *mrb, mrb_value x, mrb_value y) +{ + y = mrb_as_bint(mrb, y); + x = mrb_bint_and(mrb, x, y); + if (mrb_bint_cmp(mrb, x, y) == 0) return mrb_true_value(); + return mrb_false_value(); +} + +static mrb_value +bint_anybits(mrb_state *mrb, mrb_value x, mrb_value y) +{ + y = mrb_as_bint(mrb, y); + x = mrb_bint_and(mrb, x, y); + if (mrb_bint_cmp(mrb, x, mrb_fixnum_value(0)) != 0) + return mrb_true_value(); + return mrb_false_value(); +} + +static mrb_value +bint_nobits(mrb_state *mrb, mrb_value x, mrb_value y) +{ + y = mrb_as_bint(mrb, y); + x = mrb_bint_and(mrb, x, y); + if (mrb_bint_cmp(mrb, x, mrb_fixnum_value(0)) == 0) + return mrb_true_value(); + return mrb_false_value(); +} +#endif + /* * call-seq: * int.allbits?(mask) -> true or false @@ -11,6 +43,9 @@ static mrb_value int_allbits(mrb_state *mrb, mrb_value self) { +#ifdef MRB_USE_BIGINT + return bint_allbits(mrb, self, mrb_get_arg1(mrb)); +#endif mrb_int n, m; mrb_get_args(mrb, "i", &m); @@ -27,6 +62,9 @@ int_allbits(mrb_state *mrb, mrb_value self) static mrb_value int_anybits(mrb_state *mrb, mrb_value self) { +#ifdef MRB_USE_BIGINT + return bint_anybits(mrb, self, mrb_get_arg1(mrb)); +#endif mrb_int n, m; mrb_get_args(mrb, "i", &m); @@ -43,6 +81,9 @@ int_anybits(mrb_state *mrb, mrb_value self) static mrb_value int_nobits(mrb_state *mrb, mrb_value self) { +#ifdef MRB_USE_BIGINT + return bint_nobits(mrb, self, mrb_get_arg1(mrb)); +#endif mrb_int n, m; mrb_get_args(mrb, "i", &m); @@ -50,11 +91,9 @@ int_nobits(mrb_state *mrb, mrb_value self) return mrb_bool_value((n & m) == 0); } -static void -zerodiv(mrb_state *mrb) -{ - mrb_raise(mrb, E_ZERODIV_ERROR, "divided by 0"); -} +#ifndef MRB_NO_FLOAT +static mrb_value flo_remainder(mrb_state *mrb, mrb_value self); +#endif /* * call-seq: @@ -70,24 +109,82 @@ int_remainder(mrb_state *mrb, mrb_value x) mrb_value y = mrb_get_arg1(mrb); mrb_int a, b; +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + if (mrb_integer_p(y) || mrb_bigint_p(y)) { + return mrb_bint_rem(mrb, x, y); + } + return flo_remainder(mrb, mrb_float_value(mrb, mrb_as_float(mrb, x))); + } +#endif a = mrb_integer(x); if (mrb_integer_p(y)) { b = mrb_integer(y); - if (b == 0) zerodiv(mrb); + if (b == 0) mrb_int_zerodiv(mrb); if (a == MRB_INT_MIN && b == -1) return mrb_fixnum_value(0); return mrb_int_value(mrb, a % b); } #ifdef MRB_NO_FLOAT mrb_raise(mrb, E_TYPE_ERROR, "non integer remainder"); #else - mrb_float n = (mrb_float)a; - mrb_float m = mrb_as_float(mrb, y); - - if (isinf(m)) return mrb_float_value(mrb, n); - return mrb_float_value(mrb, n-m*trunc(n/m)); + return flo_remainder(mrb, mrb_float_value(mrb, mrb_as_float(mrb, x))); #endif } +mrb_value mrb_int_pow(mrb_state *mrb, mrb_value x); + +/* + * call-seq: + * integer.pow(numeric) -> numeric + * integer.pow(integer, integer) -> integer + * + * Returns (modular) exponentiation as: + * + * a.pow(b) #=> same as a**b + * a.pow(b, m) #=> same as (a**b) % m, but avoids huge temporary values + */ +static mrb_value +int_powm(mrb_state *mrb, mrb_value x) +{ + mrb_value m; + mrb_int base, exp, mod, result = 1; + + if (mrb_get_argc(mrb) == 1) { + return mrb_int_pow(mrb, x); + } + mrb_get_args(mrb, "io", &exp, &m); + if (exp < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "int.pow(n,m): n must be positive"); +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_bint_powm(mrb, x, exp, m); + } + if (mrb_bigint_p(m)) { + return mrb_bint_powm(mrb, mrb_bint_new_int(mrb, mrb_integer(x)), exp, m); + } +#endif + if (!mrb_integer_p(m)) mrb_raise(mrb, E_TYPE_ERROR, "int.pow(n,m): m must be integer"); + mod = mrb_integer(m); + if (mod < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "int.pow(n,m): m must be positive"); + if (mod == 0) mrb_int_zerodiv(mrb); + if (mod == 1) return mrb_fixnum_value(0); + base = mrb_integer(x); + for (;;) { + if (exp & 1) { + if (mrb_int_mul_overflow(result, base, &result)) { + mrb_int_overflow(mrb, "pow"); + } + result %= mod; + } + exp >>= 1; + if (exp == 0) break; + if (mrb_int_mul_overflow(base, base, &base)) { + mrb_int_overflow(mrb, "pow"); + } + base %= mod; + } + return mrb_int_value(mrb, result); +} + #ifndef MRB_NO_FLOAT static mrb_value flo_remainder(mrb_state *mrb, mrb_value self) @@ -96,7 +193,7 @@ flo_remainder(mrb_state *mrb, mrb_value self) a = mrb_float(self); mrb_get_args(mrb, "f", &b); - if (b == 0) zerodiv(mrb); + if (b == 0) mrb_int_zerodiv(mrb); if (isinf(b)) return mrb_float_value(mrb, a); return mrb_float_value(mrb, a-b*trunc(a/b)); } @@ -114,6 +211,8 @@ mrb_mruby_numeric_ext_gem_init(mrb_state* mrb) mrb_define_alias(mrb, i, "modulo", "%"); mrb_define_method(mrb, i, "remainder", int_remainder, MRB_ARGS_REQ(1)); + mrb_define_method_id(mrb, i, MRB_SYM(pow), int_powm, MRB_ARGS_ARG(1,1)); + #ifndef MRB_NO_FLOAT struct RClass *f = mrb_class_get(mrb, "Float"); diff --git a/mrbgems/mruby-numeric-ext/test/numeric.rb b/mrbgems/mruby-numeric-ext/test/numeric.rb index efdf25a34..7ff6bdb97 100644 --- a/mrbgems/mruby-numeric-ext/test/numeric.rb +++ b/mrbgems/mruby-numeric-ext/test/numeric.rb @@ -19,3 +19,9 @@ assert('Integer#nonzero?') do assert_equal nil, 0.nonzero? assert_equal 1000, 1000.nonzero? end + +assert('Integer#pow') do + assert_equal(8, 2.pow(3)) + assert_equal(-8, (-2).pow(3)) + assert_equal(361, 9.pow(1024,1000)) +end diff --git a/mrbgems/mruby-os-memsize/src/memsize.c b/mrbgems/mruby-os-memsize/src/memsize.c index b6a25a204..121cbb060 100644 --- a/mrbgems/mruby-os-memsize/src/memsize.c +++ b/mrbgems/mruby-os-memsize/src/memsize.c @@ -10,6 +10,7 @@ #include #include #include +#include static size_t os_memsize_of_irep(mrb_state* state, const struct mrb_irep *irep) @@ -127,23 +128,24 @@ os_memsize_of_object(mrb_state* mrb, mrb_value obj) case MRB_TT_INTEGER: if (mrb_immediate_p(obj)) break; - case MRB_TT_RATIONAL: + case MRB_TT_RATIONAL: #if defined(MRB_USE_RATIONAL) #if defined(MRB_INT64) && defined(MRB_32BIT) - size += sizeof(mrb_int)*2; + size += sizeof(mrb_int)*2; #endif - size += mrb_objspace_page_slot_size(); + size += mrb_objspace_page_slot_size(); #endif - break; + break; - case MRB_TT_COMPLEX: + case MRB_TT_COMPLEX: #if defined(MRB_USE_COMPLEX) #if defined(MRB_32BIT) && !defined(MRB_USE_FLOAT32) - size += sizeof(mrb_float)*2; + size += sizeof(mrb_float)*2; #endif - size += mrb_objspace_page_slot_size(); + size += mrb_objspace_page_slot_size(); #endif - break; + break; + case MRB_TT_BIGINT: case MRB_TT_DATA: case MRB_TT_ISTRUCT: size += mrb_objspace_page_slot_size(); diff --git a/mrbgems/mruby-pack/src/pack.c b/mrbgems/mruby-pack/src/pack.c index 1edaac93b..cd9202404 100644 --- a/mrbgems/mruby-pack/src/pack.c +++ b/mrbgems/mruby-pack/src/pack.c @@ -387,13 +387,13 @@ static int pack_BER(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int flags) { mrb_int n = mrb_integer(o); - size_t i; + int i; char *p; if (n < 0) { mrb_raise(mrb, E_ARGUMENT_ERROR, "can't compress negative numbers"); } - for (i=1; i (MRB_INT_MAX>>7)) { mrb_raise(mrb, E_RANGE_ERROR, "BER unpacking 'w' overflow"); @@ -620,6 +622,7 @@ utf8_to_uv(mrb_state *mrb, const char *p, long *lenp) } if (!(uv & 0x40)) { *lenp = 1; + malformed: mrb_raise(mrb, E_ARGUMENT_ERROR, "malformed UTF-8 character"); } @@ -630,7 +633,7 @@ utf8_to_uv(mrb_state *mrb, const char *p, long *lenp) else if (!(uv & 0x02)) { n = 6; uv &= 0x01; } else { *lenp = 1; - mrb_raise(mrb, E_ARGUMENT_ERROR, "malformed UTF-8 character"); + goto malformed; } if (n > *lenp) { mrb_raisef(mrb, E_ARGUMENT_ERROR, "malformed UTF-8 character (expected %d bytes, given %d bytes)", @@ -642,7 +645,7 @@ utf8_to_uv(mrb_state *mrb, const char *p, long *lenp) c = *p++ & 0xff; if ((c & 0xc0) != 0x80) { *lenp -= n + 1; - mrb_raise(mrb, E_ARGUMENT_ERROR, "malformed UTF-8 character"); + goto malformed; } else { c &= 0x3f; @@ -1300,7 +1303,7 @@ alias: mrb_raise(mrb, E_RUNTIME_ERROR, "too big template length"); } count = (int)n; - tmpl->idx = e - tptr; + tmpl->idx = (int)(e - tptr); continue; } else if (ch == '*') { if (type == PACK_TYPE_NONE) @@ -1387,13 +1390,12 @@ mrb_pack_pack(mrb_state *mrb, mrb_value ary) o = mrb_ary_ref(mrb, ary, aidx); if (type == PACK_TYPE_INTEGER) { - o = mrb_to_integer(mrb, o); + o = mrb_ensure_int_type(mrb, o); } #ifndef MRB_NO_FLOAT else if (type == PACK_TYPE_FLOAT) { if (!mrb_float_p(o)) { - mrb_float f = mrb_as_float(mrb, o); - o = mrb_float_value(mrb, f); + o = mrb_ensure_float_type(mrb, o); } } #endif @@ -1524,7 +1526,7 @@ pack_unpack(mrb_state *mrb, mrb_value str, int single) break; } - while (count != 0) { + while (count != 0 && srcidx < srclen) { if (srclen - srcidx < size) { while (count-- > 0) { mrb_ary_push(mrb, result, mrb_nil_value()); diff --git a/mrbgems/mruby-random/src/random.c b/mrbgems/mruby-random/src/random.c index ae917d33e..bd126a93d 100644 --- a/mrbgems/mruby-random/src/random.c +++ b/mrbgems/mruby-random/src/random.c @@ -137,7 +137,7 @@ random_rand(mrb_state *mrb, rand_state *t, mrb_int max) } static mrb_int -random_rand_i(mrb_state *mrb, rand_state *t, mrb_int max) +rand_i(rand_state *t, mrb_int max) { return rand_uint32(t) % max; } @@ -167,6 +167,7 @@ random_default(mrb_state *mrb) { #define random_ptr(v) (rand_state*)mrb_istruct_ptr(v) #define random_default_state(mrb) random_ptr(random_default(mrb)) +#define ID_RANDOM_STRICT MRB_SYM(mruby_Random) static mrb_value random_m_init(mrb_state *mrb, mrb_value self) @@ -241,14 +242,22 @@ random_m_bytes(mrb_state *mrb, mrb_value self) static mrb_value mrb_ary_shuffle_bang(mrb_state *mrb, mrb_value ary) { - mrb_int i, max; - rand_state *random; if (RARRAY_LEN(ary) > 1) { - struct RClass *c = mrb_class_get_id(mrb, MRB_SYM(Random)); - if (mrb_get_args(mrb, "|I", &random, c) == 0) { + mrb_int i, max; + mrb_value r; + rand_state *random; + + struct RClass *c = mrb_class_get_id(mrb, ID_RANDOM_STRICT); + if (mrb_get_args(mrb, "|o", &r) == 0) { random = random_default_state(mrb); } + else if (mrb_obj_is_kind_of(mrb, r, c)){ + random = (rand_state*)mrb_istruct_ptr(r); + } + else { + mrb_raise(mrb, E_TYPE_ERROR, "Random object required"); + } mrb_ary_modify(mrb, mrb_ary_ptr(ary)); max = RARRAY_LEN(ary); for (i = RARRAY_LEN(ary) - 1; i > 0; i--) { @@ -256,7 +265,7 @@ mrb_ary_shuffle_bang(mrb_state *mrb, mrb_value ary) mrb_value *ptr = RARRAY_PTR(ary); mrb_value tmp; - j = random_rand_i(mrb, random, max); + j = rand_i(random, max); tmp = ptr[i]; ptr[i] = ptr[j]; @@ -303,13 +312,20 @@ mrb_ary_sample(mrb_state *mrb, mrb_value ary) { mrb_int n = 0; mrb_bool given; + mrb_value r; rand_state *random; mrb_int len; - struct RClass *c = mrb_class_get_id(mrb, MRB_SYM(Random)); + struct RClass *c = mrb_class_get_id(mrb, ID_RANDOM_STRICT); - if (mrb_get_args(mrb, "|i?I", &n, &given, &random, c) < 2) { + if (mrb_get_args(mrb, "|i?o", &n, &given, &r) < 2) { random = random_default_state(mrb); } + else if (mrb_obj_is_kind_of(mrb, r, c)){ + random = (rand_state*)mrb_istruct_ptr(r); + } + else { + mrb_raise(mrb, E_TYPE_ERROR, "Random object required"); + } len = RARRAY_LEN(ary); if (!given) { /* pick one element */ switch (len) { @@ -318,7 +334,7 @@ mrb_ary_sample(mrb_state *mrb, mrb_value ary) case 1: return RARRAY_PTR(ary)[0]; default: - return RARRAY_PTR(ary)[rand_uint32(random) % len]; + return RARRAY_PTR(ary)[rand_i(random, len)]; } } else { @@ -333,7 +349,7 @@ mrb_ary_sample(mrb_state *mrb, mrb_value ary) for (;;) { retry: - r = (mrb_int)(rand_uint32(random) % len); + r = rand_i(random, len); for (j=0; jkernel_module, "srand", random_f_srand, MRB_ARGS_OPT(1)); random = mrb_define_class(mrb, "Random", mrb->object_class); + mrb_const_set(mrb, mrb_obj_value(mrb->object_class), ID_RANDOM_STRICT, mrb_obj_value(random)); // for class check MRB_SET_INSTANCE_TT(random, MRB_TT_ISTRUCT); mrb_define_class_method(mrb, random, "rand", random_f_rand, MRB_ARGS_OPT(1)); mrb_define_class_method(mrb, random, "srand", random_f_srand, MRB_ARGS_OPT(1)); @@ -401,7 +418,7 @@ void mrb_mruby_random_gem_init(mrb_state *mrb) mrb_define_method(mrb, array, "sample", mrb_ary_sample, MRB_ARGS_OPT(2)); mrb_const_set(mrb, mrb_obj_value(random), MRB_SYM(DEFAULT), - mrb_obj_new(mrb, random, 0, NULL)); + mrb_obj_new(mrb, random, 0, NULL)); } void mrb_mruby_random_gem_final(mrb_state *mrb) diff --git a/mrbgems/mruby-range-ext/src/range.c b/mrbgems/mruby-range-ext/src/range.c index 633c97b73..70bf0976e 100644 --- a/mrbgems/mruby-range-ext/src/range.c +++ b/mrbgems/mruby-range-ext/src/range.c @@ -2,29 +2,33 @@ #include static mrb_bool -r_le(mrb_state *mrb, mrb_value a, mrb_value b) +r_less(mrb_state *mrb, mrb_value a, mrb_value b, mrb_bool excl) { - mrb_int n = mrb_cmp(mrb, a, b); - - if (n == 0 || n == -1) return TRUE; - return FALSE; -} - -static mrb_bool -r_lt(mrb_state *mrb, mrb_value a, mrb_value b) -{ - return mrb_cmp(mrb, a, b) == -1; + switch (mrb_cmp(mrb, a, b)) { + case -2: /* failure */ + case 1: + return FALSE; + case 0: + return !excl; + case -1: + default: /* just in case */ + return TRUE; + } } /* * call-seq: * rng.cover?(obj) -> true or false + * rng.cover?(range) -> true or false * - * Returns true if +obj+ is between the begin and end of - * the range. + * Returns +true+ if the given argument is within +self+, +false+ otherwise. * - * This tests begin <= obj <= end when #exclude_end? is +false+ - * and begin <= obj < end when #exclude_end? is +true+. + * With non-range argument +object+, evaluates with <= and <. + * + * For range +self+ with included end value (#exclude_end? == false), + * evaluates thus: + * + * self.begin <= object <= self.end * * ("a".."z").cover?("c") #=> true * ("a".."z").cover?("5") #=> false @@ -40,20 +44,53 @@ range_cover(mrb_state *mrb, mrb_value range) beg = RANGE_BEG(r); end = RANGE_END(r); - if (r_le(mrb, beg, val)) { - if (mrb_nil_p(end)) { + if (mrb_nil_p(beg) && mrb_nil_p(end)) return mrb_true_value(); + + if (mrb_range_p(val)) { + struct RRange *r2 = mrb_range_ptr(mrb, val); + mrb_value beg2 = RANGE_BEG(r2); + mrb_value end2 = RANGE_END(r2); + + /* range.cover?(nil..nil) => true */ + if (mrb_nil_p(beg2) && mrb_nil_p(end2)) return mrb_true_value(); + + /* (a..b).cover?(c..d) */ + if (mrb_nil_p(end)) { /* a.. */ + /* (a..).cover?(c..) => true */ + if (mrb_nil_p(end2)) return mrb_bool_value(mrb_cmp(mrb, beg, beg2) != -2); + /* (a..).cover?(c..d) where d false */ + if (r_less(mrb, end2, beg, RANGE_EXCL(r2))) return mrb_false_value(); return mrb_true_value(); } - if (RANGE_EXCL(r)) { - if (r_lt(mrb, val, end)) - return mrb_true_value(); + else if (mrb_nil_p(beg)) { /* ..b */ + /* (..b).cover?(..d) => true */ + if (mrb_nil_p(beg2)) return mrb_bool_value(mrb_cmp(mrb, end, end2) != -2); + /* (..b).cover?(c..d) where b false */ + if (r_less(mrb, end, beg2, RANGE_EXCL(r))) return mrb_false_value(); + return mrb_true_value(); } - else { - if (r_le(mrb, val, end)) - return mrb_true_value(); + else { /* a..b */ + /* (a..b).cover?(c..) => (c (a false */ + if (r_less(mrb, end, beg2, RANGE_EXCL(r))) return mrb_false_value(); + /* (a..b).cover?(c..d) where (d false */ + if (r_less(mrb, end2, beg, RANGE_EXCL(r2))) return mrb_false_value(); + return mrb_true_value(); } } + if (mrb_nil_p(beg) || r_less(mrb, beg, val, FALSE)) { + if (mrb_nil_p(end)) { + return mrb_true_value(); + } + if (r_less(mrb, val, end, RANGE_EXCL(r))) + return mrb_true_value(); + } return mrb_false_value(); } diff --git a/mrbgems/mruby-range-ext/test/range.rb b/mrbgems/mruby-range-ext/test/range.rb index 863c619c8..4ae575669 100644 --- a/mrbgems/mruby-range-ext/test/range.rb +++ b/mrbgems/mruby-range-ext/test/range.rb @@ -3,11 +3,25 @@ assert('Range#cover?') do assert_true ("a".."z").cover?("c") - assert_true !("a".."z").cover?("5") + assert_false ("a".."z").cover?("5") assert_true ("a".."z").cover?("cc") + assert_false ("a".."z").cover?(nil) assert_true ("a"..).cover?("c") assert_false ("a"..).cover?("5") assert_true ("a"..).cover?("cc") + assert_true (.."z").cover?("a") + assert_false (..."z").cover?("z") + assert_true (.."z").cover?("z") + assert_true (nil..nil).cover?(nil) + + assert_true ("a".."c").cover?("b".."d") + assert_true ("a"..).cover?("b"..) + assert_false ("a"..).cover?(1..) + assert_false ("d"..).cover?(.."b") + assert_true (.."c").cover?("b".."d") + assert_true (.."c").cover?(.."d") + assert_false (.."c").cover?(..2) + assert_false (.."c").cover?("d"..) end assert('Range#first') do diff --git a/mrbgems/mruby-rational/src/rational.c b/mrbgems/mruby-rational/src/rational.c index e66046543..8fed218d3 100644 --- a/mrbgems/mruby-rational/src/rational.c +++ b/mrbgems/mruby-rational/src/rational.c @@ -3,6 +3,13 @@ #include #include +mrb_value mrb_complex_new(mrb_state *, mrb_float, mrb_float); +mrb_bool mrb_complex_eq(mrb_state *mrb, mrb_value, mrb_value); +mrb_value mrb_complex_add(mrb_state *mrb, mrb_value, mrb_value); +mrb_value mrb_complex_sub(mrb_state *mrb, mrb_value, mrb_value); +mrb_value mrb_complex_mul(mrb_state *mrb, mrb_value, mrb_value); +mrb_value mrb_complex_div(mrb_state *mrb, mrb_value, mrb_value); + struct mrb_rational { mrb_int numerator; mrb_int denominator; @@ -393,7 +400,6 @@ rational_eq(mrb_state *mrb, mrb_value x) #ifdef MRB_USE_COMPLEX case MRB_TT_COMPLEX: { - mrb_bool mrb_complex_eq(mrb_state *mrb, mrb_value, mrb_value); result = mrb_complex_eq(mrb, y, mrb_rational_to_f(mrb, x)); break; } @@ -405,10 +411,6 @@ rational_eq(mrb_state *mrb, mrb_value x) return mrb_bool_value(result); } -#ifndef MRB_NO_FLOAT -mrb_value mrb_complex_new(mrb_state *, mrb_float, mrb_float); -#endif - static mrb_value rational_cmp(mrb_state *mrb, mrb_value x) { @@ -454,11 +456,6 @@ rational_cmp(mrb_state *mrb, mrb_value x) return mrb_fixnum_value(-1); return mrb_fixnum_value(0); } -#endif -#ifdef MRB_USE_COMPLEX - case MRB_TT_COMPLEX: - x = mrb_complex_new(mrb, rat_float(p1), 0); - return mrb_funcall_id(mrb, x, MRB_OPSYM(cmp), 1, y); #endif default: x = mrb_funcall_id(mrb, y, MRB_OPSYM(cmp), 1, x); @@ -479,11 +476,10 @@ rational_minus(mrb_state *mrb, mrb_value x) return rational_new(mrb, -n, p->denominator); } -static mrb_value -rational_add(mrb_state *mrb, mrb_value x) +mrb_value +mrb_rational_add(mrb_state *mrb, mrb_value x, mrb_value y) { struct mrb_rational *p1 = rational_ptr(mrb, x); - mrb_value y = mrb_get_arg1(mrb); switch (mrb_type(y)) { case MRB_TT_INTEGER: @@ -513,16 +509,27 @@ rational_add(mrb_state *mrb, mrb_value x) } #endif +#if defined(MRB_USE_COMPLEX) + case MRB_TT_COMPLEX: + return mrb_complex_add(mrb, mrb_complex_new(mrb, rat_float(p1), 0), y); +#endif + default: return mrb_funcall_id(mrb, y, MRB_OPSYM(add), 1, x); } } static mrb_value -rational_sub(mrb_state *mrb, mrb_value x) +rational_add(mrb_state *mrb, mrb_value x) +{ + mrb_value y = mrb_get_arg1(mrb); + return mrb_rational_add(mrb, x, y); +} + +mrb_value +mrb_rational_sub(mrb_state *mrb, mrb_value x, mrb_value y) { struct mrb_rational *p1 = rational_ptr(mrb, x); - mrb_value y = mrb_get_arg1(mrb); switch (mrb_type(y)) { case MRB_TT_INTEGER: @@ -546,8 +553,7 @@ rational_sub(mrb_state *mrb, mrb_value x) #if defined(MRB_USE_COMPLEX) case MRB_TT_COMPLEX: - x = mrb_complex_new(mrb, rat_float(p1), 0); - return mrb_funcall_id(mrb, x, MRB_OPSYM(sub), 1, y); + return mrb_complex_sub(mrb, mrb_complex_new(mrb, rat_float(p1), 0), y); #endif #ifndef MRB_NO_FLOAT @@ -565,10 +571,16 @@ rational_sub(mrb_state *mrb, mrb_value x) } static mrb_value -rational_mul(mrb_state *mrb, mrb_value x) +rational_sub(mrb_state *mrb, mrb_value x) +{ + mrb_value y = mrb_get_arg1(mrb); + return mrb_rational_sub(mrb, x, y); +} + +mrb_value +mrb_rational_mul(mrb_state *mrb, mrb_value x, mrb_value y) { struct mrb_rational *p1 = rational_ptr(mrb, x); - mrb_value y = mrb_get_arg1(mrb); switch (mrb_type(y)) { case MRB_TT_INTEGER: @@ -595,16 +607,27 @@ rational_mul(mrb_state *mrb, mrb_value x) } #endif +#if defined(MRB_USE_COMPLEX) + case MRB_TT_COMPLEX: + return mrb_complex_mul(mrb, mrb_complex_new(mrb, rat_float(p1), 0), y); +#endif + default: return mrb_funcall_id(mrb, y, MRB_OPSYM(mul), 1, x); } } +static mrb_value +rational_mul(mrb_state *mrb, mrb_value x) +{ + mrb_value y = mrb_get_arg1(mrb); + return mrb_rational_mul(mrb, x, y); +} + mrb_value -mrb_rational_div(mrb_state *mrb, mrb_value x) +mrb_rational_div(mrb_state *mrb, mrb_value x, mrb_value y) { struct mrb_rational *p1 = rational_ptr(mrb, x); - mrb_value y = mrb_get_arg1(mrb); switch (mrb_type(y)) { case MRB_TT_INTEGER: @@ -625,8 +648,7 @@ mrb_rational_div(mrb_state *mrb, mrb_value x) #if defined(MRB_USE_COMPLEX) case MRB_TT_COMPLEX: - x = mrb_complex_new(mrb, rat_float(p1), 0); - return mrb_funcall_id(mrb, x, MRB_OPSYM(div), 1, y); + return mrb_complex_div(mrb, mrb_complex_new(mrb, rat_float(p1), 0), y); #endif default: @@ -642,65 +664,15 @@ mrb_rational_div(mrb_state *mrb, mrb_value x) } } -#define rational_div mrb_rational_div +static mrb_value +rational_div(mrb_state *mrb, mrb_value x) +{ + mrb_value y = mrb_get_arg1(mrb); + return mrb_rational_div(mrb, x, y); +} + mrb_int mrb_div_int(mrb_state *, mrb_int, mrb_int); -#ifndef MRB_USE_COMPLEX -/* 15.2.8.3.4 */ -/* - * redefine Integer#/ - */ -static mrb_value -rational_int_div(mrb_state *mrb, mrb_value x) -{ - mrb_value y = mrb_get_arg1(mrb); - mrb_int a = mrb_integer(x); - - if (mrb_integer_p(y)) { - mrb_int div = mrb_div_int(mrb, a, mrb_integer(y)); - return mrb_int_value(mrb, div); - } - switch (mrb_type(y)) { - case MRB_TT_RATIONAL: - return rational_div(mrb, rational_new(mrb, a, 1)); - default: -#ifdef MRB_NO_FLOAT - case MRB_TT_FLOAT: - mrb_raise(mrb, E_TYPE_ERROR, "non integer multiplication"); -#else - return mrb_float_value(mrb, mrb_div_float((mrb_float)a, mrb_as_float(mrb, y))); -#endif - } -} - -/* 15.2.9.3.19(x) */ -/* - * redefine Integer#quo - */ - -static mrb_value -rational_int_quo(mrb_state *mrb, mrb_value x) -{ - mrb_value y = mrb_get_arg1(mrb); - mrb_int a = mrb_integer(x); - - if (mrb_integer_p(y)) { - return rational_new(mrb, a, mrb_integer(y)); - } - switch (mrb_type(y)) { - case MRB_TT_RATIONAL: - x = rational_new(mrb, a, 1); - return mrb_funcall_id(mrb, x, MRB_OPSYM(div), 1, y); - default: -#ifdef MRB_NO_FLOAT - mrb_raise(mrb, E_TYPE_ERROR, "non integer multiplication"); -#else - return mrb_float_value(mrb, mrb_div_float((mrb_float)a, mrb_as_float(mrb, y))); -#endif - } -} -#endif /* !MRB_USE_COMPLEX */ - void mrb_mruby_rational_gem_init(mrb_state *mrb) { struct RClass *rat; @@ -726,10 +698,6 @@ void mrb_mruby_rational_gem_init(mrb_state *mrb) mrb_define_method(mrb, rat, "/", rational_div, MRB_ARGS_REQ(1)); mrb_define_method(mrb, rat, "quo", rational_div, MRB_ARGS_REQ(1)); mrb_define_method(mrb, mrb->integer_class, "to_r", fix_to_r, MRB_ARGS_NONE()); -#ifndef MRB_USE_COMPLEX - mrb_define_method(mrb, mrb->integer_class, "/", rational_int_div, MRB_ARGS_REQ(1)); /* override */ - mrb_define_method(mrb, mrb->integer_class, "quo", rational_int_quo, MRB_ARGS_REQ(1)); /* override */ -#endif mrb_define_method(mrb, mrb->kernel_module, "Rational", rational_m, MRB_ARGS_ARG(1,1)); } diff --git a/mrbgems/mruby-sleep/src/sleep.c b/mrbgems/mruby-sleep/src/sleep.c index 79a5af650..d05bc1944 100644 --- a/mrbgems/mruby-sleep/src/sleep.c +++ b/mrbgems/mruby-sleep/src/sleep.c @@ -95,7 +95,7 @@ mrb_f_usleep(mrb_state *mrb, mrb_value self) if (usec >= 0) { usleep(usec); } else { - mrb_raise(mrb, E_ARGUMENT_ERROR, "time interval must not be negative integer"); + mrb_raise(mrb, E_ARGUMENT_ERROR, "time interval must not be negative"); } #ifdef _WIN32 diff --git a/mrbgems/mruby-socket/src/socket.c b/mrbgems/mruby-socket/src/socket.c index f0213ad39..a9ce33d2e 100644 --- a/mrbgems/mruby-socket/src/socket.c +++ b/mrbgems/mruby-socket/src/socket.c @@ -38,6 +38,7 @@ #include "mruby/string.h" #include "mruby/variable.h" #include "mruby/error.h" +#include "mruby/internal.h" #include "mruby/presym.h" #include "mruby/ext/io.h" @@ -52,12 +53,6 @@ #define E_SOCKET_ERROR mrb_class_get_id(mrb, MRB_SYM(SocketError)) -#if !defined(mrb_cptr) -#define mrb_cptr_value(m,p) mrb_voidp_value((m),(p)) -#define mrb_cptr(o) mrb_voidp(o) -#define mrb_cptr_p(o) mrb_voidp_p(o) -#endif - #ifdef _WIN32 static const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) { @@ -262,10 +257,12 @@ sa2addrlist(mrb_state *mrb, const struct sockaddr *sa, socklen_t salen) return ary; } +int mrb_io_fileno(mrb_state *mrb, mrb_value io); + static int socket_fd(mrb_state *mrb, mrb_value sock) { - return (int)mrb_integer(mrb_funcall_id(mrb, sock, MRB_SYM(fileno), 0)); + return mrb_io_fileno(mrb, sock); } static int @@ -468,9 +465,10 @@ mrb_basicsocket_setsockopt(mrb_state *mrb, mrb_value self) } else if (argc == 1) { if (strcmp(mrb_obj_classname(mrb, so), "Socket::Option") != 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "not an instance of Socket::Option"); - level = mrb_integer(mrb_funcall_id(mrb, so, MRB_SYM(level), 0)); - optname = mrb_integer(mrb_funcall_id(mrb, so, MRB_SYM(optname), 0)); + level = mrb_as_int(mrb, mrb_funcall_id(mrb, so, MRB_SYM(level), 0)); + optname = mrb_as_int(mrb, mrb_funcall_id(mrb, so, MRB_SYM(optname), 0)); optval = mrb_funcall_id(mrb, so, MRB_SYM(data), 0); + mrb_ensure_string_type(mrb, optval); } else { mrb_argnum_error(mrb, argc, 3, 3); } @@ -515,9 +513,8 @@ mrb_ipsocket_ntop(mrb_state *mrb, mrb_value klass) char buf[50]; mrb_get_args(mrb, "is", &af, &addr, &n); - if ((af == AF_INET && n != 4) || (af == AF_INET6 && n != 16)) - mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid address"); - if (inet_ntop((int)af, addr, buf, sizeof(buf)) == NULL) + if ((af == AF_INET && n != 4) || (af == AF_INET6 && n != 16) || + inet_ntop((int)af, addr, buf, sizeof(buf)) == NULL) mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid address"); return mrb_str_new_cstr(mrb, buf); } @@ -530,8 +527,7 @@ mrb_ipsocket_pton(mrb_state *mrb, mrb_value klass) char buf[50]; mrb_get_args(mrb, "is", &af, &bp, &n); - if ((size_t)n > sizeof(buf) - 1) - mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid address"); + if ((size_t)n > sizeof(buf) - 1) goto invalid; memcpy(buf, bp, n); buf[n] = '\0'; @@ -623,7 +619,7 @@ mrb_socket_accept2(mrb_state *mrb, mrb_value klass) mrb_get_args(mrb, "i", &s0); socklen = sizeof(struct sockaddr_storage); - sastr = mrb_str_new_capa(mrb, socklen); + sastr = mrb_str_new_capa(mrb, (mrb_int)socklen); s1 = (int)accept(s0, (struct sockaddr *)RSTRING_PTR(sastr), &socklen); if (s1 == -1) { mrb_sys_fail(mrb, "accept"); diff --git a/mrbgems/mruby-sprintf/src/sprintf.c b/mrbgems/mruby-sprintf/src/sprintf.c index 8de3a4541..a562bdac1 100644 --- a/mrbgems/mruby-sprintf/src/sprintf.c +++ b/mrbgems/mruby-sprintf/src/sprintf.c @@ -1002,12 +1002,14 @@ retry: } break; -#ifndef MRB_NO_FLOAT case 'f': case 'g': case 'G': case 'e': case 'E': { +#ifdef MRB_NO_FLOAT + mrb_raisef(mrb, E_ARGUMENT_ERROR, "%%%c not supported with MRB_NO_FLOAT defined", *p); +#else mrb_value val = GETARG(); double fval; mrb_int need = 6; @@ -1077,9 +1079,9 @@ retry: mrb_raise(mrb, E_RUNTIME_ERROR, "formatting error"); } blen += n; +#endif } break; -#endif } flags = FNONE; } diff --git a/mrbgems/mruby-string-ext/src/string.c b/mrbgems/mruby-string-ext/src/string.c index 8360a051c..30ca5ab8d 100644 --- a/mrbgems/mruby-string-ext/src/string.c +++ b/mrbgems/mruby-string-ext/src/string.c @@ -4,6 +4,7 @@ #include #include #include +#include #define ENC_ASCII_8BIT "ASCII-8BIT" #define ENC_BINARY "BINARY" diff --git a/mrbgems/mruby-struct/src/struct.c b/mrbgems/mruby-struct/src/struct.c index 2d864bdaf..393e6719c 100644 --- a/mrbgems/mruby-struct/src/struct.c +++ b/mrbgems/mruby-struct/src/struct.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #define RSTRUCT_LEN(st) RARRAY_LEN(st) diff --git a/mrbgems/mruby-symbol-ext/src/symbol.c b/mrbgems/mruby-symbol-ext/src/symbol.c index 460d2531d..4340d74a3 100644 --- a/mrbgems/mruby-symbol-ext/src/symbol.c +++ b/mrbgems/mruby-symbol-ext/src/symbol.c @@ -1,6 +1,7 @@ #include #include #include +#include #ifdef MRB_USE_ALL_SYMBOLS # include #endif diff --git a/mrbgems/mruby-test-inline-struct/test/inline.c b/mrbgems/mruby-test-inline-struct/test/inline.c index 7537bffc6..f3940476b 100644 --- a/mrbgems/mruby-test-inline-struct/test/inline.c +++ b/mrbgems/mruby-test-inline-struct/test/inline.c @@ -56,10 +56,18 @@ istruct_test_test_receive(mrb_state *mrb, mrb_value self) static mrb_value istruct_test_test_receive_direct(mrb_state *mrb, mrb_value self) { - char *ptr; + mrb_value is; struct RClass *klass = mrb_class_get(mrb, "InlineStructTest"); - mrb_get_args(mrb, "I", &ptr, klass); - return mrb_bool_value(ptr[0] == 's'); + mrb_get_args(mrb, "o", &is); + /* if you need to protect istruct retrieval from untrusted code, + you need to care about class replacing. + See mrbgem/mruby-random/src/random.c for detail */ + if (mrb_istruct_p(is) && mrb_obj_is_kind_of(mrb, is, klass)) { + char *ptr = (char*)mrb_istruct_ptr(is);; + return mrb_bool_value(ptr[0] == 's'); + } + mrb_raise(mrb, E_TYPE_ERROR, "InlineStructTest"); + return mrb_false_value(); } static mrb_value diff --git a/mrbgems/mruby-time/src/time.c b/mrbgems/mruby-time/src/time.c index 6b9762acf..664ee8ed5 100644 --- a/mrbgems/mruby-time/src/time.c +++ b/mrbgems/mruby-time/src/time.c @@ -459,7 +459,7 @@ time_mktime(mrb_state *mrb, mrb_int ayear, mrb_int amonth, mrb_int aday, #define OUTINT(x) 0 #endif - if (OUTINT(ayear-1900) || + if (ayear < 1900 || OUTINT(ayear-1900) || amonth < 1 || amonth > 12 || aday < 1 || aday > 31 || ahour < 0 || ahour > 24 || @@ -476,14 +476,21 @@ time_mktime(mrb_state *mrb, mrb_int ayear, mrb_int amonth, mrb_int aday, nowtime.tm_sec = (int)asec; nowtime.tm_isdst = -1; + time_t (*mk)(struct tm*); if (timezone == MRB_TIMEZONE_UTC) { - nowsecs = timegm(&nowtime); + mk = timegm; } else { - nowsecs = mktime(&nowtime); + mk = mktime; } + nowsecs = (*mk)(&nowtime); if (nowsecs == (time_t)-1) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "Not a valid time"); + nowtime.tm_sec += 1; /* maybe Epoch-1 sec */ + nowsecs = (*mk)(&nowtime); + if (nowsecs != 0) { /* check if Epoch */ + mrb_raise(mrb, E_ARGUMENT_ERROR, "Not a valid time"); + } + nowsecs = (time_t)-1; /* valid Epoch-1 */ } return time_alloc_time(mrb, nowsecs, ausec, timezone); diff --git a/mrbgems/mruby-time/test/time.rb b/mrbgems/mruby-time/test/time.rb index e239dec28..2c3a354f4 100644 --- a/mrbgems/mruby-time/test/time.rb +++ b/mrbgems/mruby-time/test/time.rb @@ -267,7 +267,3 @@ assert('2000 times 500us make a second') do end assert_equal(0, t.usec) end - -assert('Time.gm with Dec 31 23:59:59 1969 raise ArgumentError') do - assert_raise(ArgumentError) {Time.gm(1969, 12, 31, 23, 59, 59)} -end diff --git a/mrbgems/stdlib.gembox b/mrbgems/stdlib.gembox index 72fb9e343..2b2f45334 100644 --- a/mrbgems/stdlib.gembox +++ b/mrbgems/stdlib.gembox @@ -51,4 +51,7 @@ MRuby::GemBox.new do |conf| # Use class/module extension conf.gem :core => "mruby-class-ext" + + # Use errno extension + conf.gem :core => "mruby-errno" end diff --git a/mrblib/00class.rb b/mrblib/00class.rb index d7a718ba1..5bef3f126 100644 --- a/mrblib/00class.rb +++ b/mrblib/00class.rb @@ -22,7 +22,8 @@ class Module # 15.2.2.4.27 def include(*args) - args.reverse.each do |m| + args.reverse! + args.each do |m| m.append_features(self) m.included(self) end @@ -30,7 +31,8 @@ class Module end def prepend(*args) - args.reverse.each do |m| + args.reverse! + args.each do |m| m.prepend_features(self) m.prepended(self) end diff --git a/mrblib/00kernel.rb b/mrblib/00kernel.rb new file mode 100644 index 000000000..02f3a9981 --- /dev/null +++ b/mrblib/00kernel.rb @@ -0,0 +1,35 @@ +module Kernel + ## + # call-seq: + # obj.extend(module, ...) -> obj + # + # Adds to _obj_ the instance methods from each module given as a + # parameter. + # + # module Mod + # def hello + # "Hello from Mod.\n" + # end + # end + # + # class Klass + # def hello + # "Hello from Klass.\n" + # end + # end + # + # k = Klass.new + # k.hello #=> "Hello from Klass.\n" + # k.extend(Mod) #=> # + # k.hello #=> "Hello from Mod.\n" + # + # ISO 15.3.1.3.13 + def extend(*args) + args.reverse! + args.each do |m| + m.extend_object(self) + m.extended(self) + end + self + end +end diff --git a/mrblib/10error.rb b/mrblib/10error.rb index aa9da91bb..431f77809 100644 --- a/mrblib/10error.rb +++ b/mrblib/10error.rb @@ -1,3 +1,16 @@ +class Exception + ## + # call-seq: + # exception.message -> string + # + # Returns the result of invoking exception.to_s. + # Normally this returns the exception's message or name. + # + def message + to_s + end +end + # ISO 15.2.24 class ArgumentError < StandardError end diff --git a/mrblib/array.rb b/mrblib/array.rb index 6b4f74b96..cef944f8a 100644 --- a/mrblib/array.rb +++ b/mrblib/array.rb @@ -167,10 +167,14 @@ class Array n = other.size len = n if len > n i = 0 - while i < len - n = (self[i] <=> other[i]) - return n if n.nil? || n != 0 - i += 1 + begin + while i < len + n = (self[i] <=> other[i]) + return n if n.nil? || n != 0 + i += 1 + end + rescue NoMethodError + return nil end len = self.size - other.size if len == 0 diff --git a/mrblib/string.rb b/mrblib/string.rb index 81ddf6784..84e7530c9 100644 --- a/mrblib/string.rb +++ b/mrblib/string.rb @@ -150,10 +150,9 @@ class String # Call the given block for each byte of +self+. def each_byte(&block) return to_enum(:each_byte, &block) unless block - bytes = self.bytes pos = 0 - while pos < bytes.size - block.call(bytes[pos]) + while pos < bytesize + block.call(getbyte(pos)) pos += 1 end self diff --git a/src/array.c b/src/array.c index 1a95b75c9..6d096a61d 100644 --- a/src/array.c +++ b/src/array.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "value_array.h" @@ -18,15 +19,26 @@ #define ARY_C_MAX_SIZE (SIZE_MAX / sizeof(mrb_value)) #define ARY_MAX_SIZE ((mrb_int)((ARY_C_MAX_SIZE < (size_t)MRB_INT_MAX) ? ARY_C_MAX_SIZE : MRB_INT_MAX-1)) +static void +ary_too_big(mrb_state *mrb) +{ + mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); +} + +static void +ary_check_too_big(mrb_state *mrb, mrb_int a, mrb_int b) +{ + if (a > ARY_MAX_SIZE - b || a < 0) + ary_too_big(mrb); +} + static struct RArray* ary_new_capa(mrb_state *mrb, mrb_int capa) { struct RArray *a; size_t blen; - if (capa > ARY_MAX_SIZE) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); - } + ary_check_too_big(mrb, capa, 0); blen = capa * sizeof(mrb_value); a = MRB_OBJ_ALLOC(mrb, MRB_TT_ARRAY, mrb->array_class); @@ -188,11 +200,7 @@ ary_expand_capa(mrb_state *mrb, struct RArray *a, mrb_int len) { mrb_int capa = ARY_CAPA(a); - if (len > ARY_MAX_SIZE || len < 0) { - size_error: - mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); - } - + ary_check_too_big(mrb, len, 0); if (capa < ARY_DEFAULT_LEN) { capa = ARY_DEFAULT_LEN; } @@ -205,7 +213,7 @@ ary_expand_capa(mrb_state *mrb, struct RArray *a, mrb_int len) } } if (capa < len || capa > ARY_MAX_SIZE) { - goto size_error; + ary_too_big(mrb); } if (ARY_EMBED_P(a)) { @@ -302,9 +310,7 @@ ary_concat(mrb_state *mrb, struct RArray *a, struct RArray *a2) ary_replace(mrb, a, a2); return; } - if (ARY_LEN(a2) > ARY_MAX_SIZE - ARY_LEN(a)) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); - } + ary_check_too_big(mrb, ARY_LEN(a2), ARY_LEN(a)); len = ARY_LEN(a) + ARY_LEN(a2); ary_modify(mrb, a); @@ -343,9 +349,7 @@ mrb_ary_plus(mrb_state *mrb, mrb_value self) mrb_int blen, len1; mrb_get_args(mrb, "a", &ptr, &blen); - if (ARY_MAX_SIZE - blen < ARY_LEN(a1)) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); - } + ary_check_too_big(mrb, ARY_LEN(a1), blen); len1 = ARY_LEN(a1); a2 = ary_new_capa(mrb, len1 + blen); array_copy(ARY_PTR(a2), ARY_PTR(a1), len1); @@ -425,16 +429,22 @@ mrb_ary_times(mrb_state *mrb, mrb_value self) { struct RArray *a1 = mrb_ary_ptr(self); struct RArray *a2; - mrb_value *ptr; + mrb_value *ptr, sep, tmp; mrb_int times, len1; + mrb_get_args(mrb, "o", &sep); + tmp = mrb_check_string_type(mrb, sep); + if (!mrb_nil_p(tmp)) { + return mrb_ary_join(mrb, self, tmp); + } + mrb_get_args(mrb, "i", ×); if (times < 0) { mrb_raise(mrb, E_ARGUMENT_ERROR, "negative argument"); } if (times == 0) return mrb_ary_new(mrb); if (ARY_MAX_SIZE / times < ARY_LEN(a1)) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); + ary_too_big(mrb); } len1 = ARY_LEN(a1); a2 = ary_new_capa(mrb, len1 * times); @@ -710,6 +720,9 @@ mrb_ary_set(mrb_state *mrb, mrb_value ary, mrb_int n, mrb_value val) mrb_raisef(mrb, E_INDEX_ERROR, "index %i out of array", n - len); } } + if (n >= ARY_MAX_SIZE) { + mrb_raise(mrb, E_INDEX_ERROR, "index too big"); + } if (len <= n) { if (ARY_CAPA(a) <= n) ary_expand_capa(mrb, a, n + 1); @@ -834,7 +847,7 @@ ary_subseq(mrb_state *mrb, struct RArray *a, mrb_int beg, mrb_int len) return mrb_ary_new_from_values(mrb, len, ARY_PTR(a)+beg); } ary_make_shared(mrb, a); - b = MRB_OBJ_ALLOC(mrb, MRB_TT_ARRAY, mrb->array_class); + b = MRB_OBJ_ALLOC(mrb, MRB_TT_ARRAY, mrb->array_class); b->as.heap.ptr = a->as.heap.ptr + beg; b->as.heap.len = len; b->as.heap.aux.shared = a->as.heap.aux.shared; @@ -1003,7 +1016,7 @@ mrb_ary_aset(mrb_state *mrb, mrb_value self) return v3; } -static mrb_value +mrb_value mrb_ary_delete_at(mrb_state *mrb, mrb_value self) { struct RArray *a = mrb_ary_ptr(self); diff --git a/src/backtrace.c b/src/backtrace.c index d6648cc43..30b496927 100644 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -14,6 +14,7 @@ #include #include #include +#include #include struct backtrace_location { @@ -26,8 +27,7 @@ typedef void (*each_backtrace_func)(mrb_state*, const struct backtrace_location* static const mrb_data_type bt_type = { "Backtrace", mrb_free }; -mrb_value mrb_exc_inspect(mrb_state *mrb, mrb_value exc); -mrb_value mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace); +struct RObject *mrb_unpack_backtrace(mrb_state *mrb, struct RObject *backtrace); static void each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, each_backtrace_func func, void *data) @@ -97,17 +97,17 @@ each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, each_backtrace_func func, void * #ifndef MRB_NO_STDIO static void -print_backtrace(mrb_state *mrb, struct RObject *exc, mrb_value backtrace) +print_backtrace(mrb_state *mrb, struct RObject *exc, struct RArray *backtrace) { mrb_int i; - mrb_int n = RARRAY_LEN(backtrace); + mrb_int n = ARY_LEN(backtrace); mrb_value *loc, mesg; if (n != 0) { if (n > 1) { fprintf(stderr, "trace (most recent call last):\n"); } - for (i=n-1,loc=&RARRAY_PTR(backtrace)[i]; i>0; i--,loc--) { + for (i=n-1,loc=&ARY_PTR(backtrace)[i]; i>0; i--,loc--) { if (mrb_string_p(*loc)) { fprintf(stderr, "\t[%d] %.*s\n", (int)i, (int)RSTRING_LEN(*loc), RSTRING_PTR(*loc)); @@ -130,16 +130,14 @@ print_backtrace(mrb_state *mrb, struct RObject *exc, mrb_value backtrace) MRB_API void mrb_print_backtrace(mrb_state *mrb) { - mrb_value backtrace; - if (!mrb->exc) { return; } - backtrace = mrb_obj_iv_get(mrb, mrb->exc, MRB_SYM(backtrace)); - if (mrb_nil_p(backtrace)) return; - if (!mrb_array_p(backtrace)) backtrace = mrb_unpack_backtrace(mrb, backtrace); - print_backtrace(mrb, mrb->exc, backtrace); + struct RObject *backtrace = ((struct RException*)mrb->exc)->backtrace; + if (!backtrace) return; + if (backtrace->tt != MRB_TT_ARRAY) backtrace = mrb_unpack_backtrace(mrb, backtrace); + print_backtrace(mrb, mrb->exc, (struct RArray*)backtrace); } #else @@ -172,7 +170,7 @@ pack_backtrace_i(mrb_state *mrb, *pptr = ptr+1; } -static mrb_value +static struct RObject* packed_backtrace(mrb_state *mrb) { struct RData *backtrace; @@ -183,44 +181,51 @@ packed_backtrace(mrb_state *mrb) each_backtrace(mrb, ciidx, count_backtrace_i, &len); size = len * sizeof(struct backtrace_location); + backtrace = mrb_data_object_alloc(mrb, NULL, NULL, &bt_type); ptr = mrb_malloc(mrb, size); - backtrace = mrb_data_object_alloc(mrb, NULL, ptr, &bt_type); + backtrace->data = ptr; backtrace->flags = (uint32_t)len; each_backtrace(mrb, ciidx, pack_backtrace_i, &ptr); - return mrb_obj_value(backtrace); + return (struct RObject*)backtrace; +} + +static void +store_backtrace(mrb_state *mrb, mrb_value exc, struct RObject *backtrace) +{ + struct RException *e = mrb_exc_ptr(exc); + e->backtrace = backtrace; + mrb_field_write_barrier(mrb, (struct RBasic*)e, (struct RBasic*)backtrace); } void mrb_keep_backtrace(mrb_state *mrb, mrb_value exc) { - mrb_sym sym = MRB_SYM(backtrace); - mrb_value backtrace; int ai; - if (mrb_iv_defined(mrb, exc, sym)) return; + if (mrb_exc_ptr(exc)->backtrace) return; ai = mrb_gc_arena_save(mrb); - backtrace = packed_backtrace(mrb); - mrb_iv_set(mrb, exc, sym, backtrace); + struct RObject *backtrace = packed_backtrace(mrb); + store_backtrace(mrb, exc, backtrace); mrb_gc_arena_restore(mrb, ai); } -mrb_value -mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace) +struct RObject* +mrb_unpack_backtrace(mrb_state *mrb, struct RObject *backtrace) { const struct backtrace_location *bt; mrb_int n, i; int ai; - if (mrb_nil_p(backtrace)) { + if (backtrace == NULL) { empty_backtrace: - return mrb_ary_new_capa(mrb, 0); + return mrb_obj_ptr(mrb_ary_new_capa(mrb, 0)); } - if (mrb_array_p(backtrace)) return backtrace; - bt = (struct backtrace_location*)mrb_data_check_get_ptr(mrb, backtrace, &bt_type); + if (backtrace->tt == MRB_TT_ARRAY) return backtrace; + bt = (struct backtrace_location*)mrb_data_check_get_ptr(mrb, mrb_obj_value(backtrace), &bt_type); if (bt == NULL) goto empty_backtrace; - n = (mrb_int)RDATA(backtrace)->flags; + n = (mrb_int)backtrace->flags; if (n == 0) goto empty_backtrace; - backtrace = mrb_ary_new_capa(mrb, n); + backtrace = mrb_obj_ptr(mrb_ary_new_capa(mrb, n)); ai = mrb_gc_arena_save(mrb); for (i = 0; i < n; i++) { const struct backtrace_location *entry = &bt[i]; @@ -236,7 +241,7 @@ mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace) mrb_str_cat_lit(mrb, btline, ":in "); mrb_str_cat_cstr(mrb, btline, mrb_sym_name(mrb, entry->method_id)); } - mrb_ary_push(mrb, backtrace, btline); + mrb_ary_push(mrb, mrb_obj_value(backtrace), btline); mrb_gc_arena_restore(mrb, ai); } @@ -246,20 +251,21 @@ mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace) mrb_value mrb_exc_backtrace(mrb_state *mrb, mrb_value exc) { - mrb_value backtrace; - - backtrace = mrb_iv_get(mrb, exc, MRB_SYM(backtrace)); - if (mrb_nil_p(backtrace) || mrb_array_p(backtrace)) { - return backtrace; + struct RObject *backtrace = mrb_exc_ptr(exc)->backtrace; + if (backtrace == NULL) { + return mrb_nil_value(); + } + if (backtrace->tt == MRB_TT_ARRAY) { + return mrb_obj_value(backtrace); } /* unpack packed-backtrace */ backtrace = mrb_unpack_backtrace(mrb, backtrace); - mrb_iv_set(mrb, exc, MRB_SYM(backtrace), backtrace); - return backtrace; + store_backtrace(mrb, exc, backtrace); + return mrb_obj_value(backtrace); } mrb_value mrb_get_backtrace(mrb_state *mrb) { - return mrb_unpack_backtrace(mrb, packed_backtrace(mrb)); + return mrb_obj_value(mrb_unpack_backtrace(mrb, packed_backtrace(mrb))); } diff --git a/src/cdump.c b/src/cdump.c index b4dfc4e87..1c1d6c1ca 100644 --- a/src/cdump.c +++ b/src/cdump.c @@ -9,6 +9,7 @@ #include #include #include +#include #include @@ -302,7 +303,7 @@ cdump_debug(mrb_state *mrb, const char *name, int n, mrb_irep_debug_info *info, line_type = "mrb_debug_line_flat_map"; fprintf(fp, "static struct mrb_irep_debug_info_line %s_debug_lines_%d[%d] = {", name, n, len); for (i=0; ifiles[0]->lines.flat_map[i]; + const mrb_irep_debug_info_line *fmap = &info->files[0]->lines.flat_map[i]; fprintf(fp, "\t{.start_pos=0x%04x,.line=%d},\n", fmap->start_pos, fmap->line); } fputs("};\n", fp); @@ -310,8 +311,8 @@ cdump_debug(mrb_state *mrb, const char *name, int n, mrb_irep_debug_info *info, case mrb_debug_line_packed_map: line_type = "mrb_debug_line_packed_map"; - fprintf(fp, "static char %s_debug_lines_%d[] = \"", name, n); - uint8_t *pmap = info->files[0]->lines.packed_map; + fprintf(fp, "static const char %s_debug_lines_%d[] = \"", name, n); + const uint8_t *pmap = info->files[0]->lines.packed_map; for (i=0; i #include #include +#include #include union mt_ptr { @@ -150,9 +151,11 @@ mt_get(mrb_state *mrb, mt_tbl *t, mrb_sym sym, union mt_ptr *pp) hash = kh_int_hash_func(mrb, sym); #ifdef MRB_USE_INLINE_METHOD_CACHE int cpos = (hash^(uintptr_t)t) % MT_CACHE_SIZE; + mrb_sym key; pos = mt_cache[cpos]; - if (cpos < t->alloc && t->table[cpos].key == sym) { - return &t->table[cpos]; + if (cpos < t->alloc && key = keys[pos] && MT_KEY_SYM(key) == sym) { + *pp = vals[pos]; + return key; } #endif start = pos = hash & (t->alloc-1); @@ -161,7 +164,7 @@ mt_get(mrb_state *mrb, mt_tbl *t, mrb_sym sym, union mt_ptr *pp) if (MT_KEY_SYM(key) == sym) { *pp = vals[pos]; #ifdef MRB_USE_INLINE_METHOD_CACHE - if (pos < 0xff) { + if (pos < 0x100) { mt_cache[cpos] = pos; } #endif @@ -545,7 +548,7 @@ mrb_define_class(mrb_state *mrb, const char *name, struct RClass *super) return mrb_define_class_id(mrb, mrb_intern_cstr(mrb, name), super); } -static mrb_value mrb_bob_init(mrb_state *mrb, mrb_value); +static mrb_value mrb_do_nothing(mrb_state *mrb, mrb_value); #ifndef MRB_NO_METHOD_CACHE static void mc_clear(mrb_state *mrb); #else @@ -564,7 +567,7 @@ mrb_class_inherited(mrb_state *mrb, struct RClass *super, struct RClass *klass) s = mrb_obj_value(super); mrb_mc_clear_by_class(mrb, klass); mid = MRB_SYM(inherited); - if (!mrb_func_basic_p(mrb, s, mid, mrb_bob_init)) { + if (!mrb_func_basic_p(mrb, s, mid, mrb_do_nothing)) { mrb_value c = mrb_obj_value(klass); mrb_funcall_argv(mrb, s, mid, 1, &c); } @@ -877,8 +880,6 @@ mrb_get_arg1(mrb_state *mrb) return array_argv[0]; } -mrb_int mrb_ci_bidx(mrb_callinfo *ci); - MRB_API mrb_bool mrb_block_given_p(mrb_state *mrb) { @@ -913,7 +914,6 @@ mrb_block_given_p(mrb_state *mrb) b: boolean [mrb_bool] n: String/Symbol [mrb_sym] d: data [void*,mrb_data_type const] 2nd argument will be used to check data type so it won't be modified; when ! follows, the value may be nil - I: inline struct [void*,struct RClass] I! gives NULL for nil &: block [mrb_value] &! raises exception if no block given *: rest argument [const mrb_value*,mrb_int] The rest of the arguments as an array; *! avoid copy of the stack |: optional Following arguments are optional @@ -932,10 +932,10 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) { const char *fmt = format; char c; - int i = 0; + mrb_int i = 0; va_list ap; mrb_callinfo *ci = mrb->c->ci; - int argc = ci->n; + mrb_int argc = ci->n; const mrb_value *argv = ci->stack+1; mrb_bool argv_on_stack; mrb_bool opt = FALSE; @@ -1161,29 +1161,6 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) } } break; - case 'I': - { - void* *p; - struct RClass *klass; - - p = va_arg(ap, void**); - klass = va_arg(ap, struct RClass*); - if (pickarg) { - if (altmode && mrb_nil_p(*pickarg)) { - *p = NULL; - } - else { - if (!mrb_obj_is_kind_of(mrb, *pickarg, klass)) { - mrb_raisef(mrb, E_TYPE_ERROR, "%v is not a %C", *pickarg, klass); - } - if (!mrb_istruct_p(*pickarg)) { - mrb_raisef(mrb, E_TYPE_ERROR, "%v is not inline struct", *pickarg); - } - *p = mrb_istruct_ptr(*pickarg); - } - } - } - break; #ifndef MRB_NO_FLOAT case 'f': { @@ -1376,6 +1353,7 @@ boot_defclass(mrb_state *mrb, struct RClass *super) if (super) { c->super = super; mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)super); + c->flags |= MRB_FL_CLASS_IS_INHERITED; } else { c->super = mrb->object_class; @@ -1970,7 +1948,7 @@ mrb_instance_new(mrb_state *mrb, mrb_value cv) mrb_get_args(mrb, "*!&", &argv, &argc, &blk); obj = mrb_instance_alloc(mrb, cv); init = MRB_SYM(initialize); - if (!mrb_func_basic_p(mrb, obj, init, mrb_bob_init)) { + if (!mrb_func_basic_p(mrb, obj, init, mrb_do_nothing)) { mrb_funcall_with_block(mrb, obj, init, argc, argv, blk); } return obj; @@ -1984,7 +1962,7 @@ mrb_obj_new(mrb_state *mrb, struct RClass *c, mrb_int argc, const mrb_value *arg obj = mrb_instance_alloc(mrb, mrb_obj_value(c)); mid = MRB_SYM(initialize); - if (!mrb_func_basic_p(mrb, obj, mid, mrb_bob_init)) { + if (!mrb_func_basic_p(mrb, obj, mid, mrb_do_nothing)) { mrb_funcall_argv(mrb, obj, mid, argc, argv); } return obj; @@ -2041,7 +2019,7 @@ mrb_class_superclass(mrb_state *mrb, mrb_value klass) } static mrb_value -mrb_bob_init(mrb_state *mrb, mrb_value cv) +mrb_do_nothing(mrb_state *mrb, mrb_value cv) { return mrb_nil_value(); } @@ -2305,8 +2283,6 @@ mrb_mod_to_s(mrb_state *mrb, mrb_value klass) } } -void mrb_method_added(mrb_state *mrb, struct RClass *c, mrb_sym mid); - static mrb_value mrb_mod_alias(mrb_state *mrb, mrb_value mod) { @@ -2363,7 +2339,10 @@ mrb_remove_method(mrb_state *mrb, struct RClass *c, mrb_sym mid) MRB_CLASS_ORIGIN(c); h = c->mt; - if (h && mt_del(mrb, h, mid)) return; + if (h && mt_del(mrb, h, mid)) { + mrb_mc_clear_by_class(mrb, c); + return; + } mrb_name_error(mrb, mid, "method '%n' not defined in %C", mid, c); } @@ -2930,32 +2909,32 @@ mrb_init_class(mrb_state *mrb) MRB_SET_INSTANCE_TT(mrb->proc_class, MRB_TT_PROC); MRB_SET_INSTANCE_TT(cls, MRB_TT_CLASS); - mrb_define_method(mrb, bob, "initialize", mrb_bob_init, MRB_ARGS_NONE()); + mrb_define_method(mrb, bob, "initialize", mrb_do_nothing, MRB_ARGS_NONE()); mrb_define_method(mrb, bob, "!", mrb_bob_not, MRB_ARGS_NONE()); mrb_define_method(mrb, bob, "==", mrb_obj_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.1 */ mrb_define_method(mrb, bob, "__id__", mrb_obj_id_m, MRB_ARGS_NONE()); /* 15.3.1.3.4 */ mrb_define_method(mrb, bob, "__send__", mrb_f_send, MRB_ARGS_REQ(1)|MRB_ARGS_REST()|MRB_ARGS_BLOCK()); /* 15.3.1.3.5 */ mrb_define_method(mrb, bob, "equal?", mrb_obj_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.11 */ mrb_define_method(mrb, bob, "instance_eval", mrb_obj_instance_eval, MRB_ARGS_OPT(1)|MRB_ARGS_BLOCK()); /* 15.3.1.3.18 */ - mrb_define_method(mrb, bob, "singleton_method_added", mrb_bob_init, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, bob, "singleton_method_added", mrb_do_nothing, MRB_ARGS_REQ(1)); mrb_define_class_method(mrb, cls, "new", mrb_class_new_class, MRB_ARGS_OPT(1)|MRB_ARGS_BLOCK()); mrb_define_method(mrb, cls, "allocate", mrb_instance_alloc, MRB_ARGS_NONE()); mrb_define_method(mrb, cls, "superclass", mrb_class_superclass, MRB_ARGS_NONE()); /* 15.2.3.3.4 */ mrb_define_method(mrb, cls, "initialize", mrb_class_initialize, MRB_ARGS_OPT(1)); /* 15.2.3.3.1 */ - mrb_define_method(mrb, cls, "inherited", mrb_bob_init, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, cls, "inherited", mrb_do_nothing, MRB_ARGS_REQ(1)); init_class_new(mrb, cls); MRB_SET_INSTANCE_TT(mod, MRB_TT_MODULE); mrb_define_method(mrb, mod, "extend_object", mrb_mod_extend_object, MRB_ARGS_REQ(1)); /* 15.2.2.4.25 */ - mrb_define_method(mrb, mod, "extended", mrb_bob_init, MRB_ARGS_REQ(1)); /* 15.2.2.4.26 */ - mrb_define_method(mrb, mod, "prepended", mrb_bob_init, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, mod, "extended", mrb_do_nothing, MRB_ARGS_REQ(1)); /* 15.2.2.4.26 */ + mrb_define_method(mrb, mod, "prepended", mrb_do_nothing, MRB_ARGS_REQ(1)); mrb_define_method(mrb, mod, "prepend_features", mrb_mod_prepend_features, MRB_ARGS_REQ(1)); mrb_define_method(mrb, mod, "include?", mrb_mod_include_p, MRB_ARGS_REQ(1)); /* 15.2.2.4.28 */ mrb_define_method(mrb, mod, "append_features", mrb_mod_append_features, MRB_ARGS_REQ(1)); /* 15.2.2.4.10 */ mrb_define_method(mrb, mod, "class_eval", mrb_mod_module_eval, MRB_ARGS_ANY()); /* 15.2.2.4.15 */ - mrb_define_method(mrb, mod, "included", mrb_bob_init, MRB_ARGS_REQ(1)); /* 15.2.2.4.29 */ + mrb_define_method(mrb, mod, "included", mrb_do_nothing, MRB_ARGS_REQ(1)); /* 15.2.2.4.29 */ mrb_define_method(mrb, mod, "initialize", mrb_mod_initialize, MRB_ARGS_NONE()); /* 15.2.2.4.31 */ mrb_define_method(mrb, mod, "module_eval", mrb_mod_module_eval, MRB_ARGS_ANY()); /* 15.2.2.4.35 */ mrb_define_method(mrb, mod, "module_function", mrb_mod_module_function, MRB_ARGS_ANY()); @@ -2978,7 +2957,7 @@ mrb_init_class(mrb_state *mrb) mrb_define_method(mrb, mod, "define_method", mod_define_method, MRB_ARGS_ARG(1,1)); mrb_define_method(mrb, mod, "===", mrb_mod_eqq, MRB_ARGS_REQ(1)); /* 15.2.2.4.7 */ mrb_define_method(mrb, mod, "dup", mrb_mod_dup, MRB_ARGS_NONE()); - mrb_define_method(mrb, bob, "method_added", mrb_bob_init, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, mod, "method_added", mrb_do_nothing, MRB_ARGS_REQ(1)); mrb_undef_method(mrb, cls, "append_features"); mrb_undef_method(mrb, cls, "prepend_features"); diff --git a/src/codedump.c b/src/codedump.c index 5d763fa37..6abb953fd 100644 --- a/src/codedump.c +++ b/src/codedump.c @@ -5,6 +5,7 @@ #include #include #include +#include #ifndef MRB_NO_STDIO static void @@ -42,11 +43,12 @@ print_lv_ab(mrb_state *mrb, const mrb_irep *irep, uint16_t a, uint16_t b) } static void -print_header(mrb_state *mrb, const mrb_irep *irep, uint32_t i) +print_header(mrb_state *mrb, const mrb_irep *irep, ptrdiff_t i) { int32_t line; - line = mrb_debug_get_line(mrb, irep, i); + mrb_assert(i <= UINT32_MAX); + line = mrb_debug_get_line(mrb, irep, (uint32_t)i); if (line < 0) { printf(" "); } @@ -58,8 +60,9 @@ print_header(mrb_state *mrb, const mrb_irep *irep, uint32_t i) } static void -print_args(uint8_t i) +print_args(uint16_t i) { + mrb_assert(i <= 255); uint8_t n = i&0xf; uint8_t nk = (i>>4)&0xf; @@ -78,7 +81,7 @@ print_args(uint8_t i) printf("nk=%d", nk); } } - printf(" (0x%02x)\n", i); + printf("\n"); } #define CASE(insn,ops) case insn: FETCH_ ## ops (); L_ ## insn @@ -97,11 +100,17 @@ codedump(mrb_state *mrb, const mrb_irep *irep) if (irep->lv) { int i; + int head = FALSE; - printf("local variable names:\n"); for (i = 1; i < irep->nlocals; ++i) { char const *s = mrb_sym_dump(mrb, irep->lv[i - 1]); - printf(" R%d:%s\n", i, s ? s : ""); + if (s) { + if (!head) { + head = TRUE; + printf("local variable names:\n"); + } + printf(" R%d:%s\n", i, s); + } } } @@ -149,7 +158,7 @@ codedump(mrb_state *mrb, const mrb_irep *irep) printf("file: %s\n", next_file); file = next_file; } - print_header(mrb, irep, (uint32_t)i); + print_header(mrb, irep, i); ins = READ_B(); switch (ins) { CASE(OP_NOP, Z): @@ -494,16 +503,11 @@ codedump(mrb_state *mrb, const mrb_irep *irep) break; CASE(OP_STRING, BB): mrb_assert((irep->pool[b].tt&IREP_TT_NFLAG)==0); - if ((irep->pool[b].tt & IREP_TT_NFLAG) == 0) { - printf("STRING\tR%d\tL(%d)\t; %s", a, b, irep->pool[b].u.str); - } - else { - printf("STRING\tR%d\tL(%d)\t", a, b); - } + printf("STRING\tR%d\tL(%d)\t; %s", a, b, irep->pool[b].u.str); print_lv_a(mrb, irep, a); break; CASE(OP_STRCAT, B): - printf("STRCAT\tR%d\tR%d", a, a+1); + printf("STRCAT\tR%d\tR%d\t", a, a+1); print_lv_a(mrb, irep, a); break; CASE(OP_HASH, BB): @@ -515,7 +519,7 @@ codedump(mrb_state *mrb, const mrb_irep *irep) print_lv_a(mrb, irep, a); break; CASE(OP_HASHCAT, B): - printf("HASHCAT\tR%d\t", a); + printf("HASHCAT\tR%d\tR%d\t", a, a+1); print_lv_a(mrb, irep, a); break; diff --git a/src/debug.c b/src/debug.c index e570e8068..d0f5ab124 100644 --- a/src/debug.c +++ b/src/debug.c @@ -63,7 +63,7 @@ mrb_packed_int_encode(uint32_t num, uint8_t *p, uint8_t *pend) } uint32_t -mrb_packed_int_decode(uint8_t *p, uint8_t **newpos) +mrb_packed_int_decode(const uint8_t *p, const uint8_t **newpos) { size_t i = 0, shift = 0; uint32_t n = 0; @@ -106,11 +106,11 @@ mrb_debug_get_line(mrb_state *mrb, const mrb_irep *irep, uint32_t pc) case mrb_debug_line_flat_map: { /* get upper bound */ - mrb_irep_debug_info_line *ret = f->lines.flat_map; + const mrb_irep_debug_info_line *ret = f->lines.flat_map; uint32_t count = f->line_entry_count; while (count > 0) { int32_t step = count / 2; - mrb_irep_debug_info_line *it = ret + step; + const mrb_irep_debug_info_line *it = ret + step; if (!(pc < it->start_pos)) { ret = it + 1; count -= step + 1; @@ -131,8 +131,8 @@ mrb_debug_get_line(mrb_state *mrb, const mrb_irep *irep, uint32_t pc) } case mrb_debug_line_packed_map: { - uint8_t *p = f->lines.packed_map; - uint8_t *pend = p + f->line_entry_count; + const uint8_t *p = f->lines.packed_map; + const uint8_t *pend = p + f->line_entry_count; uint32_t pos = 0, line = 0, line_diff; while (p < pend) { pos += mrb_packed_int_decode(p, &p); @@ -209,7 +209,7 @@ mrb_debug_info_append_file(mrb_state *mrb, mrb_irep_debug_info *d, packed_size += mrb_packed_int_len(lines[start_pos+i]-prev_line); prev_line = lines[start_pos + i]; } - p = f->lines.packed_map = (uint8_t*)mrb_malloc(mrb, packed_size); + f->lines.packed_map = p = (uint8_t*)mrb_malloc(mrb, packed_size); pend = p + packed_size; prev_line = 0; prev_pc = 0; for (i = 0; i < file_pc_count; ++i) { diff --git a/src/dump.c b/src/dump.c index 3841e12ac..c0ad4b689 100644 --- a/src/dump.c +++ b/src/dump.c @@ -110,7 +110,7 @@ get_pool_block_size(mrb_state *mrb, const mrb_irep *irep) switch (irep->pool[pool_no].tt) { case IREP_TT_INT64: -#ifdef MRB_64BIT +#if defined(MRB_64BIT) || defined(MRB_INT64) { int64_t i = irep->pool[pool_no].u.i64; @@ -131,7 +131,6 @@ get_pool_block_size(mrb_state *mrb, const mrb_irep *irep) { mrb_int len = irep->pool[pool_no].u.str[0]; mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX); - size += sizeof(uint8_t); size += (size_t)len+2; } break; @@ -173,8 +172,8 @@ write_pool_block(mrb_state *mrb, const mrb_irep *irep, uint8_t *buf) int ai = mrb_gc_arena_save(mrb); switch (irep->pool[pool_no].tt) { -#ifdef MRB_64BIT case IREP_TT_INT64: +#if defined(MRB_64BIT) || defined(MRB_INT64) { int64_t i = irep->pool[pool_no].u.i64; if (i < INT32_MIN || INT32_MAX < i) { @@ -199,7 +198,6 @@ write_pool_block(mrb_state *mrb, const mrb_irep *irep, uint8_t *buf) len = irep->pool[pool_no].u.str[0]; memcpy(cur, irep->pool[pool_no].u.str, (size_t)len+2); cur += len+2; - *cur++ = '\0'; break; case IREP_TT_FLOAT: diff --git a/src/error.c b/src/error.c index 5fa872c9b..8773f1347 100644 --- a/src/error.c +++ b/src/error.c @@ -15,36 +15,24 @@ #include #include #include +#include #include -static void -exc_mesg_set(mrb_state *mrb, struct RException *exc, mrb_value mesg) +void +mrb_exc_mesg_set(mrb_state *mrb, struct RException *exc, mrb_value mesg) { - if (mrb_string_p(mesg)) { - exc->flags |= MRB_EXC_MESG_STRING_FLAG; - exc->mesg = RSTRING(mesg); - mrb_field_write_barrier_value(mrb, (struct RBasic*)exc, mesg); - } - else { - exc->flags &= ~MRB_EXC_MESG_STRING_FLAG; - if (mrb_nil_p(mesg)) { - exc->mesg = 0; - } - else { - mrb_obj_iv_set(mrb, (struct RObject*)exc, MRB_SYM(mesg), mesg); - } + if (!mrb_string_p(mesg)) { + mesg = mrb_obj_as_string(mrb, mesg); } + exc->mesg = mrb_obj_ptr(mesg); + mrb_field_write_barrier_value(mrb, (struct RBasic*)exc, mesg); } -static mrb_value -exc_mesg_get(mrb_state *mrb, struct RException *exc) +mrb_value +mrb_exc_mesg_get(mrb_state *mrb, struct RException *exc) { - if ((exc->flags & MRB_EXC_MESG_STRING_FLAG) != 0) { - return mrb_obj_value(exc->mesg); - } - else { - return mrb_obj_iv_get(mrb, (struct RObject*)exc, MRB_SYM(mesg)); - } + if (exc->mesg == NULL) return mrb_nil_value(); + return mrb_obj_value(exc->mesg); } MRB_API mrb_value @@ -52,14 +40,14 @@ mrb_exc_new_str(mrb_state *mrb, struct RClass* c, mrb_value str) { mrb_ensure_string_type(mrb, str); - struct RBasic* e = mrb_obj_alloc(mrb, MRB_TT_EXCEPTION, c); + struct RException *e = MRB_OBJ_ALLOC(mrb, MRB_TT_EXCEPTION, c); mrb_value exc = mrb_obj_value(e); - mrb_iv_set(mrb, exc, MRB_SYM(mesg), str); + mrb_exc_mesg_set(mrb, e, str); return exc; } MRB_API mrb_value -mrb_exc_new(mrb_state *mrb, struct RClass *c, const char *ptr, size_t len) +mrb_exc_new(mrb_state *mrb, struct RClass *c, const char *ptr, mrb_int len) { return mrb_exc_new_str(mrb, c, mrb_str_new(mrb, ptr, len)); } @@ -78,7 +66,7 @@ exc_initialize(mrb_state *mrb, mrb_value exc) mrb_value mesg; if (mrb_get_args(mrb, "|o", &mesg) == 1) { - exc_mesg_set(mrb, mrb_exc_ptr(exc), mesg); + mrb_exc_mesg_set(mrb, mrb_exc_ptr(exc), mesg); } return exc; } @@ -107,7 +95,7 @@ exc_exception(mrb_state *mrb, mrb_value self) if (argc == 0) return self; if (mrb_obj_equal(mrb, self, a)) return self; exc = mrb_obj_clone(mrb, self); - exc_mesg_set(mrb, mrb_exc_ptr(exc), a); + mrb_exc_mesg_set(mrb, mrb_exc_ptr(exc), a); return exc; } @@ -123,7 +111,7 @@ exc_exception(mrb_state *mrb, mrb_value self) static mrb_value exc_to_s(mrb_state *mrb, mrb_value exc) { - mrb_value mesg = exc_mesg_get(mrb, mrb_exc_ptr(exc)); + mrb_value mesg = mrb_exc_mesg_get(mrb, mrb_exc_ptr(exc)); struct RObject *p; if (!mrb_string_p(mesg)) { @@ -136,20 +124,6 @@ exc_to_s(mrb_state *mrb, mrb_value exc) return mesg; } -/* - * call-seq: - * exception.message -> string - * - * Returns the result of invoking exception.to_s. - * Normally this returns the exception's message or name. - */ - -static mrb_value -exc_message(mrb_state *mrb, mrb_value exc) -{ - return mrb_funcall_id(mrb, exc, MRB_SYM(to_s), 0); -} - /* * call-seq: * exception.inspect -> string @@ -163,10 +137,9 @@ exc_message(mrb_state *mrb, mrb_value exc) mrb_value mrb_exc_inspect(mrb_state *mrb, mrb_value exc) { - mrb_value mesg = exc_mesg_get(mrb, mrb_exc_ptr(exc)); mrb_value cname = mrb_mod_to_s(mrb, mrb_obj_value(mrb_obj_class(mrb, exc))); - mesg = mrb_obj_as_string(mrb, mesg); - return RSTRING_LEN(mesg) == 0 ? cname : mrb_format(mrb, "%v (%v)", mesg, cname); + mrb_value mesg = mrb_exc_mesg_get(mrb, mrb_exc_ptr(exc)); /* string or nil */ + return (mrb_nil_p(mesg)||RSTRING_LEN(mesg)==0) ? cname : mrb_format(mrb, "%v (%v)", mesg, cname); } void mrb_keep_backtrace(mrb_state *mrb, mrb_value exc); @@ -187,7 +160,8 @@ set_backtrace(mrb_state *mrb, mrb_value exc, mrb_value backtrace) p++; } } - mrb_iv_set(mrb, exc, MRB_SYM(backtrace), backtrace); + mrb_exc_ptr(exc)->backtrace = mrb_obj_ptr(backtrace); + mrb_field_write_barrier_value(mrb, mrb_basic_ptr(exc), backtrace); } static mrb_value @@ -534,25 +508,24 @@ exception_call: return mesg; } -MRB_API void +MRB_API mrb_noreturn void mrb_sys_fail(mrb_state *mrb, const char *mesg) { struct RClass *sce; mrb_int no; no = (mrb_int)errno; - if (mrb_class_defined(mrb, "SystemCallError")) { - sce = mrb_class_get(mrb, "SystemCallError"); + if (mrb_class_defined_id(mrb, MRB_SYM(SystemCallError))) { + sce = mrb_class_get_id(mrb, MRB_SYM(SystemCallError)); if (mesg != NULL) { - mrb_funcall(mrb, mrb_obj_value(sce), "_sys_fail", 2, mrb_fixnum_value(no), mrb_str_new_cstr(mrb, mesg)); + mrb_funcall_id(mrb, mrb_obj_value(sce), MRB_SYM(_sys_fail), 2, mrb_fixnum_value(no), mrb_str_new_cstr(mrb, mesg)); } else { - mrb_funcall(mrb, mrb_obj_value(sce), "_sys_fail", 1, mrb_fixnum_value(no)); + mrb_funcall_id(mrb, mrb_obj_value(sce), MRB_SYM(_sys_fail), 1, mrb_fixnum_value(no)); } } - else { - mrb_raise(mrb, E_RUNTIME_ERROR, mesg); - } + + mrb_raise(mrb, E_RUNTIME_ERROR, mesg); } MRB_API mrb_noreturn void @@ -656,6 +629,26 @@ mrb_raise_nomemory(mrb_state *mrb) } } +MRB_API void +mrb_print_error(mrb_state *mrb) +{ +#ifndef MRB_NO_STDIO + if (mrb->jmp == NULL) { + struct mrb_jmpbuf c_jmp; + MRB_TRY(&c_jmp) { + mrb->jmp = &c_jmp; + mrb_print_backtrace(mrb); + } MRB_CATCH(&c_jmp) { + /* ignore exception during print_backtrace() */ + } MRB_END_EXC(&c_jmp); + mrb->jmp = NULL; + } + else { + mrb_print_backtrace(mrb); + } +#endif +} + void mrb_init_exception(mrb_state *mrb) { @@ -667,7 +660,6 @@ mrb_init_exception(mrb_state *mrb) mrb_define_method(mrb, exception, "exception", exc_exception, MRB_ARGS_OPT(1)); mrb_define_method(mrb, exception, "initialize", exc_initialize, MRB_ARGS_OPT(1)); mrb_define_method(mrb, exception, "to_s", exc_to_s, MRB_ARGS_NONE()); - mrb_define_method(mrb, exception, "message", exc_message, MRB_ARGS_NONE()); mrb_define_method(mrb, exception, "inspect", mrb_exc_inspect, MRB_ARGS_NONE()); mrb_define_method(mrb, exception, "backtrace", mrb_exc_backtrace, MRB_ARGS_NONE()); mrb_define_method(mrb, exception, "set_backtrace", exc_set_backtrace, MRB_ARGS_REQ(1)); diff --git a/src/fmt_fp.c b/src/fmt_fp.c index bcb9ccc24..32b793674 100644 --- a/src/fmt_fp.c +++ b/src/fmt_fp.c @@ -78,7 +78,7 @@ static const mrb_float g_neg_pow[] = { int mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, char sign) { char *s = buf; - int buf_remaining = buf_size - 1; + int buf_remaining = (int)buf_size - 1; int alt_form = 0; if ((uint8_t)fmt & 0x80) { @@ -103,7 +103,7 @@ mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, ch } else if (sign) { *s++ = sign; } - buf_remaining -= (s - buf); // Adjust for sign + buf_remaining -= (int)(s - buf); // Adjust for sign { char uc = fmt & 0x20; @@ -118,7 +118,7 @@ mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, ch *s++ = 'N' ^ uc; ret: *s = '\0'; - return s - buf; + return (int)(s - buf); } } @@ -358,6 +358,6 @@ mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, ch } *s = '\0'; - return s - buf; + return (int)(s - buf); } #endif diff --git a/src/gc.c b/src/gc.c index a6ff0c588..486bdccd7 100644 --- a/src/gc.c +++ b/src/gc.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #ifdef MRB_GC_STRESS @@ -192,7 +193,7 @@ gettimeofday_time(void) #define GC_STEP_SIZE 1024 -/* white: 001 or 010, black: 100, gray: 000 */ +/* white: 001 or 010, black: 100, gray: 000, red:111 */ #define GC_GRAY 0 #define GC_WHITE_A 1 #define GC_WHITE_B (1 << 1) @@ -292,7 +293,7 @@ MRB_API void* mrb_alloca(mrb_state *mrb, size_t size) { struct RString *s; - s = MRB_OBJ_ALLOC(mrb, MRB_TT_STRING, mrb->string_class); + s = MRB_OBJ_ALLOC(mrb, MRB_TT_STRING, NULL); return s->as.heap.ptr = (char*)mrb_malloc(mrb, size); } @@ -306,7 +307,7 @@ heap_p(mrb_gc *gc, struct RBasic *object) RVALUE *p; p = objects(page); - if (&p[0].as.basic <= object && object <= &p[MRB_HEAP_PAGE_SIZE].as.basic) { + if (&p[0].as.basic <= object && object <= &p[MRB_HEAP_PAGE_SIZE - 1].as.basic) { return TRUE; } page = page->next; @@ -448,6 +449,7 @@ mrb_gc_destroy(mrb_state *mrb, mrb_gc *gc) static void gc_protect(mrb_state *mrb, mrb_gc *gc, struct RBasic *p) { + if (is_red(p)) return; #ifdef MRB_GC_FIXED_ARENA if (gc->arena_idx >= MRB_GC_ARENA_SIZE) { /* arena overflow error */ @@ -553,6 +555,7 @@ mrb_obj_alloc(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls) ttype != MRB_TT_SCLASS && ttype != MRB_TT_ICLASS && ttype != MRB_TT_ENV && + ttype != MRB_TT_BIGINT && ttype != tt) { mrb_raisef(mrb, E_TYPE_ERROR, "allocation failure of %C", cls); } @@ -760,9 +763,10 @@ gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) case MRB_TT_EXCEPTION: mrb_gc_mark_iv(mrb, (struct RObject*)obj); - if ((obj->flags & MRB_EXC_MESG_STRING_FLAG) != 0) { + if (((struct RException*)obj)->mesg) { mrb_gc_mark(mrb, (struct RBasic*)((struct RException*)obj)->mesg); } + mrb_gc_mark(mrb, (struct RBasic*)((struct RException*)obj)->backtrace); break; default: @@ -907,6 +911,12 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end) break; #endif +#ifdef MRB_USE_BIGINT + case MRB_TT_BIGINT: + mrb_gc_free_bint(mrb, obj); + break; +#endif + default: break; } @@ -1049,7 +1059,10 @@ gc_gray_counts(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) case MRB_TT_EXCEPTION: children += mrb_gc_mark_iv_size(mrb, (struct RObject*)obj); - if ((obj->flags & MRB_EXC_MESG_STRING_FLAG) != 0) { + if (((struct RException*)obj)->mesg) { + children++; + } + if (((struct RException*)obj)->backtrace) { children++; } break; diff --git a/src/hash.c b/src/hash.c index fc6b6fa6b..a0491de27 100644 --- a/src/hash.c +++ b/src/hash.c @@ -11,6 +11,7 @@ #include #include #include +#include #include /* diff --git a/src/kernel.c b/src/kernel.c index 7a261560f..9514c07bd 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -13,6 +13,7 @@ #include #include #include +#include #include MRB_API mrb_bool @@ -215,59 +216,6 @@ mrb_obj_class_m(mrb_state *mrb, mrb_value self) return mrb_obj_value(mrb_obj_class(mrb, self)); } -static mrb_value -mrb_obj_extend(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value obj) -{ - mrb_int i; - - if (argc == 0) { - mrb_argnum_error(mrb, argc, 1, -1); - } - for (i = 0; i < argc; i++) { - mrb_check_type(mrb, argv[i], MRB_TT_MODULE); - } - while (argc--) { - mrb_funcall_id(mrb, argv[argc], MRB_SYM(extend_object), 1, obj); - mrb_funcall_id(mrb, argv[argc], MRB_SYM(extended), 1, obj); - } - return obj; -} - -/* 15.3.1.3.13 */ -/* - * call-seq: - * obj.extend(module, ...) -> obj - * - * Adds to _obj_ the instance methods from each module given as a - * parameter. - * - * module Mod - * def hello - * "Hello from Mod.\n" - * end - * end - * - * class Klass - * def hello - * "Hello from Klass.\n" - * end - * end - * - * k = Klass.new - * k.hello #=> "Hello from Klass.\n" - * k.extend(Mod) #=> # - * k.hello #=> "Hello from Mod.\n" - */ -static mrb_value -mrb_obj_extend_m(mrb_state *mrb, mrb_value self) -{ - const mrb_value *argv; - mrb_int argc; - - mrb_get_args(mrb, "*", &argv, &argc); - return mrb_obj_extend(mrb, argc, argv, self); -} - MRB_API mrb_value mrb_obj_freeze(mrb_state *mrb, mrb_value self) { @@ -589,13 +537,13 @@ mrb_obj_ceqq(mrb_state *mrb, mrb_value self) else if (mrb_nil_p(self)) { return mrb_false_value(); } - else if (!mrb_respond_to(mrb, self, mrb_intern_lit(mrb, "to_a"))) { + else if (!mrb_respond_to(mrb, self, MRB_SYM(to_a))) { mrb_value c = mrb_funcall_argv(mrb, self, eqq, 1, &v); if (mrb_test(c)) return mrb_true_value(); return mrb_false_value(); } else { - ary = mrb_funcall(mrb, self, "to_a", 0); + ary = mrb_funcall_id(mrb, self, MRB_SYM(to_a), 0); if (mrb_nil_p(ary)) { return mrb_funcall_argv(mrb, self, eqq, 1, &v); } @@ -640,7 +588,6 @@ mrb_init_kernel(mrb_state *mrb) mrb_define_method(mrb, krn, "clone", mrb_obj_clone, MRB_ARGS_NONE()); /* 15.3.1.3.8 */ mrb_define_method(mrb, krn, "dup", mrb_obj_dup, MRB_ARGS_NONE()); /* 15.3.1.3.9 */ mrb_define_method(mrb, krn, "eql?", mrb_obj_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.10 */ - mrb_define_method(mrb, krn, "extend", mrb_obj_extend_m, MRB_ARGS_ANY()); /* 15.3.1.3.13 */ mrb_define_method(mrb, krn, "freeze", mrb_obj_freeze, MRB_ARGS_NONE()); mrb_define_method(mrb, krn, "frozen?", mrb_obj_frozen, MRB_ARGS_NONE()); mrb_define_method(mrb, krn, "hash", mrb_obj_hash, MRB_ARGS_NONE()); /* 15.3.1.3.15 */ diff --git a/src/load.c b/src/load.c index bb22a6130..1916c6c9d 100644 --- a/src/load.c +++ b/src/load.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #if SIZE_MAX < UINT32_MAX @@ -162,17 +163,16 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, const uint8_t *end, size_ #endif case IREP_TT_BIGINT: - pool_data_len = bin_to_uint8(src); /* pool data length */ - src += sizeof(uint8_t); + pool_data_len = bin_to_uint8(src) + 2; /* pool data length */ if (src + pool_data_len > end) return FALSE; - { + else { char *p; pool[i].tt = IREP_TT_BIGINT; - p = (char*)mrb_malloc(mrb, pool_data_len+2); - memcpy(p, src, pool_data_len+2); + p = (char*)mrb_malloc(mrb, pool_data_len); + memcpy(p, src, pool_data_len); pool[i].u.str = (const char*)p; } - src += pool_data_len + 2; + src += pool_data_len; break; case IREP_TT_FLOAT: @@ -352,11 +352,12 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, const uint8_t *end, mrb_ size_t l = sizeof(uint16_t) * (size_t)file->line_entry_count; if (bin + l > end) return MRB_DUMP_GENERAL_FAILURE; - file->lines.ary = (uint16_t *)mrb_malloc(mrb, l); + uint16_t *ary = (uint16_t *)mrb_malloc(mrb, l); for (l = 0; l < file->line_entry_count; ++l) { - file->lines.ary[l] = bin_to_uint16(bin); + ary[l] = bin_to_uint16(bin); bin += sizeof(uint16_t); } + file->lines.ary = ary; } break; case mrb_debug_line_flat_map: { @@ -364,21 +365,23 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, const uint8_t *end, mrb_ size_t n = sizeof(mrb_irep_debug_info_line); if (bin + c*n > end) return MRB_DUMP_GENERAL_FAILURE; - file->lines.flat_map = (mrb_irep_debug_info_line*)mrb_calloc(mrb, c, n); + mrb_irep_debug_info_line *flat_map = (mrb_irep_debug_info_line*)mrb_calloc(mrb, c, n); for (size_t l = 0; l < file->line_entry_count; ++l) { - file->lines.flat_map[l].start_pos = bin_to_uint32(bin); + flat_map[l].start_pos = bin_to_uint32(bin); bin += sizeof(uint32_t); - file->lines.flat_map[l].line = bin_to_uint16(bin); + flat_map[l].line = bin_to_uint16(bin); bin += sizeof(uint16_t); } + file->lines.flat_map = flat_map; } break; case mrb_debug_line_packed_map: { size_t l = (size_t)file->line_entry_count; if (bin + l > end) return MRB_DUMP_GENERAL_FAILURE; - file->lines.packed_map = (uint8_t*)mrb_calloc(mrb, 1, l); - memcpy(file->lines.packed_map, bin, file->line_entry_count); + uint8_t *packed_map = (uint8_t*)mrb_malloc(mrb, l); + memcpy(packed_map, bin, file->line_entry_count); + file->lines.packed_map = packed_map; bin += file->line_entry_count; } break; diff --git a/src/numeric.c b/src/numeric.c index fb3c0e48f..27a7cb8c3 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -20,14 +21,14 @@ #endif #endif -static void -int_overflow(mrb_state *mrb, const char *reason) +void +mrb_int_overflow(mrb_state *mrb, const char *reason) { mrb_raisef(mrb, E_RANGE_ERROR, "integer overflow in %s", reason); } -static void -int_zerodiv(mrb_state *mrb) +void +mrb_int_zerodiv(mrb_state *mrb) { mrb_raise(mrb, E_ZERODIV_ERROR, "divided by 0"); } @@ -41,9 +42,21 @@ int_zerodiv(mrb_state *mrb) * * 2.0**3 #=> 8.0 */ -static mrb_value -int_pow(mrb_state *mrb, mrb_value x) +mrb_value +mrb_int_pow(mrb_state *mrb, mrb_value x) { +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + mrb_value y = mrb_get_arg1(mrb); + +#ifndef MRB_NO_FLOAT + if (mrb_float_p(y)) { + return mrb_float_value(mrb, pow(mrb_bint_as_float(mrb, x), mrb_float(y))); + } +#endif + return mrb_bint_pow(mrb, x, y); + } +#endif mrb_int base = mrb_integer(x); mrb_int result = 1; mrb_int exp; @@ -66,32 +79,41 @@ int_pow(mrb_state *mrb, mrb_value x) #ifndef MRB_NO_FLOAT return mrb_float_value(mrb, pow((double)base, (double)exp)); #else - int_overflow(mrb, "negative power"); + mrb_int_overflow(mrb, "negative power"); #endif } for (;;) { if (exp & 1) { if (mrb_int_mul_overflow(result, base, &result)) { - int_overflow(mrb, "power"); +#ifdef MRB_USE_BIGINT + return mrb_bint_pow(mrb, mrb_bint_new_int(mrb, mrb_integer(x)), y); +#else + mrb_int_overflow(mrb, "power"); +#endif } } exp >>= 1; if (exp == 0) break; if (mrb_int_mul_overflow(base, base, &base)) { - int_overflow(mrb, "power"); +#ifdef MRB_USE_BIGINT + return mrb_bint_pow(mrb, mrb_bint_new_int(mrb, mrb_integer(x)), y); +#else + mrb_int_overflow(mrb, "power"); +#endif } } return mrb_int_value(mrb, result); } +#define int_pow mrb_int_pow mrb_int mrb_div_int(mrb_state *mrb, mrb_int x, mrb_int y) { if (y == 0) { - int_zerodiv(mrb); + mrb_int_zerodiv(mrb); } else if(x == MRB_INT_MIN && y == -1) { - int_overflow(mrb, "division"); + mrb_int_overflow(mrb, "division"); } else { mrb_int div = x / y; @@ -119,17 +141,44 @@ static mrb_value int_div(mrb_state *mrb, mrb_value x) { mrb_value y = mrb_get_arg1(mrb); +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_bint_div(mrb, x, y); + } +#endif mrb_int a = mrb_integer(x); if (mrb_integer_p(y)) { - mrb_int div = mrb_div_int(mrb, a, mrb_integer(y)); + mrb_int b = mrb_integer(y); +#ifdef MRB_USE_BIGINT + if(a == MRB_INT_MIN && b == -1) { + return mrb_bint_mul_ii(mrb, a, b); + } +#endif + mrb_int div = mrb_div_int(mrb, a, b); return mrb_int_value(mrb, div); } -#ifdef MRB_NO_FLOAT - mrb_raise(mrb, E_TYPE_ERROR, "non integer division"); -#else - return mrb_float_value(mrb, mrb_div_float((mrb_float)a, mrb_as_float(mrb, y))); + switch (mrb_type(y)) { +#ifdef MRB_USE_BIGINT + case MRB_TT_BIGINT: + return mrb_bint_div(mrb, mrb_bint_new_int(mrb, a), y); #endif +#ifdef MRB_USE_RATIONAL + case MRB_TT_RATIONAL: + return mrb_rational_div(mrb, mrb_rational_new(mrb, a, 1), y); +#endif +#ifdef MRB_USE_COMPLEX + case MRB_TT_COMPLEX: + x = mrb_complex_new(mrb, (mrb_float)a, 0); + return mrb_complex_div(mrb, x, y); +#endif + default: +#ifdef MRB_NO_FLOAT + mrb_raise(mrb, E_TYPE_ERROR, "non integer division"); +#else + return mrb_float_value(mrb, mrb_div_float((mrb_float)a, mrb_as_float(mrb, y))); +#endif + } } /* 15.2.9.3.19(x) */ @@ -149,28 +198,54 @@ int_div(mrb_state *mrb, mrb_value x) static mrb_value int_idiv(mrb_state *mrb, mrb_value x) { +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_bint_div(mrb, x, mrb_get_arg1(mrb)); + } +#endif mrb_int y; mrb_get_args(mrb, "i", &y); - if (y == 0) { - int_zerodiv(mrb); - } - return mrb_int_value(mrb, mrb_integer(x) / y); + return mrb_int_value(mrb, mrb_div_int(mrb, mrb_integer(x), y)); } static mrb_value -int_quo(mrb_state *mrb, mrb_value xv) +int_quo(mrb_state *mrb, mrb_value x) { +#ifndef MRB_USE_RATIONAL #ifdef MRB_NO_FLOAT - return int_idiv(mrb, xv); + return int_idiv(mrb, x); #else mrb_float y; mrb_get_args(mrb, "f", &y); if (y == 0) { - int_zerodiv(mrb); + mrb_int_zerodiv(mrb); + } +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_float_value(mrb, mrb_bint_as_float(mrb, x) / y); + } +#endif + return mrb_float_value(mrb, mrb_integer(x) / y); +#endif +#else + mrb_int a = mrb_integer(x); + mrb_value y = mrb_get_arg1(mrb); + if (mrb_integer_p(y) && mrb_class_defined_id(mrb, MRB_SYM(Rational))) { + return mrb_rational_new(mrb, a, mrb_integer(y)); + } + switch (mrb_type(y)) { + case MRB_TT_RATIONAL: + x = mrb_rational_new(mrb, a, 1); + return mrb_rational_div(mrb, x, y); + default: +#ifdef MRB_NO_FLOAT + mrb_raise(mrb, E_TYPE_ERROR, "non integer division"); +#else + return mrb_float_value(mrb, mrb_div_float((mrb_float)a, mrb_as_float(mrb, y))); +#endif } - return mrb_float_value(mrb, mrb_integer(xv) / y); #endif } @@ -184,7 +259,7 @@ coerce_step_counter(mrb_state *mrb, mrb_value self) #ifndef MRB_NO_FLOAT mrb->c->ci->mid = 0; if (mrb_float_p(num) || mrb_float_p(step)) { - return mrb_to_float(mrb, self); + return mrb_ensure_float_type(mrb, self); } #endif @@ -239,11 +314,17 @@ flo_div(mrb_state *mrb, mrb_value x) mrb_value y = mrb_get_arg1(mrb); mrb_float a = mrb_float(x); - if (mrb_float_p(y)) { + switch(mrb_type(y)) { +#ifdef MRB_USE_COMPLEX + case MRB_TT_COMPLEX: + return mrb_complex_div(mrb, mrb_complex_new(mrb, a, 0), y); +#endif + case MRB_TT_FLOAT: a = mrb_div_float(a, mrb_float(y)); - } - else { + return mrb_float_value(mrb, a); + default: a = mrb_div_float(a, mrb_as_float(mrb, y)); + return mrb_float_value(mrb, a); } return mrb_float_value(mrb, a); } @@ -328,7 +409,7 @@ flo_add(mrb_state *mrb, mrb_value x) return mrb_float_value(mrb, a + mrb_float(y)); #if defined(MRB_USE_COMPLEX) case MRB_TT_COMPLEX: - return mrb_funcall_id(mrb, y, MRB_OPSYM(add), 1, x); + return mrb_complex_add(mrb, y, x); #endif default: return mrb_float_value(mrb, a + mrb_as_float(mrb, y)); @@ -355,8 +436,7 @@ flo_sub(mrb_state *mrb, mrb_value x) return mrb_float_value(mrb, a - mrb_float(y)); #if defined(MRB_USE_COMPLEX) case MRB_TT_COMPLEX: - x = mrb_funcall_id(mrb, y, MRB_OPSYM(sub), 1, x); - return mrb_funcall_id(mrb, x, MRB_OPSYM(minus), 0); + return mrb_complex_sub(mrb, mrb_complex_new(mrb, a, 0), y); #endif default: return mrb_float_value(mrb, a - mrb_as_float(mrb, y)); @@ -383,7 +463,7 @@ flo_mul(mrb_state *mrb, mrb_value x) return mrb_float_value(mrb, a * mrb_float(y)); #if defined(MRB_USE_COMPLEX) case MRB_TT_COMPLEX: - return mrb_funcall_id(mrb, y, MRB_OPSYM(mul), 1, x); + return mrb_complex_mul(mrb, y, x); #endif default: return mrb_float_value(mrb, a * mrb_as_float(mrb, y)); @@ -401,7 +481,7 @@ flodivmod(mrb_state *mrb, double x, double y, mrb_float *divp, mrb_float *modp) goto exit; } if (y == 0.0) { - int_zerodiv(mrb); + mrb_int_zerodiv(mrb); } if (isinf(y) && !isinf(x)) { mod = x; @@ -467,6 +547,11 @@ int_eql(mrb_state *mrb, mrb_value x) { mrb_value y = mrb_get_arg1(mrb); +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_bool_value(mrb_bint_cmp(mrb, x, y) == 0); + } +#endif if (!mrb_integer_p(y)) return mrb_false_value(); return mrb_bool_value(mrb_integer(x) == mrb_integer(y)); } @@ -542,7 +627,7 @@ static mrb_value int64_value(mrb_state *mrb, int64_t v) { if (!TYPED_FIXABLE(v,int64_t)) { - int_overflow(mrb, "bit operation"); + mrb_int_overflow(mrb, "bit operation"); } return mrb_fixnum_value((mrb_int)v); } @@ -733,12 +818,12 @@ flo_ceil_floor(mrb_state *mrb, mrb_value num, double (*func)(double)) } if (ndigits > 0) { if (ndigits > fprec) return num; - mrb_float d = pow(10, ndigits); + mrb_float d = pow(10, (double)ndigits); f = func(f * d) / d; return mrb_float_value(mrb, f); } if (ndigits < 0) { - mrb_float d = pow(10, -ndigits); + mrb_float d = pow(10, (double)-ndigits); f = func(f / d) * d; } else { /* ndigits == 0 */ @@ -930,10 +1015,18 @@ flo_to_i(mrb_state *mrb, mrb_value num) { mrb_float f = mrb_float(num); + mrb_check_num_exact(mrb, f); + + if (!FIXABLE_FLOAT(f)) { +#ifdef MRB_USE_BIGINT + return mrb_bint_new_float(mrb, f); +#else + mrb_int_overflow(mrb, "to_f"); +#endif + } if (f > 0.0) f = floor(f); if (f < 0.0) f = ceil(f); - mrb_check_num_exact(mrb, f); return mrb_int_value(mrb, (mrb_int)f); } @@ -991,8 +1084,8 @@ int_to_i(mrb_state *mrb, mrb_value num) return num; } -static mrb_value -fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y) +mrb_value +mrb_int_mul(mrb_state *mrb, mrb_value x, mrb_value y) { mrb_int a; @@ -1003,15 +1096,27 @@ fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y) if (a == 0) return x; b = mrb_integer(y); if (mrb_int_mul_overflow(a, b, &c)) { - int_overflow(mrb, "multiplication"); +#ifdef MRB_USE_BIGINT + x = mrb_bint_new_int(mrb, a); + return mrb_bint_mul(mrb, x, y); +#else + mrb_int_overflow(mrb, "multiplication"); +#endif } return mrb_int_value(mrb, c); } switch (mrb_type(y)) { -#if defined(MRB_USE_RATIONAL) || defined(MRB_USE_COMPLEX) +#ifdef MRB_USE_BIGINT + case MRB_TT_BIGINT: + return mrb_bint_mul(mrb, y, x); +#endif +#ifdef MRB_USE_RATIONAL case MRB_TT_RATIONAL: + return mrb_rational_mul(mrb, y, x); +#endif +#ifdef MRB_USE_COMPLEX case MRB_TT_COMPLEX: - return mrb_funcall_id(mrb, y, MRB_OPSYM(mul), 1, x); + return mrb_complex_mul(mrb, y, x); #endif default: #ifdef MRB_NO_FLOAT @@ -1022,30 +1127,6 @@ fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y) } } -MRB_API mrb_value -mrb_num_mul(mrb_state *mrb, mrb_value x, mrb_value y) -{ - if (mrb_integer_p(x)) { - return fixnum_mul(mrb, x, y); - } -#ifndef MRB_NO_FLOAT - if (mrb_float_p(x)) { - return mrb_float_value(mrb, mrb_float(x) * mrb_as_float(mrb, y)); - } -#endif -#if defined(MRB_USE_RATIONAL) || defined(MRB_USE_COMPLEX) - switch (mrb_type(x)) { - case MRB_TT_RATIONAL: - case MRB_TT_COMPLEX: - return mrb_funcall_id(mrb, x, MRB_OPSYM(mul), 1, y); - default: - break; - } -#endif - mrb_raise(mrb, E_TYPE_ERROR, "no number multiply"); - return mrb_nil_value(); /* not reached */ -} - /* 15.2.8.3.3 */ /* * call-seq: @@ -1061,17 +1142,22 @@ int_mul(mrb_state *mrb, mrb_value x) { mrb_value y = mrb_get_arg1(mrb); - return fixnum_mul(mrb, x, y); +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_bint_mul(mrb, x, y); + } +#endif + return mrb_int_mul(mrb, x, y); } static void intdivmod(mrb_state *mrb, mrb_int x, mrb_int y, mrb_int *divp, mrb_int *modp) { if (y == 0) { - int_zerodiv(mrb); + mrb_int_zerodiv(mrb); } else if(x == MRB_INT_MIN && y == -1) { - int_overflow(mrb, "division"); + mrb_int_overflow(mrb, "division"); } else { mrb_int div = x / y; @@ -1101,10 +1187,15 @@ int_mod(mrb_state *mrb, mrb_value x) mrb_value y = mrb_get_arg1(mrb); mrb_int a, b; +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_bint_mod(mrb, x, y); + } +#endif a = mrb_integer(x); if (mrb_integer_p(y)) { b = mrb_integer(y); - if (b == 0) int_zerodiv(mrb); + if (b == 0) mrb_int_zerodiv(mrb); if (a == MRB_INT_MIN && b == -1) return mrb_fixnum_value(0); mrb_int mod = a % b; if ((a < 0) != (b < 0) && mod != 0) { @@ -1122,6 +1213,10 @@ int_mod(mrb_state *mrb, mrb_value x) #endif } +#ifndef MRB_NO_FLOAT +static mrb_value flo_divmod(mrb_state *mrb, mrb_value x); +#endif + /* * call-seq: * int.divmod(numeric) -> array @@ -1133,6 +1228,17 @@ int_divmod(mrb_state *mrb, mrb_value x) { mrb_value y = mrb_get_arg1(mrb); +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { +#ifndef MRB_NO_FLOAT + if (mrb_float_p(y)) { + mrb_float f = mrb_bint_as_float(mrb, x); + return flo_divmod(mrb, mrb_float_value(mrb, f)); + } +#endif + return mrb_bint_divmod(mrb, x, y); + } +#endif if (mrb_integer_p(y)) { mrb_int div, mod; @@ -1142,15 +1248,7 @@ int_divmod(mrb_state *mrb, mrb_value x) #ifdef MRB_NO_FLOAT mrb_raise(mrb, E_TYPE_ERROR, "non integer divmod"); #else - else { - mrb_float div, mod; - mrb_value a, b; - - flodivmod(mrb, (mrb_float)mrb_integer(x), mrb_as_float(mrb, y), &div, &mod); - a = mrb_int_value(mrb, (mrb_int)div); - b = mrb_float_value(mrb, mod); - return mrb_assoc_new(mrb, a, b); - } + return flo_divmod(mrb, x); #endif } @@ -1196,6 +1294,10 @@ int_equal(mrb_state *mrb, mrb_value x) case MRB_TT_FLOAT: return mrb_bool_value((mrb_float)mrb_integer(x) == mrb_float(y)); #endif +#ifdef MRB_USE_BIGINT + case MRB_TT_BIGINT: + return mrb_bool_value(mrb_bint_cmp(mrb, y, x) == 0); +#endif #ifdef MRB_USE_RATIONAL case MRB_TT_RATIONAL: return mrb_bool_value(mrb_equal(mrb, y, x)); @@ -1225,6 +1327,11 @@ int_rev(mrb_state *mrb, mrb_value num) { mrb_int val = mrb_integer(num); +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(num)) { + mrb_bint_rev(mrb, num); + } +#endif return mrb_int_value(mrb, ~val); } @@ -1255,6 +1362,11 @@ int_and(mrb_state *mrb, mrb_value x) { mrb_value y = mrb_get_arg1(mrb); +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_bint_and(mrb, x, y); + } +#endif bit_op(x, y, and, &); } @@ -1271,6 +1383,11 @@ int_or(mrb_state *mrb, mrb_value x) { mrb_value y = mrb_get_arg1(mrb); +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_bint_or(mrb, x, y); + } +#endif bit_op(x, y, or, |); } @@ -1287,6 +1404,11 @@ int_xor(mrb_state *mrb, mrb_value x) { mrb_value y = mrb_get_arg1(mrb); +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_bint_xor(mrb, x, y); + } +#endif bit_op(x, y, or, ^); } @@ -1345,10 +1467,20 @@ int_lshift(mrb_state *mrb, mrb_value x) if (width == 0) { return x; } + if (width == MRB_INT_MIN) mrb_int_overflow(mrb, "bit shift"); +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_bint_lshift(mrb, x, width); + } +#endif val = mrb_integer(x); if (val == 0) return x; if (!mrb_num_shift(mrb, val, width, &val)) { - int_overflow(mrb, "bit shift"); +#ifdef MRB_USE_BIGINT + return mrb_bint_lshift(mrb, mrb_bint_new_int(mrb, val), width); +#else + mrb_int_overflow(mrb, "bit shift"); +#endif } return mrb_int_value(mrb, val); } @@ -1370,11 +1502,20 @@ int_rshift(mrb_state *mrb, mrb_value x) if (width == 0) { return x; } + if (width == MRB_INT_MIN) mrb_int_overflow(mrb, "bit shift"); +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_bint_rshift(mrb, x, width); + } +#endif val = mrb_integer(x); if (val == 0) return x; - if (width == MRB_INT_MIN) int_overflow(mrb, "bit shift"); if (!mrb_num_shift(mrb, val, -width, &val)) { - int_overflow(mrb, "bit shift"); +#ifdef MRB_USE_BIGINT + return mrb_bint_rshift(mrb, mrb_bint_new_int(mrb, val), width); +#else + mrb_int_overflow(mrb, "bit shift"); +#endif } return mrb_int_value(mrb, val); } @@ -1392,6 +1533,11 @@ int_rshift(mrb_state *mrb, mrb_value x) static mrb_value int_to_f(mrb_state *mrb, mrb_value num) { +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(num)) { + return mrb_float_value(mrb, mrb_bint_as_float(mrb, num)); + } +#endif return mrb_float_value(mrb, (mrb_float)mrb_integer(num)); } @@ -1425,15 +1571,19 @@ mrb_float_to_integer(mrb_state *mrb, mrb_value x) z = (mrb_int)d; } else { +#ifdef MRB_USE_BIGINT + return mrb_bint_new_float(mrb, d); +#else mrb_raisef(mrb, E_RANGE_ERROR, "number (%v) too big for integer", x); +#endif } } return mrb_int_value(mrb, z); } #endif -static mrb_value -int_plus(mrb_state *mrb, mrb_value x, mrb_value y) +mrb_value +mrb_int_add(mrb_state *mrb, mrb_value x, mrb_value y) { mrb_int a; @@ -1444,15 +1594,27 @@ int_plus(mrb_state *mrb, mrb_value x, mrb_value y) if (a == 0) return y; b = mrb_integer(y); if (mrb_int_add_overflow(a, b, &c)) { - int_overflow(mrb, "addition"); +#ifdef MRB_USE_BIGINT + x = mrb_bint_new_int(mrb, a); + return mrb_bint_add(mrb, x, y); +#else + mrb_int_overflow(mrb, "addition"); +#endif } return mrb_int_value(mrb, c); } switch (mrb_type(y)) { -#if defined(MRB_USE_RATIONAL) || defined(MRB_USE_COMPLEX) +#ifdef MRB_USE_BIGINT + case MRB_TT_BIGINT: + return mrb_bint_add(mrb, y, x); +#endif +#ifdef MRB_USE_RATIONAL case MRB_TT_RATIONAL: + return mrb_rational_add(mrb, y, x); +#endif +#ifdef MRB_USE_COMPLEX case MRB_TT_COMPLEX: - return mrb_funcall_id(mrb, y, MRB_OPSYM(add), 1, x); + return mrb_complex_add(mrb, y, x); #endif default: #ifdef MRB_NO_FLOAT @@ -1463,30 +1625,6 @@ int_plus(mrb_state *mrb, mrb_value x, mrb_value y) } } -MRB_API mrb_value -mrb_num_plus(mrb_state *mrb, mrb_value x, mrb_value y) -{ - if (mrb_integer_p(x)) { - return int_plus(mrb, x, y); - } -#ifndef MRB_NO_FLOAT - if (mrb_float_p(x)) { - return mrb_float_value(mrb, mrb_float(x) + mrb_as_float(mrb, y)); - } -#endif -#if defined(MRB_USE_RATIONAL) || defined(MRB_USE_COMPLEX) - switch (mrb_type(x)) { - case MRB_TT_RATIONAL: - case MRB_TT_COMPLEX: - return mrb_funcall_id(mrb, x, MRB_OPSYM(add), 1, y); - default: - break; - } -#endif - mrb_raise(mrb, E_TYPE_ERROR, "no number addition"); - return mrb_nil_value(); /* not reached */ -} - /* 15.2.8.3.1 */ /* * call-seq: @@ -1501,11 +1639,16 @@ int_add(mrb_state *mrb, mrb_value self) { mrb_value other = mrb_get_arg1(mrb); - return int_plus(mrb, self, other); +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(self)) { + return mrb_bint_add(mrb, self, other); + } +#endif + return mrb_int_add(mrb, self, other); } -static mrb_value -int_minus(mrb_state *mrb, mrb_value x, mrb_value y) +mrb_value +mrb_int_sub(mrb_state *mrb, mrb_value x, mrb_value y) { mrb_int a; @@ -1515,16 +1658,27 @@ int_minus(mrb_state *mrb, mrb_value x, mrb_value y) b = mrb_integer(y); if (mrb_int_sub_overflow(a, b, &c)) { - int_overflow(mrb, "subtraction"); +#ifdef MRB_USE_BIGINT + x = mrb_bint_new_int(mrb, a); + return mrb_bint_sub(mrb, x, y); +#else + mrb_int_overflow(mrb, "subtraction"); +#endif } return mrb_int_value(mrb, c); } switch (mrb_type(y)) { -#if defined(MRB_USE_RATIONAL) || defined(MRB_USE_COMPLEX) +#ifdef MRB_USE_BIGINT + case MRB_TT_BIGINT: + return mrb_bint_sub(mrb, mrb_bint_new_int(mrb, a), y); +#endif +#ifdef MRB_USE_RATIONAL case MRB_TT_RATIONAL: + return mrb_rational_sub(mrb, mrb_rational_new(mrb, a, 1), y); +#endif +#ifdef MRB_USE_COMPLEX case MRB_TT_COMPLEX: - x = mrb_funcall_id(mrb, y, MRB_OPSYM(sub), 1, x); - return mrb_funcall_id(mrb, x, MRB_OPSYM(minus), 0); + return mrb_complex_sub(mrb, mrb_complex_new(mrb, (mrb_float)a, 0), y); #endif default: #ifdef MRB_NO_FLOAT @@ -1535,30 +1689,6 @@ int_minus(mrb_state *mrb, mrb_value x, mrb_value y) } } -MRB_API mrb_value -mrb_num_minus(mrb_state *mrb, mrb_value x, mrb_value y) -{ - if (mrb_integer_p(x)) { - return int_minus(mrb, x, y); - } -#ifndef MRB_NO_FLOAT - if (mrb_float_p(x)) { - return mrb_float_value(mrb, mrb_float(x) - mrb_as_float(mrb, y)); - } -#endif -#if defined(MRB_USE_RATIONAL) || defined(MRB_USE_COMPLEX) - switch (mrb_type(x)) { - case MRB_TT_RATIONAL: - case MRB_TT_COMPLEX: - return mrb_funcall_id(mrb, x, MRB_OPSYM(sub), 1, y); - default: - break; - } -#endif - mrb_raise(mrb, E_TYPE_ERROR, "no number subtraction"); - return mrb_nil_value(); /* not reached */ -} - /* 15.2.8.3.2 */ /* 15.2.8.3.16 */ /* @@ -1574,7 +1704,12 @@ int_sub(mrb_state *mrb, mrb_value self) { mrb_value other = mrb_get_arg1(mrb); - return int_minus(mrb, self, other); +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(self)) { + return mrb_bint_sub(mrb, self, other); + } +#endif + return mrb_int_sub(mrb, self, other); } MRB_API char* @@ -1619,6 +1754,11 @@ mrb_integer_to_str(mrb_state *mrb, mrb_value x, mrb_int base) if (base < 2 || 36 < base) { mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %i", base); } +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_bint_to_s(mrb, x, base); + } +#endif const char *p = mrb_int_to_cstr(buf, sizeof(buf), val, base); mrb_assert(p != NULL); mrb_value str = mrb_str_new_cstr(mrb, p); @@ -1648,6 +1788,11 @@ int_to_s(mrb_state *mrb, mrb_value self) mrb_int base = 10; mrb_get_args(mrb, "|i", &base); +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(self)) { + return mrb_bint_to_s(mrb, self, base); + } +#endif return mrb_integer_to_str(mrb, self, base); } @@ -1655,6 +1800,12 @@ int_to_s(mrb_state *mrb, mrb_value self) static mrb_int cmpnum(mrb_state *mrb, mrb_value v1, mrb_value v2) { +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(v2)) { + return mrb_bint_cmp(mrb, v1, v2); + } +#endif + #ifdef MRB_NO_FLOAT mrb_int x, y; #else @@ -1787,6 +1938,7 @@ mrb_cmp(mrb_state *mrb, mrb_value obj1, mrb_value obj2) return -2; return mrb_str_cmp(mrb, obj1, obj2); default: + if (!mrb_respond_to(mrb, obj1, MRB_OPSYM(cmp))) return -2; v = mrb_funcall_id(mrb, obj1, MRB_OPSYM(cmp), 1, obj2); if (mrb_nil_p(v) || !mrb_integer_p(v)) return -2; diff --git a/src/numops.c b/src/numops.c new file mode 100644 index 000000000..ff8adc2d6 --- /dev/null +++ b/src/numops.c @@ -0,0 +1,112 @@ +/* +** numeric.c - Numeric, Integer, Float class +** +** See Copyright Notice in mruby.h +*/ + +#include +#include +#include +#include + +MRB_API mrb_value +mrb_num_add(mrb_state *mrb, mrb_value x, mrb_value y) +{ +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_bint_add(mrb, x, y); + } +#endif + if (mrb_integer_p(x)) { + return mrb_int_add(mrb, x, y); + } +#ifndef MRB_NO_FLOAT + if (mrb_float_p(x)) { + return mrb_float_value(mrb, mrb_float(x) + mrb_as_float(mrb, y)); + } +#endif +#if defined(MRB_USE_RATIONAL) || defined(MRB_USE_COMPLEX) + switch (mrb_type(x)) { +#if defined(MRB_USE_RATIONAL) + case MRB_TT_RATIONAL: + return mrb_rational_add(mrb, x, y); +#endif +#if defined(MRB_USE_COMPLEX) + case MRB_TT_COMPLEX: + return mrb_complex_add(mrb, x, y); +#endif + default: + break; + } +#endif + mrb_raise(mrb, E_TYPE_ERROR, "no number addition"); + return mrb_nil_value(); /* not reached */ +} + +MRB_API mrb_value +mrb_num_sub(mrb_state *mrb, mrb_value x, mrb_value y) +{ +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_bint_sub(mrb, x, y); + } +#endif + if (mrb_integer_p(x)) { + return mrb_int_sub(mrb, x, y); + } +#ifndef MRB_NO_FLOAT + if (mrb_float_p(x)) { + return mrb_float_value(mrb, mrb_float(x) - mrb_as_float(mrb, y)); + } +#endif +#if defined(MRB_USE_RATIONAL) || defined(MRB_USE_COMPLEX) + switch (mrb_type(x)) { +#if defined(MRB_USE_RATIONAL) + case MRB_TT_RATIONAL: + return mrb_rational_sub(mrb, x, y); +#endif +#if defined(MRB_USE_COMPLEX) + case MRB_TT_COMPLEX: + return mrb_complex_sub(mrb, x, y); +#endif + default: + break; + } +#endif + mrb_raise(mrb, E_TYPE_ERROR, "no number subtraction"); + return mrb_nil_value(); /* not reached */ +} + +MRB_API mrb_value +mrb_num_mul(mrb_state *mrb, mrb_value x, mrb_value y) +{ +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_bint_mul(mrb, x, y); + } +#endif + if (mrb_integer_p(x)) { + return mrb_int_mul(mrb, x, y); + } +#ifndef MRB_NO_FLOAT + if (mrb_float_p(x)) { + return mrb_float_value(mrb, mrb_float(x) * mrb_as_float(mrb, y)); + } +#endif +#if defined(MRB_USE_RATIONAL) || defined(MRB_USE_COMPLEX) + switch (mrb_type(x)) { +#if defined(MRB_USE_RATIONAL) + case MRB_TT_RATIONAL: + return mrb_rational_mul(mrb, x, y); +#endif +#if defined(MRB_USE_COMPLEX) + case MRB_TT_COMPLEX: + return mrb_complex_mul(mrb, x, y); +#endif + default: + break; + } +#endif + mrb_raise(mrb, E_TYPE_ERROR, "no number multiply"); + return mrb_nil_value(); /* not reached */ +} diff --git a/src/object.c b/src/object.c index a42293016..530702173 100644 --- a/src/object.c +++ b/src/object.c @@ -9,6 +9,7 @@ #include #include #include +#include #include MRB_API mrb_bool @@ -496,7 +497,7 @@ mrb_value mrb_complex_to_i(mrb_state *mrb, mrb_value comp); #endif MRB_API mrb_value -mrb_ensure_int_type(mrb_state *mrb, mrb_value val) +mrb_ensure_integer_type(mrb_state *mrb, mrb_value val) { if (!mrb_integer_p(val)) { #ifndef MRB_NO_FLOAT @@ -505,6 +506,10 @@ mrb_ensure_int_type(mrb_state *mrb, mrb_value val) } else { switch (mrb_type(val)) { +#ifdef MRB_USE_BIGINT + case MRB_TT_BIGINT: + return val; +#endif #ifdef MRB_USE_RATIONAL case MRB_TT_RATIONAL: return mrb_rational_to_i(mrb, val); @@ -523,6 +528,18 @@ mrb_ensure_int_type(mrb_state *mrb, mrb_value val) return val; } +MRB_API mrb_value +mrb_ensure_int_type(mrb_state *mrb, mrb_value val) +{ + val = mrb_ensure_integer_type(mrb, val); +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(val)) { + return mrb_int_value(mrb, mrb_bint_as_int(mrb, val)); + } +#endif + return val; +} + #ifndef MRB_NO_FLOAT MRB_API mrb_value mrb_ensure_float_type(mrb_state *mrb, mrb_value val) @@ -547,6 +564,11 @@ mrb_ensure_float_type(mrb_state *mrb, mrb_value val) return mrb_complex_to_f(mrb, val); #endif +#ifdef MRB_USE_BIGINT + case MRB_TT_BIGINT: + return mrb_float_value(mrb, mrb_bint_as_float(mrb, val)); +#endif + default: mrb_raisef(mrb, E_TYPE_ERROR, "%Y cannot be converted to Float", val); /* not reached */ @@ -606,7 +628,11 @@ mrb_check_hash_type(mrb_state *mrb, mrb_value hash) MRB_API mrb_value mrb_inspect(mrb_state *mrb, mrb_value obj) { - return mrb_obj_as_string(mrb, mrb_funcall_id(mrb, obj, MRB_SYM(inspect), 0)); + mrb_value v = mrb_funcall_id(mrb, obj, MRB_SYM(inspect), 0); + if (!mrb_string_p(v)) { + v = mrb_obj_as_string(mrb, obj); + } + return v; } MRB_API mrb_bool diff --git a/src/print.c b/src/print.c index 4af871b43..c6cb6464e 100644 --- a/src/print.c +++ b/src/print.c @@ -49,12 +49,6 @@ mrb_p(mrb_state *mrb, mrb_value obj) } -MRB_API void -mrb_print_error(mrb_state *mrb) -{ - mrb_print_backtrace(mrb); -} - MRB_API void mrb_show_version(mrb_state *mrb) { @@ -78,11 +72,6 @@ mrb_p(mrb_state *mrb, mrb_value obj) { } -MRB_API void -mrb_print_error(mrb_state *mrb) -{ -} - MRB_API void mrb_show_version(mrb_state *mrb) { diff --git a/src/proc.c b/src/proc.c index abace39de..100e04150 100644 --- a/src/proc.c +++ b/src/proc.c @@ -9,9 +9,10 @@ #include #include #include -#include #include #include +#include +#include static const mrb_code call_iseq[] = { OP_CALL, @@ -237,14 +238,20 @@ mrb_proc_s_new(mrb_state *mrb, mrb_value proc_class) return proc; } +static void +check_proc(mrb_state *mrb, mrb_value proc) +{ + if (!mrb_proc_p(proc)) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "not a proc"); + } +} + static mrb_value mrb_proc_init_copy(mrb_state *mrb, mrb_value self) { mrb_value proc = mrb_get_arg1(mrb); - if (!mrb_proc_p(proc)) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "not a proc"); - } + check_proc(mrb, proc); mrb_proc_copy(mrb, mrb_proc_ptr(self), mrb_proc_ptr(proc)); return self; } @@ -275,9 +282,7 @@ proc_lambda(mrb_state *mrb, mrb_value self) if (mrb_nil_p(blk)) { mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block"); } - if (!mrb_proc_p(blk)) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "not a proc"); - } + check_proc(mrb, blk); p = mrb_proc_ptr(blk); if (!MRB_PROC_STRICT_P(p)) { struct RProc *p2 = MRB_OBJ_ALLOC(mrb, MRB_TT_PROC, p->c); diff --git a/src/range.c b/src/range.c index 7507173b6..34ae7e451 100644 --- a/src/range.c +++ b/src/range.c @@ -362,9 +362,13 @@ range_num_to_a(mrb_state *mrb, mrb_value range) mrb_int len; if (mrb_int_sub_overflow(b, a, &len)) { + too_long: mrb_raise(mrb, E_RANGE_ERROR, "integer range too long"); } - if (!RANGE_EXCL(r)) len++; + if (!RANGE_EXCL(r)) { + if (len == MRB_INT_MAX) goto too_long; + len++; + } ary = mrb_ary_new_capa(mrb, len); for (mrb_int i=0; i #include #include +#include void mrb_init_core(mrb_state*); void mrb_init_mrbgems(mrb_state*); @@ -137,6 +138,7 @@ mrb_irep_cutref(mrb_state *mrb, mrb_irep *irep) if (irep->flags & MRB_IREP_NO_FREE) return; reps = (mrb_irep**)irep->reps; + if (!reps) return; for (i=0; irlen; i++) { mrb_irep *tmp = reps[i]; reps[i] = NULL; diff --git a/src/string.c b/src/string.c index 332c4e777..f6f97c7df 100644 --- a/src/string.c +++ b/src/string.c @@ -14,12 +14,13 @@ #include #include #include +#include #include #include typedef struct mrb_shared_string { int refcnt; - mrb_ssize capa; + mrb_int capa; char *ptr; } mrb_shared_string; @@ -29,26 +30,26 @@ const char mrb_digitmap[] = "0123456789abcdefghijklmnopqrstuvwxyz"; static struct RString* str_init_normal_capa(mrb_state *mrb, struct RString *s, - const char *p, size_t len, size_t capa) + const char *p, mrb_int len, mrb_int capa) { char *dst = (char *)mrb_malloc(mrb, capa + 1); if (p) memcpy(dst, p, len); dst[len] = '\0'; s->as.heap.ptr = dst; - s->as.heap.len = (mrb_ssize)len; - s->as.heap.aux.capa = (mrb_ssize)capa; + s->as.heap.len = len; + s->as.heap.aux.capa = capa; RSTR_UNSET_TYPE_FLAG(s); return s; } static struct RString* -str_init_normal(mrb_state *mrb, struct RString *s, const char *p, size_t len) +str_init_normal(mrb_state *mrb, struct RString *s, const char *p, mrb_int len) { return str_init_normal_capa(mrb, s, p, len, len); } static struct RString* -str_init_embed(struct RString *s, const char *p, size_t len) +str_init_embed(struct RString *s, const char *p, mrb_int len) { if (p) memcpy(RSTR_EMBED_PTR(s), p, len); RSTR_EMBED_PTR(s)[len] = '\0'; @@ -58,10 +59,10 @@ str_init_embed(struct RString *s, const char *p, size_t len) } static struct RString* -str_init_nofree(struct RString *s, const char *p, size_t len) +str_init_nofree(struct RString *s, const char *p, mrb_int len) { s->as.heap.ptr = (char *)p; - s->as.heap.len = (mrb_ssize)len; + s->as.heap.len = len; s->as.heap.aux.capa = 0; /* nofree */ RSTR_SET_TYPE_FLAG(s, NOFREE); return s; @@ -97,37 +98,29 @@ str_init_fshared(const struct RString *orig, struct RString *s, struct RString * } static struct RString* -str_init_modifiable(mrb_state *mrb, struct RString *s, const char *p, size_t len) +str_init_modifiable(mrb_state *mrb, struct RString *s, const char *p, mrb_int len) { if (RSTR_EMBEDDABLE_P(len)) { return str_init_embed(s, p, len); } - else { - return str_init_normal(mrb, s, p, len); - } + return str_init_normal(mrb, s, p, len); } static struct RString* -str_new_static(mrb_state *mrb, const char *p, size_t len) +str_new_static(mrb_state *mrb, const char *p, mrb_int len) { if (RSTR_EMBEDDABLE_P(len)) { return str_init_embed(mrb_obj_alloc_string(mrb), p, len); } - if (len >= MRB_SSIZE_MAX) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big"); - } return str_init_nofree(mrb_obj_alloc_string(mrb), p, len); } static struct RString* -str_new(mrb_state *mrb, const char *p, size_t len) +str_new(mrb_state *mrb, const char *p, mrb_int len) { if (RSTR_EMBEDDABLE_P(len)) { return str_init_embed(mrb_obj_alloc_string(mrb), p, len); } - if (len >= MRB_SSIZE_MAX) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big"); - } if (p && mrb_ro_data_p(p)) { return str_init_nofree(mrb_obj_alloc_string(mrb), p, len); } @@ -135,31 +128,22 @@ str_new(mrb_state *mrb, const char *p, size_t len) } MRB_API mrb_value -mrb_str_new_capa(mrb_state *mrb, size_t capa) +mrb_str_new_capa(mrb_state *mrb, mrb_int capa) { - struct RString *s; + struct RString *s = mrb_obj_alloc_string(mrb); if (RSTR_EMBEDDABLE_P(capa)) { - s = str_init_embed(mrb_obj_alloc_string(mrb), NULL, 0); - } - else if (capa >= MRB_SSIZE_MAX) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "string capacity size too big"); - /* not reached */ - s = NULL; + s = str_init_embed(s, NULL, 0); } else { - s = str_init_normal_capa(mrb, mrb_obj_alloc_string(mrb), NULL, 0, capa); + s = str_init_normal_capa(mrb, s, NULL, 0, capa); } - return mrb_obj_value(s); } static void -resize_capa(mrb_state *mrb, struct RString *s, size_t capacity) +resize_capa(mrb_state *mrb, struct RString *s, mrb_int capacity) { -#if SIZE_MAX > MRB_SSIZE_MAX - mrb_assert(capacity < MRB_SSIZE_MAX); -#endif if (RSTR_EMBED_P(s)) { if (!RSTR_EMBEDDABLE_P(capacity)) { str_init_normal_capa(mrb, s, RSTR_EMBED_PTR(s), RSTR_EMBED_LEN(s), capacity); @@ -172,7 +156,7 @@ resize_capa(mrb_state *mrb, struct RString *s, size_t capacity) } MRB_API mrb_value -mrb_str_new(mrb_state *mrb, const char *p, size_t len) +mrb_str_new(mrb_state *mrb, const char *p, mrb_int len) { return mrb_obj_value(str_new(mrb, p, len)); } @@ -181,7 +165,7 @@ MRB_API mrb_value mrb_str_new_cstr(mrb_state *mrb, const char *p) { struct RString *s; - size_t len; + mrb_int len; if (p) { len = strlen(p); @@ -196,7 +180,7 @@ mrb_str_new_cstr(mrb_state *mrb, const char *p) } MRB_API mrb_value -mrb_str_new_static(mrb_state *mrb, const char *p, size_t len) +mrb_str_new_static(mrb_state *mrb, const char *p, mrb_int len) { struct RString *s = str_new_static(mrb, p, len); return mrb_obj_value(s); @@ -225,20 +209,19 @@ str_modify_keep_ascii(mrb_state *mrb, struct RString *s) mrb_free(mrb, shared); } else { - str_init_modifiable(mrb, s, s->as.heap.ptr, (size_t)s->as.heap.len); + str_init_modifiable(mrb, s, s->as.heap.ptr, s->as.heap.len); str_decref(mrb, shared); } } else if (RSTR_NOFREE_P(s) || RSTR_FSHARED_P(s)) { - str_init_modifiable(mrb, s, s->as.heap.ptr, (size_t)s->as.heap.len); + str_init_modifiable(mrb, s, s->as.heap.ptr, s->as.heap.len); } } static void -check_null_byte(mrb_state *mrb, mrb_value str) +check_null_byte(mrb_state *mrb, struct RString *str) { - mrb_ensure_string_type(mrb, str); - if (memchr(RSTRING_PTR(str), '\0', RSTRING_LEN(str))) { + if (memchr(RSTR_PTR(str), '\0', RSTR_LEN(str))) { mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte"); } } @@ -714,21 +697,6 @@ str_rindex(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos) } } -MRB_API mrb_int -mrb_str_strlen(mrb_state *mrb, struct RString *s) -{ - mrb_int i, max = RSTR_LEN(s); - char *p = RSTR_PTR(s); - - if (!p) return 0; - for (i=0; i @@ -833,14 +801,9 @@ mrb_str_to_cstr(mrb_state *mrb, mrb_value str0) struct RString *s; const char *p = RSTRING_PTR(str0); - size_t len = RSTRING_LEN(str0); - check_null_byte(mrb, str0); - if (RSTR_EMBEDDABLE_P(len)) { - s = str_init_embed(mrb_obj_alloc_string(mrb), p, len); - } - else { - s = str_init_normal(mrb, mrb_obj_alloc_string(mrb), p, len); - } + mrb_int len = RSTRING_LEN(str0); + check_null_byte(mrb, RSTRING(str0)); + s = str_init_modifiable(mrb, mrb_obj_alloc_string(mrb), p, len); return RSTR_PTR(s); } @@ -920,7 +883,7 @@ mrb_str_bytesize(mrb_state *mrb, mrb_value self) static mrb_value mrb_str_times(mrb_state *mrb, mrb_value self) { - mrb_int n,len,times; + mrb_int n, len, times; struct RString *str2; char *p; @@ -928,11 +891,9 @@ mrb_str_times(mrb_state *mrb, mrb_value self) if (times < 0) { mrb_raise(mrb, E_ARGUMENT_ERROR, "negative argument"); } - if (times && MRB_SSIZE_MAX / times < RSTRING_LEN(self)) { + if (mrb_int_mul_overflow(RSTRING_LEN(self), times, &len)) { mrb_raise(mrb, E_ARGUMENT_ERROR, "argument too big"); } - - len = RSTRING_LEN(self)*times; str2 = str_new(mrb, 0, len); p = RSTR_PTR(str2); if (len > 0) { @@ -1059,22 +1020,6 @@ mrb_str_equal_m(mrb_state *mrb, mrb_value str1) } /* ---------------------------------- */ -/* obslete: use RSTRING_PTR() */ -MRB_API const char* -mrb_string_value_ptr(mrb_state *mrb, mrb_value str) -{ - str = mrb_obj_as_string(mrb, str); - return RSTRING_PTR(str); -} - -/* obslete: use RSTRING_LEN() */ -MRB_API mrb_int -mrb_string_value_len(mrb_state *mrb, mrb_value ptr) -{ - mrb_ensure_string_type(mrb, ptr); - return RSTRING_LEN(ptr); -} - MRB_API mrb_value mrb_str_dup(mrb_state *mrb, mrb_value str) { @@ -1234,7 +1179,7 @@ str_replace_partial(mrb_state *mrb, mrb_value src, mrb_int pos, mrb_int end, mrb } replen = (mrb_nil_p(rep) ? 0 : RSTRING_LEN(rep)); - if (mrb_int_add_overflow(replen, len - (end - pos), &newlen) || newlen >= MRB_SSIZE_MAX) { + if (mrb_int_add_overflow(replen, len - (end - pos), &newlen)) { mrb_raise(mrb, E_RUNTIME_ERROR, "string size too big"); } @@ -2039,10 +1984,9 @@ mrb_str_rindex(mrb_state *mrb, mrb_value str) { mrb_value sub; mrb_int pos; - int argc = mrb_get_args(mrb, "S|i", &sub, &pos); mrb_int len = RSTRING_CHAR_LEN(str); - if (argc == 1) { + if (mrb_get_args(mrb, "S|i", &sub, &pos) == 1) { pos = len; } else { @@ -2205,11 +2149,24 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str) return result; } +static mrb_bool +trailingbad(const char *str, const char *p, const char *pend) +{ + if (p == str) return TRUE; /* no number */ + if (*(p - 1) == '_') return TRUE; /* trailing '_' */ + while (p= base) { @@ -2347,22 +2307,27 @@ mrb_str_len_to_integer(mrb_state *mrb, const char *str, size_t len, mrb_int base break; } overflow: +#ifdef MRB_USE_BIGINT + ; + const char *p3 = p2; + while (p3 < pend) { + char c = TOLOWER(*p3); + const char *p4 = strchr(mrb_digitmap, c); + if (p4 == NULL && c != '_') break; + if (p4 - mrb_digitmap >= base) break; + p3++; + } + if (badcheck && trailingbad(str, p, pend)) goto bad; + return mrb_bint_new_str(mrb, p2, (mrb_int)(p3-p2), sign ? base : -base); +#else mrb_raisef(mrb, E_RANGE_ERROR, "string (%l) too big for integer", str, pend-str); +#endif } n += c; } val = (mrb_int)n; - if (badcheck) { - if (p == str) goto bad; /* no number */ - if (*(p - 1) == '_') goto bad; /* trailing '_' */ - while (p= MRB_SSIZE_MAX) { + if (mrb_int_add_overflow(RSTR_LEN(s), len, &total)) { size_error: mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big"); } if (capa <= total) { if (capa == 0) capa = 1; while (capa <= total) { - if (capa <= MRB_SSIZE_MAX / 2) { - capa *= 2; - } - else { - capa = total+1; - } - } - if (capa <= total || capa > MRB_SSIZE_MAX) { - goto size_error; + if (mrb_int_mul_overflow(capa, 2, &capa)) goto size_error; } resize_capa(mrb, s, capa); } @@ -2681,7 +2638,6 @@ mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len) ptr = RSTR_PTR(s) + off; } memcpy(RSTR_PTR(s) + RSTR_LEN(s), ptr, len); - mrb_assert_int_fit(size_t, total, mrb_ssize, MRB_SSIZE_MAX); RSTR_SET_LEN(s, total); RSTR_PTR(s)[total] = '\0'; /* sentinel */ return str; diff --git a/src/symbol.c b/src/symbol.c index cc8986eaa..429074532 100644 --- a/src/symbol.c +++ b/src/symbol.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #ifndef MRB_NO_PRESYM @@ -134,10 +135,6 @@ symhash(const char *key, size_t len) return hash & 0xff; } -size_t mrb_packed_int_len(uint32_t num); -size_t mrb_packed_int_encode(uint32_t num, uint8_t *p, uint8_t *pend); -uint32_t mrb_packed_int_decode(uint8_t *p, uint8_t **newpos); - #define sym_lit_p(mrb, i) (mrb->symflags[i>>3]&(1<<(i&7))) #define sym_lit_set(mrb, i) mrb->symflags[i>>3]|=(1<<(i&7)) #define sym_flags_clear(mrb, i) mrb->symflags[i>>3]&=~(1<<(i&7)) @@ -154,7 +151,7 @@ sym_check(mrb_state *mrb, const char *name, size_t len, mrb_sym i) } else { /* length in BER */ - symlen = mrb_packed_int_decode((uint8_t*)symname, (uint8_t**)&symname); + symlen = mrb_packed_int_decode((const uint8_t*)symname, (const uint8_t**)&symname); } if (len == symlen && memcmp(symname, name, len) == 0) { return TRUE; @@ -220,7 +217,7 @@ sym_intern(mrb_state *mrb, const char *name, size_t len, mrb_bool lit) size_t symcapa = mrb->symcapa; if (symcapa == 0) symcapa = 100; else symcapa = (size_t)(symcapa * 6 / 5); - mrb->symtbl = (const char**)mrb_realloc(mrb, mrb->symtbl, sizeof(char*)*symcapa); + mrb->symtbl = (const char**)mrb_realloc(mrb, (void*)mrb->symtbl, sizeof(char*)*symcapa); mrb->symflags = (uint8_t*)mrb_realloc(mrb, mrb->symflags, symcapa/8+1); memset(mrb->symflags+mrb->symcapa/8+1, 0, (symcapa-mrb->symcapa)/8); mrb->symlink = (uint8_t*)mrb_realloc(mrb, mrb->symlink, symcapa); @@ -232,9 +229,10 @@ sym_intern(mrb_state *mrb, const char *name, size_t len, mrb_bool lit) mrb->symtbl[sym] = name; } else { - int ilen = mrb_packed_int_len(len); + uint32_t ulen = (uint32_t)len; + size_t ilen = mrb_packed_int_len(ulen); char *p = (char *)mrb_malloc(mrb, len+ilen+1); - mrb_packed_int_encode(len, (uint8_t*)p, (uint8_t*)p+ilen); + mrb_packed_int_encode(ulen, (uint8_t*)p, (uint8_t*)p+ilen); memcpy(p+ilen, name, len); p[ilen+len] = 0; mrb->symtbl[sym] = p; @@ -347,7 +345,7 @@ sym2name_len(mrb_state *mrb, mrb_sym sym, char *buf, mrb_int *lenp) const char *symname = mrb->symtbl[sym]; if (!sym_lit_p(mrb, sym)) { - size_t len = mrb_packed_int_decode((uint8_t*)symname, (uint8_t**)&symname); + uint32_t len = mrb_packed_int_decode((const uint8_t*)symname, (const uint8_t**)&symname); if (lenp) *lenp = (mrb_int)len; } else if (lenp) { @@ -376,9 +374,9 @@ mrb_free_symtbl(mrb_state *mrb) mrb_free(mrb, (char*)mrb->symtbl[i]); } } - mrb_free(mrb, mrb->symtbl); - mrb_free(mrb, mrb->symlink); - mrb_free(mrb, mrb->symflags); + mrb_free(mrb, (void*)mrb->symtbl); + mrb_free(mrb, (void*)mrb->symlink); + mrb_free(mrb, (void*)mrb->symflags); } void diff --git a/src/variable.c b/src/variable.c index 53b760d0f..365d93034 100644 --- a/src/variable.c +++ b/src/variable.c @@ -10,6 +10,7 @@ #include #include #include +#include #include /* Instance variable table structure */ @@ -485,7 +486,7 @@ mrb_value mrb_obj_iv_inspect(mrb_state *mrb, struct RObject *obj) { iv_tbl *t = obj->iv; - int len = iv_size(mrb, t); + size_t len = iv_size(mrb, t); if (len > 0) { const char *cn = mrb_obj_classname(mrb, mrb_obj_value(obj)); @@ -773,6 +774,7 @@ const_get(mrb_state *mrb, struct RClass *base, mrb_sym sym, mrb_bool skip) mrb_bool retry = FALSE; mrb_value name; + /* if skip then skip the current class (already searched) */ if (skip) c = c->super; L_RETRY: while (c) { @@ -781,6 +783,7 @@ L_RETRY: return v; } c = c->super; + if (!skip && c == mrb->object_class) break; } if (!retry && base->tt == MRB_TT_MODULE) { c = mrb->object_class; @@ -985,7 +988,7 @@ mrb_f_global_variables(mrb_state *mrb, mrb_value self) } static mrb_bool -mrb_const_defined_0(mrb_state *mrb, mrb_value mod, mrb_sym id, mrb_bool exclude, mrb_bool recurse) +const_defined_0(mrb_state *mrb, mrb_value mod, mrb_sym id, mrb_bool exclude, mrb_bool recurse) { struct RClass *klass = mrb_class_ptr(mod); struct RClass *tmp; @@ -1011,13 +1014,13 @@ retry: MRB_API mrb_bool mrb_const_defined(mrb_state *mrb, mrb_value mod, mrb_sym id) { - return mrb_const_defined_0(mrb, mod, id, TRUE, TRUE); + return const_defined_0(mrb, mod, id, TRUE, TRUE); } MRB_API mrb_bool mrb_const_defined_at(mrb_state *mrb, mrb_value mod, mrb_sym id) { - return mrb_const_defined_0(mrb, mod, id, TRUE, FALSE); + return const_defined_0(mrb, mod, id, TRUE, FALSE); } MRB_API mrb_value diff --git a/src/vm.c b/src/vm.c index 3501abf57..b04c9d7e5 100644 --- a/src/vm.c +++ b/src/vm.c @@ -19,6 +19,7 @@ #include "value_array.h" #include #include +#include #include #ifdef MRB_NO_STDIO @@ -201,6 +202,21 @@ mrb_stack_extend(mrb_state *mrb, mrb_int room) } } +static void +mrb_stack_extend_adjust(mrb_state *mrb, mrb_int room, const mrb_value **argp) +{ + const struct mrb_context *c = mrb->c; + ptrdiff_t voff = *argp - c->stbase; + + if (voff < 0 || voff >= c->stend - c->stbase) { + mrb_stack_extend(mrb, room); + } + else { + mrb_stack_extend(mrb, room); + *argp = c->stbase + voff; + } +} + static inline struct REnv* uvenv(mrb_state *mrb, mrb_int up) { @@ -245,7 +261,7 @@ top_proc(mrb_state *mrb, const struct RProc *proc) static inline mrb_callinfo* cipush(mrb_state *mrb, mrb_int push_stacks, uint8_t cci, - struct RClass *target_class, const struct RProc *proc, mrb_sym mid, uint8_t argc) + struct RClass *target_class, const struct RProc *proc, mrb_sym mid, uint16_t argc) { struct mrb_context *c = mrb->c; mrb_callinfo *ci = c->ci; @@ -422,7 +438,7 @@ mrb_ci_nregs(mrb_callinfo *ci) const struct RProc *p; if (!ci) return 4; - uint8_t nregs = mrb_ci_bidx(ci) + 1; /* self + args + kargs + blk */ + mrb_int nregs = mrb_ci_bidx(ci) + 1; /* self + args + kargs + blk */ p = ci->proc; if (p && !MRB_PROC_CFUNC_P(p) && p->body.irep && p->body.irep->nregs > nregs) { return p->body.irep->nregs; @@ -471,7 +487,7 @@ prepare_missing(mrb_state *mrb, mrb_value recv, mrb_sym mid, struct RClass **cls argv[1] = argv[n]; argv[2] = blk; } - *c = 15 | (nk<<4); + *c = 15 | (uint16_t)(nk<<4); mrb_ary_unshift(mrb, args, mrb_symbol_value(mid)); return m; } @@ -507,7 +523,6 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc struct RClass *c; mrb_callinfo *ci = mrb->c->ci; mrb_int n = mrb_ci_nregs(ci); - ptrdiff_t voff = -1; if (!mrb->c->stbase) { stack_init(mrb); @@ -515,26 +530,29 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc if (ci - mrb->c->cibase > MRB_CALL_LEVEL_MAX) { mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); } - if (mrb->c->stbase <= argv && argv < mrb->c->stend) { - voff = argv - mrb->c->stbase; - } if (argc < 0) { mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (%i)", argc); } c = mrb_class(mrb, self); m = mrb_method_search_vm(mrb, &c, mid); - mrb_stack_extend(mrb, n + argc + 3); + mrb_stack_extend_adjust(mrb, n + argc + 3, &argv); if (argc >= 15) { ci->stack[n+1] = mrb_ary_new_from_values(mrb, argc, argv); + ci->stack[n+2] = blk; argc = 15; } + else { + if (argc > 0) + stack_copy(ci->stack+n+1, argv, argc); + ci->stack[n+argc+1] = blk; + } if (MRB_METHOD_UNDEF_P(m)) { uint16_t ac = (uint16_t)argc; - m = prepare_missing(mrb, self, mid, &c, n, &ac, mrb_nil_value(), 0); + m = prepare_missing(mrb, self, mid, &c, (uint32_t)n, &ac, mrb_nil_value(), 0); argc = (mrb_int)ac; mid = MRB_SYM(method_missing); } - ci = cipush(mrb, n, 0, c, NULL, mid, argc); + ci = cipush(mrb, n, 0, c, NULL, mid, (uint16_t)argc); if (MRB_METHOD_PROC_P(m)) { struct RProc *p = MRB_METHOD_PROC(m); @@ -543,18 +561,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc mrb_stack_extend(mrb, p->body.irep->nregs + argc); } } - if (voff >= 0) { - argv = mrb->c->stbase + voff; - } ci->stack[0] = self; - if (argc < 15) { - if (argc > 0) - stack_copy(ci->stack+1, argv, argc); - ci->stack[argc+1] = blk; - } - else { - ci->stack[2] = blk; - } if (MRB_METHOD_CFUNC_P(m)) { ci->cci = CINFO_DIRECT; @@ -580,7 +587,7 @@ mrb_funcall_argv(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc, cons static void check_method_noarg(mrb_state *mrb, const mrb_callinfo *ci) { - int argc = ci->n == CALL_MAXARGS ? RARRAY_LEN(ci->stack[1]) : ci->n; + mrb_int argc = ci->n == CALL_MAXARGS ? RARRAY_LEN(ci->stack[1]) : ci->n; if (ci->nk > 0) { mrb_value kdict = ci->stack[mrb_ci_kidx(ci)]; if (!(mrb_hash_p(kdict) && mrb_hash_empty_p(mrb, kdict))) { @@ -596,7 +603,7 @@ static mrb_value exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p) { mrb_callinfo *ci = mrb->c->ci; - int keep, nregs; + mrb_int keep, nregs; ci->stack[0] = self; mrb_vm_ci_proc_set(ci, p); @@ -639,7 +646,7 @@ mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p) cipop(mrb); } else { - int keep = mrb_ci_bidx(ci) + 1; /* receiver + block */ + mrb_int keep = mrb_ci_bidx(ci) + 1; /* receiver + block */ ret = mrb_top_run(mrb, p, self, keep); } if (mrb->exc && mrb->jmp) { @@ -736,6 +743,17 @@ mrb_f_send(mrb_state *mrb, mrb_value self) return exec_irep(mrb, self, MRB_METHOD_PROC(m)); } +static void +check_block(mrb_state *mrb, mrb_value blk) +{ + if (mrb_nil_p(blk)) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); + } + if (!mrb_proc_p(blk)) { + mrb_raise(mrb, E_TYPE_ERROR, "not a block"); + } +} + static mrb_value eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c) { @@ -743,9 +761,7 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c) mrb_callinfo *ci; int nregs; - if (mrb_nil_p(blk)) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); - } + check_block(mrb, blk); ci = mrb->c->ci; if (ci->cci == CINFO_DIRECT) { return mrb_yield_with_class(mrb, blk, 1, &self, self, c); @@ -836,9 +852,7 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value mrb_value val; mrb_int n; - if (mrb_nil_p(b)) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); - } + check_block(mrb, b); ci = mrb->c->ci; n = mrb_ci_nregs(ci); p = mrb_proc_ptr(b); @@ -849,10 +863,10 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value n = 3; } else { - ci->n = argc; + ci->n = (uint8_t)argc; n = argc + 2; } - mrb_stack_extend(mrb, n); + mrb_stack_extend_adjust(mrb, n, &argv); mrb->c->ci->stack[0] = self; if (ci->n == 15) { mrb->c->ci->stack[1] = mrb_ary_new_from_values(mrb, argc, argv); @@ -896,17 +910,11 @@ mrb_yield_cont(mrb_state *mrb, mrb_value b, mrb_value self, mrb_int argc, const struct RProc *p; mrb_callinfo *ci; - if (mrb_nil_p(b)) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); - } - if (!mrb_proc_p(b)) { - mrb_raise(mrb, E_TYPE_ERROR, "not a block"); - } - + check_block(mrb, b); p = mrb_proc_ptr(b); ci = mrb->c->ci; - mrb_stack_extend(mrb, 4); + mrb_stack_extend_adjust(mrb, 4, &argv); mrb->c->ci->stack[1] = mrb_ary_new_from_values(mrb, argc, argv); mrb->c->ci->stack[2] = mrb_nil_value(); mrb->c->ci->stack[3] = mrb_nil_value(); @@ -1162,8 +1170,37 @@ hash_new_from_values(mrb_state *mrb, mrb_int argc, mrb_value *regs) return hash; } -void mrb_method_added(mrb_state *mrb, struct RClass *c, mrb_sym mid); -mrb_value mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value idx, mrb_value len); +#define ARGUMENT_NORMALIZE(arg_base, arg_info, insn) do { \ + int n = *(arg_info)&0xf; \ + int nk = (*(arg_info)>>4)&0xf; \ + mrb_int bidx = (arg_base) + mrb_bidx(*(arg_info)); \ + if (nk == CALL_MAXARGS) { \ + mrb_ensure_hash_type(mrb, regs[(arg_base)+(n==CALL_MAXARGS?1:n)+1]); \ + } \ + else if (nk > 0) { /* pack keyword arguments */ \ + mrb_int kidx = (arg_base)+(n==CALL_MAXARGS?1:n)+1; \ + mrb_value kdict = hash_new_from_values(mrb, nk, regs+kidx); \ + regs[kidx] = kdict; \ + nk = CALL_MAXARGS; \ + *(arg_info) = n | (nk<<4); \ + } \ + \ + mrb_assert(bidx < irep->nregs+(arg_base)); \ + mrb_int new_bidx = (arg_base)+mrb_bidx(*(arg_info)); \ + if ((insn) == OP_SEND) { \ + /* clear block argument */ \ + SET_NIL_VALUE(regs[new_bidx]); \ + SET_NIL_VALUE(blk); \ + } \ + else { \ + blk = regs[bidx]; \ + if (!mrb_nil_p(blk) && !mrb_proc_p(blk)) { \ + blk = mrb_type_convert(mrb, blk, MRB_TT_PROC, MRB_SYM(to_proc)); \ + /* The stack might have been reallocated during mrb_type_convert(), see #3622 */ \ + } \ + regs[new_bidx] = blk; \ + } \ +} while (0) MRB_API mrb_value mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) @@ -1236,7 +1273,15 @@ RETRY_TRY_BLOCK: goto L_INT_OVERFLOW; #endif case IREP_TT_BIGINT: +#ifdef MRB_USE_BIGINT + { + const char *s = pool[b].u.str; + regs[a] = mrb_bint_new_str(mrb, s+2, (mrb_int)s[0], (mrb_int)s[1]); + } + break; +#else goto L_INT_OVERFLOW; +#endif #ifndef MRB_NO_FLOAT case IREP_TT_FLOAT: regs[a] = mrb_float_value(mrb, pool[b].u.f); @@ -1575,39 +1620,12 @@ RETRY_TRY_BLOCK: mid = syms[b]; L_SENDB_SYM: { - int n = c&0xf; - int nk = (c>>4)&0xf; mrb_callinfo *ci = mrb->c->ci; - mrb_int bidx = a + mrb_bidx(c); mrb_method_t m; struct RClass *cls; - mrb_value recv; + mrb_value recv, blk; - if (0 < nk && nk < 15) { /* pack keyword arguments */ - mrb_int kidx = a+(n==15?1:n)+1; - mrb_value kdict = hash_new_from_values(mrb, nk, regs+kidx); - regs[kidx] = kdict; - nk = 15; - c = n | (nk<<4); - } - - mrb_assert(bidx < irep->nregs+a); - mrb_value blk; - mrb_int new_bidx = a+mrb_bidx(c); - if (insn == OP_SEND) { - /* clear block argument */ - SET_NIL_VALUE(regs[new_bidx]); - SET_NIL_VALUE(blk); - } - else { - blk = regs[bidx]; - if (!mrb_nil_p(blk) && !mrb_proc_p(blk)) { - blk = mrb_type_convert(mrb, blk, MRB_TT_PROC, MRB_SYM(to_proc)); - /* The stack might have been reallocated during mrb_type_convert(), - see #3622 */ - } - regs[new_bidx] = blk; - } + ARGUMENT_NORMALIZE(a, &c, insn); recv = regs[a]; cls = mrb_class(mrb, recv); @@ -1724,29 +1742,14 @@ RETRY_TRY_BLOCK: mrb_method_t m; struct RClass *cls; mrb_callinfo *ci = mrb->c->ci; - mrb_int bidx = mrb_bidx(b)+a; mrb_value recv, blk; const struct RProc *p = ci->proc; mrb_sym mid = ci->mid; - struct RClass* target_class = MRB_PROC_TARGET_CLASS(p); + struct RClass* target_class = mrb_vm_ci_target_class(ci); if (MRB_PROC_ENV_P(p) && p->e.env->mid && p->e.env->mid != mid) { /* alias support */ mid = p->e.env->mid; /* restore old mid */ } - mrb_assert(bidx < irep->nregs); - - blk = regs[bidx]; - uint8_t nk = (b >> 4) & 0x0f; - if (nk > 0 && nk < CALL_MAXARGS) { /* pack keyword arguments */ - uint8_t n = b & 0x0f; - mrb_int kidx = a+(n==15?1:n)+1; - mrb_value kdict = hash_new_from_values(mrb, nk, regs+kidx); - regs[kidx] = kdict; - nk = 15; - b = n | (nk<<4); - bidx = kidx + 1; - regs[bidx] = blk; - } if (mid == 0 || !target_class) { mrb_value exc = mrb_exc_new_lit(mrb, E_NOMETHOD_ERROR, "super called outside of method"); @@ -1754,10 +1757,7 @@ RETRY_TRY_BLOCK: goto L_RAISE; } if ((target_class->flags & MRB_FL_CLASS_IS_PREPENDED) || target_class->tt == MRB_TT_MODULE) { - target_class = mrb_vm_ci_target_class(ci); - if (!target_class || target_class->tt != MRB_TT_ICLASS) { - goto super_typeerror; - } + goto super_typeerror; } recv = regs[0]; if (!mrb_obj_is_kind_of(mrb, recv, target_class)) { @@ -1767,13 +1767,9 @@ RETRY_TRY_BLOCK: mrb_exc_set(mrb, exc); goto L_RAISE; } - if (!mrb_nil_p(blk) && !mrb_proc_p(blk)) { - blk = mrb_type_convert(mrb, blk, MRB_TT_PROC, MRB_SYM(to_proc)); - /* The stack or ci stack might have been reallocated during - mrb_type_convert(), see #3622 and #3784 */ - regs[bidx] = blk; - ci = mrb->c->ci; - } + + ARGUMENT_NORMALIZE(a, &b, OP_SUPER); + cls = target_class->super; m = mrb_method_search_vm(mrb, &cls, mid); if (MRB_METHOD_UNDEF_P(m)) { @@ -2016,7 +2012,7 @@ RETRY_TRY_BLOCK: } /* format arguments for generated code */ - mrb->c->ci->n = len; + mrb->c->ci->n = (uint8_t)len; /* clear local (but non-argument) variables */ if (irep->nlocals-blk_pos-1 > 0) { @@ -2280,9 +2276,9 @@ RETRY_TRY_BLOCK: } if (ci->cci > CINFO_NONE) { ci = cipop(mrb); + mrb->exc = (struct RObject*)break_new(mrb, RBREAK_TAG_BREAK, proc, v); mrb_gc_arena_restore(mrb, ai); mrb->c->vmexec = FALSE; - mrb->exc = (struct RObject*)break_new(mrb, RBREAK_TAG_BREAK, proc, v); mrb->jmp = prev_jmp; MRB_THROW(prev_jmp); } @@ -2388,12 +2384,14 @@ RETRY_TRY_BLOCK: NEXT; } +#if !defined(MRB_USE_BIGINT) || defined(MRB_INT32) L_INT_OVERFLOW: { mrb_value exc = mrb_exc_new_lit(mrb, E_RANGE_ERROR, "integer overflow"); mrb_exc_set(mrb, exc); } goto L_RAISE; +#endif #define TYPES2(a,b) ((((uint16_t)(a))<<8)|(((uint16_t)(b))&0xff)) #define OP_MATH(op_name) \ @@ -2413,8 +2411,9 @@ RETRY_TRY_BLOCK: case TYPES2(MRB_TT_INTEGER, MRB_TT_INTEGER): \ { \ mrb_int x = mrb_integer(regs[a]), y = mrb_integer(regs[a+1]), z; \ - if (mrb_int_##op_name##_overflow(x, y, &z)) \ - OP_MATH_OVERFLOW_INT(); \ + if (mrb_int_##op_name##_overflow(x, y, &z)) { \ + OP_MATH_OVERFLOW_INT(op_name,x,y); \ + } \ else \ SET_INT_VALUE(mrb,regs[a], z); \ } \ @@ -2430,7 +2429,11 @@ RETRY_TRY_BLOCK: } \ break #endif -#define OP_MATH_OVERFLOW_INT() goto L_INT_OVERFLOW +#ifdef MRB_USE_BIGINT +#define OP_MATH_OVERFLOW_INT(op,x,y) regs[a] = mrb_bint_##op##_ii(mrb,x,y) +#else +#define OP_MATH_OVERFLOW_INT(op,x,y) goto L_INT_OVERFLOW +#endif #define OP_MATH_CASE_STRING_add() \ case TYPES2(MRB_TT_STRING, MRB_TT_STRING): \ regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]); \ @@ -2512,8 +2515,9 @@ RETRY_TRY_BLOCK: case MRB_TT_INTEGER: \ { \ mrb_int x = mrb_integer(regs[a]), y = (mrb_int)b, z; \ - if (mrb_int_##op_name##_overflow(x, y, &z)) \ - OP_MATH_OVERFLOW_INT(); \ + if (mrb_int_##op_name##_overflow(x, y, &z)) { \ + OP_MATH_OVERFLOW_INT(op_name,x,y); \ + } \ else \ SET_INT_VALUE(mrb,regs[a], z); \ } \ @@ -2636,7 +2640,7 @@ RETRY_TRY_BLOCK: regs[a] = splat; } else { - mrb_assert(mrb_type(regs[a]) == MRB_TT_ARRAY); + mrb_assert(mrb_array_p(regs[a])); mrb_ary_concat(mrb, regs[a], splat); } mrb_gc_arena_restore(mrb, ai); @@ -2644,7 +2648,7 @@ RETRY_TRY_BLOCK: } CASE(OP_ARYPUSH, BB) { - mrb_assert(mrb_type(regs[a]) == MRB_TT_ARRAY); + mrb_assert(mrb_array_p(regs[a])); for (mrb_int i=0; i> 2; @@ -2760,6 +2764,7 @@ RETRY_TRY_BLOCK: } CASE(OP_STRCAT, B) { + mrb_assert(mrb_string_p(regs[a])); mrb_str_concat(mrb, regs[a], regs[a+1]); NEXT; } @@ -2793,7 +2798,7 @@ RETRY_TRY_BLOCK: CASE(OP_HASHCAT, B) { mrb_value hash = regs[a]; - mrb_ensure_hash_type(mrb, hash); + mrb_assert(mrb_hash_p(hash)); mrb_hash_merge(mrb, hash, regs[a+1]); mrb_gc_arena_restore(mrb, ai); NEXT; diff --git a/tasks/benchmark.rake b/tasks/benchmark.rake index 12e0d4602..b32d165bf 100644 --- a/tasks/benchmark.rake +++ b/tasks/benchmark.rake @@ -9,11 +9,8 @@ def bm_files end def build_config_name - if !ENV['MRUBY_CONFIG'].to_s.empty? - File.basename(ENV['MRUBY_CONFIG'], '.rb').gsub('build_config_', '') - else - "bm" - end + path = MRuby::Build.mruby_config_path + File.basename(path, '.rb').gsub('build_config_', '') end def plot_file @@ -21,6 +18,8 @@ def plot_file end def plot + raise "no build target to benchmark against" if $dat_files.empty? + opts_file = "#{MRUBY_ROOT}/benchmark/plot.gpl" opts = File.read(opts_file).each_line.to_a.map(&:strip).join(';') @@ -46,11 +45,13 @@ def plot p.puts "e" end end + + puts "Benchmark results output to #{plot_file}" end MRuby.each_target do |target| - next if target.name == 'host' || target.internal? + next if !target.benchmark_enabled? || target.internal? mruby_bin = "#{target.build_dir}/bin/mruby" bm_files.each do |bm_file| diff --git a/test/t/array.rb b/test/t/array.rb index 5f26259f2..eccb435ef 100644 --- a/test/t/array.rb +++ b/test/t/array.rb @@ -32,6 +32,8 @@ assert('Array#*', '15.2.12.5.2') do end assert_equal([1, 1, 1], [1].*(3)) assert_equal([], [1].*(0)) + assert_equal('abc', ['a', 'b', 'c'].*('')) + assert_equal('0, 0, 1, {:foo=>0}', [0, [0, 1], {foo: 0}].*(', ')) end assert('Array#<<', '15.2.12.5.3') do diff --git a/test/t/integer.rb b/test/t/integer.rb index d4076f38a..5a5098b92 100644 --- a/test/t/integer.rb +++ b/test/t/integer.rb @@ -40,15 +40,26 @@ assert('Integer#/', '15.2.8.3.4') do assert_equal 2, a a = 5/2 assert_equal 2, a + b = -1/2 + assert_equal(-1, b) + b = 1/-2 + assert_equal(-1, b) skip unless Object.const_defined?(:Float) b = 2/1.0 assert_equal 2.0, b end -assert('Integer#quo') do - a = 6.quo(5) - assert_equal 1.2, a -end if Object.const_defined?(:Float) +if Object.const_defined?(:Rational) + assert('Integer#quo') do + a = 6.quo(5) + assert_equal 5/6r, a + end +elsif Object.const_defined?(:Float) + assert('Integer#quo') do + a = 6.quo(5) + assert_equal 1.2, a + end +end assert('Integer#%', '15.2.8.3.5') do a = 1%1