diff --git a/mrbgems/ngx_mruby_mrblib/mrblib/mrb_nginx.rb b/mrbgems/ngx_mruby_mrblib/mrblib/mrb_nginx.rb index 3ee0f4a4..c0f8156a 100644 --- a/mrbgems/ngx_mruby_mrblib/mrblib/mrb_nginx.rb +++ b/mrbgems/ngx_mruby_mrblib/mrblib/mrb_nginx.rb @@ -1,7 +1,7 @@ class Nginx class Request def scheme - self.var.scheme + var.scheme end def document_root @@ -14,32 +14,33 @@ def read_body end def body - self.get_body + get_body end def uri_args - args_to_hash(self.args) + args_to_hash(args) end def uri_args=(params) raise ArgumentError unless params.is_a?(Hash) - self.args = params.map{|k,v| "#{k}=#{v}"}.join("&") + + self.args = params.map { |k, v| "#{k}=#{v}" }.join('&') end def post_args - args_to_hash(self.body) + args_to_hash(body) end private def args_to_hash(args) - Hash[*args.split("&").map{|arg| arg.split("=", 2)}.flatten] + Hash[*args.split('&').map { |arg| arg.split('=', 2) }.flatten] end end class Headers_in def user_agent - self["User-Agent"] + self['User-Agent'] end end @@ -50,32 +51,32 @@ def self.var class Utils class << self def encode_parameters(params, delimiter = '&', quote = nil) - if params.is_a?(Hash) - params = params.map do |key, value| - sprintf("%s=%s%s%s", escape(key), quote, escape(value), quote) - end - else - params = params.map { |value| escape(value) } - end + params = if params.is_a?(Hash) + params.map do |key, value| + format('%s=%s%s%s', escape(key), quote, escape(value), quote) + end + else + params.map { |value| escape(value) } + end delimiter ? params.join(delimiter) : params end def escape(str) reserved_str = [ - "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "n", "m", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", - "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", - "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", - "-", ".", "_", "~" + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'm', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '-', '.', '_', '~' ] tmp = '' str = str.to_s str.size.times do |idx| chr = str[idx] - if reserved_str.include?(chr) - tmp += chr - else - tmp += "%" + chr.unpack("H*").first.upcase - end + tmp += if reserved_str.include?(chr) + chr + else + '%' + chr.unpack1('H*').upcase + end end tmp end @@ -122,7 +123,6 @@ class Response end end - module Kernel def get_server_class Nginx @@ -132,10 +132,8 @@ def _ngx_mrb_prepare_fiber(nginx_handler) fiber_handler = Fiber.new { nginx_handler.call } lambda do - GC.disable # BUG?: return nginx_handler directly from fiber, not proc in any case. result = fiber_handler.resume - GC.enable [fiber_handler.alive?, result] end end diff --git a/mruby/.dockerignore b/mruby/.dockerignore new file mode 100644 index 00000000..627d921e --- /dev/null +++ b/mruby/.dockerignore @@ -0,0 +1,14 @@ +.DS_Store +.idea +.vscode +*.bak +*.iml +*.ipr +*.swp +*.tmp + +/.yardoc +/bin +/build +/doc/api +/doc/capi diff --git a/mruby/.editorconfig b/mruby/.editorconfig index f966739f..a5145bad 100644 --- a/mruby/.editorconfig +++ b/mruby/.editorconfig @@ -8,37 +8,27 @@ root = true [*] charset = utf-8 end_of_line = lf -indent_size = 8 -indent_style = tab +indent_size = 2 +indent_style = space insert_final_newline = true tab_width = 8 +trim_trailing_whitespace = true [{Makefile,Makefile.*,makefile,*.mk}] -trim_trailing_whitespace = true +indent_style = tab #max_line_length = 80 -[*.{c,cc,C,cxx,cpp,h,hh,H,hxx,hpp,inc,y}] -indent_size = 2 -indent_style = space -trim_trailing_whitespace = true +#[*.{c,cc,C,cxx,cpp,h,hh,H,hxx,hpp,inc,y}] #max_line_length = 120 -[{*.rb,Rakefile,rakefile,*.rake,*.gemspec,*.gembox}] -indent_size = 2 -indent_style = space -trim_trailing_whitespace = true +#[{*.rb,Rakefile,rakefile,*.rake,*.gemspec,*.gembox}] #max_line_length = 120 # limitation to US-ASCII [*.bat] end_of_line = crlf -indent_style = space #max_line_length = 80 -[*.{yaml,yml}] -indent_size = 2 -indent_style = space +#[*.{yaml,yml}] -[*.md] -indent_size = 2 -indent_style = space +#[*.md] diff --git a/mruby/.gitattributes b/mruby/.gitattributes new file mode 100644 index 00000000..0f776312 --- /dev/null +++ b/mruby/.gitattributes @@ -0,0 +1,4 @@ +* text=auto eol=lf +*.bat text eol=crlf +*.cmd text eol=crlf +*.png binary diff --git a/mruby/.github/dependabot.yml b/mruby/.github/dependabot.yml index dac4cac3..ff902ec0 100644 --- a/mruby/.github/dependabot.yml +++ b/mruby/.github/dependabot.yml @@ -1,8 +1,11 @@ # Basic set up - version: 2 updates: - + # Maintain dependencies for Ruby + - package-ecosystem: "bundler" + directory: "/" + schedule: + interval: "daily" # Maintain dependencies for GitHub Actions - package-ecosystem: "github-actions" directory: "/" diff --git a/mruby/.github/labeler.yml b/mruby/.github/labeler.yml new file mode 100644 index 00000000..b4f73b78 --- /dev/null +++ b/mruby/.github/labeler.yml @@ -0,0 +1,29 @@ +benchmark: + - benchmark/**/* +build: + - Makefile + - Rakefile + - build_config/**/* + - lib/**/* + - tasks/**/* +core: + - include/**/* + - mrblib/**/* + - src/**/* + - test/**/* +doc: + - CONTRIBUTING.md + - LEGAL + - LICENSE + - NEWS + - README.md + - SECURITY.md + - TODO.md + - doc/**/* + - examples/**/* +github: + - .github/**/* +mrbgems: + - mrbgems/**/* +oss-fuzz: + - oss-fuzz/**/* diff --git a/mruby/.github/linters/.markdown-lint.yml b/mruby/.github/linters/.markdown-lint.yml index 5c6cbec4..f6c3cdd2 100644 --- a/mruby/.github/linters/.markdown-lint.yml +++ b/mruby/.github/linters/.markdown-lint.yml @@ -19,5 +19,11 @@ MD025: false # MD026 no-trailing-punctuation - Trailing punctuation in heading MD026: false +# MD033/no-inline-html - Inline HTML +MD033: false + # MD040 fenced-code-language - Fenced code blocks should have a language specified MD040: false + +# MD041 first-line-heading/first-line-h1 - First line in a file should be a top-level heading +MD041: false diff --git a/mruby/.github/workflows/build.yml b/mruby/.github/workflows/build.yml index ec82c0de..c0a7024e 100644 --- a/mruby/.github/workflows/build.yml +++ b/mruby/.github/workflows/build.yml @@ -27,7 +27,8 @@ jobs: CXX: ${{ matrix.cxx }} LD: ${{ matrix.cc }} steps: - - uses: actions/checkout@v3 + - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" + uses: actions/checkout@v4 - name: Ruby version run: ruby -v - name: Compiler version @@ -41,7 +42,8 @@ jobs: env: MRUBY_CONFIG: ci/msvc steps: - - uses: actions/checkout@v3 + - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" + uses: actions/checkout@v4 - name: Ruby version run: ruby -v - name: Build and test diff --git a/mruby/.github/workflows/codeql-analysis.yml b/mruby/.github/workflows/codeql-analysis.yml deleted file mode 100644 index 10117d54..00000000 --- a/mruby/.github/workflows/codeql-analysis.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: Code scanning - action - -on: - push: - branches-ignore: - - dependabot/** - pull_request: - schedule: - - cron: '0 19 * * 4' - -permissions: - contents: read - -jobs: - CodeQL-Build: - permissions: - actions: read # for github/codeql-action/init to get workflow details - contents: read # for actions/checkout to fetch code - security-events: write # for github/codeql-action/autobuild to send a status report - runs-on: ubuntu-latest - steps: - - name: Checkout repository - 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. - fetch-depth: 2 - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - # Override language selection by uncommenting this and choosing your languages - # with: - # languages: go, javascript, csharp, python, cpp, java - - # 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@v2 - - # ℹ️ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl - - # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language - - # - run: | - # make bootstrap - # make release - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 diff --git a/mruby/.github/workflows/labeler.yml b/mruby/.github/workflows/labeler.yml new file mode 100644 index 00000000..f85abb12 --- /dev/null +++ b/mruby/.github/workflows/labeler.yml @@ -0,0 +1,15 @@ +# https://github.com/actions/labeler +name: Pull Request Labeler +on: + - pull_request_target +jobs: + triage: + permissions: + contents: read + pull-requests: write + runs-on: ubuntu-latest + steps: + - uses: actions/labeler@v4 + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" + sync-labels: true diff --git a/mruby/.github/workflows/lint.yml b/mruby/.github/workflows/lint.yml index c31b7411..b95005f2 100644 --- a/mruby/.github/workflows/lint.yml +++ b/mruby/.github/workflows/lint.yml @@ -1,3 +1,4 @@ +# https://pre-commit.com/ name: Lint on: [pull_request] @@ -6,22 +7,12 @@ permissions: contents: read jobs: - misspell: - name: Check spelling with misspell - runs-on: ubuntu-latest - steps: - - name: Check Out - uses: actions/checkout@v3 - - name: Install - run: wget -O - -q https://git.io/misspell | sh -s -- -b . - - name: Run misspell - run: git ls-files --empty-directory | xargs ./misspell -error pre-commit: name: Run pre-commit runs-on: ubuntu-latest steps: - - name: Check Out - uses: actions/checkout@v3 + - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" + uses: actions/checkout@v4 - name: Install run: | python -m pip install --upgrade pip diff --git a/mruby/.github/workflows/oss-fuzz.yml b/mruby/.github/workflows/oss-fuzz.yml index 414c750e..72d40cf9 100644 --- a/mruby/.github/workflows/oss-fuzz.yml +++ b/mruby/.github/workflows/oss-fuzz.yml @@ -1,3 +1,4 @@ +# https://github.com/google/oss-fuzz name: CIFuzz on: [pull_request] permissions: diff --git a/mruby/.github/workflows/super-linter.yml b/mruby/.github/workflows/super-linter.yml index 538ccf07..fd577722 100644 --- a/mruby/.github/workflows/super-linter.yml +++ b/mruby/.github/workflows/super-linter.yml @@ -1,3 +1,4 @@ +# https://github.com/super-linter/super-linter name: Super-Linter on: [pull_request] @@ -13,13 +14,13 @@ jobs: name: Lint Code Base runs-on: ubuntu-latest steps: - - name: Checkout Code - uses: actions/checkout@v3 + - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" + uses: actions/checkout@v4 with: # Full git history is needed to get a proper list of changed files within `super-linter` fetch-depth: 0 - name: Lint Code Base - uses: github/super-linter/slim@v4.10.1 + uses: super-linter/super-linter/slim@v5.3.1 env: ERROR_ON_MISSING_EXEC_BIT: true VALIDATE_BASH: true diff --git a/mruby/.gitignore b/mruby/.gitignore index 6a0e7e46..eb5b5ddf 100644 --- a/mruby/.gitignore +++ b/mruby/.gitignore @@ -1,8 +1,8 @@ -*.lock *.bak *.bc *.d *.i +*.lock *.o *.orig *.pdb @@ -13,25 +13,23 @@ *.tmp *~ .DS_Store +.ccls* .ccmalloc .svn .vscode .yardoc -.ccls* -compile_flags.txt -compile_commands.json -cscope.files -cscope.out -tags - /.git -/bin -/build -/mruby-source-*.gem - /benchmark/**/*.dat /benchmark/*.pdf /benchmark/*.png - +/bin +/build /doc/api /doc/capi +/mruby-source-*.gem +compile_commands.json +compile_flags.txt +cscope.files +cscope.out +tags +!Gemfile.lock diff --git a/mruby/.pre-commit-config.yaml b/mruby/.pre-commit-config.yaml index 4c7bc52e..48e353b7 100644 --- a/mruby/.pre-commit-config.yaml +++ b/mruby/.pre-commit-config.yaml @@ -23,12 +23,14 @@ repos: - id: detect-private-key - id: end-of-file-fixer - id: file-contents-sorter + args: [--unique] files: ^codespell\.txt$ - id: fix-byte-order-marker + - id: forbid-submodules - id: mixed-line-ending - id: trailing-whitespace - repo: https://github.com/Lucas-C/pre-commit-hooks - rev: v1.3.1 + rev: v1.5.1 hooks: - id: forbid-tabs exclude: Makefile$|Makefile\..+$|makefile$|\.mk$ @@ -36,7 +38,7 @@ repos: args: [--whitespaces-count, '2'] exclude: Makefile$|Makefile\..+$|makefile$|\.mk$ - repo: https://github.com/codespell-project/codespell - rev: v2.2.2 + rev: v2.2.5 hooks: - id: codespell name: Run codespell @@ -49,7 +51,7 @@ repos: name: Local policy is to exclude extension from all shell files types: [shell] - repo: https://github.com/igorshubovych/markdownlint-cli - rev: v0.33.0 + rev: v0.35.0 hooks: - id: markdownlint name: Run markdownlint @@ -57,8 +59,17 @@ repos: entry: markdownlint -c .github/linters/.markdown-lint.yml . types: [markdown] files: \.(md|mdown|markdown)$ + - repo: https://github.com/tcort/markdown-link-check + rev: v3.11.2 + hooks: + - id: markdown-link-check + name: Run markdown-link-check + description: Checks hyperlinks in Markdown files + args: [-q] + types: [markdown] + files: \.(md|mdown|markdown)$ - repo: https://github.com/adrienverge/yamllint - rev: v1.28.0 + rev: v1.32.0 hooks: - id: yamllint name: Run yamllint diff --git a/mruby/AUTHORS b/mruby/AUTHORS index fce97efc..6483ddc5 100644 --- a/mruby/AUTHORS +++ b/mruby/AUTHORS @@ -1,10 +1,10 @@ # Authors of mruby (mruby developers) -## The List of Contributors sorted by number of commits (as of 2022-01-08 4462e3d) +## The List of Contributors sorted by number of commits (as of 2023-08-26 b85b682) - 8860 Yukihiro "Matz" Matsumoto (@matz)* + 9287 Yukihiro "Matz" Matsumoto (@matz)* 586 KOBAYASHI Shuji (@shuujii) - 441 dearblue (@dearblue)* + 494 dearblue (@dearblue)* 378 Daniel Bovensiepen (@bovi)* 346 Takeshi Watanabe (@take-cheeze)* 334 Masaki Muranaka (@monaka) @@ -12,15 +12,15 @@ 234 Jun Hiroe (@suzukaze) 220 Cremno (@cremno)* 209 Yuki Kurihara (@ksss)+ + 159 John Bampton (@jbampton) 151 Yasuhiro Matsumoto (@mattn)* 113 Carson McDonald (@carsonmcdonald) - 113 John Bampton (@jbampton) 103 Tomasz Dąbrowski (@dabroz)* 84 Akira Yumiyama (@akiray03)* 84 skandhas (@skandhas) + 81 Hiroshi Mimaki (@mimaki)* 80 Masamitsu MURASE (@masamitsu-murase) 74 Yuichiro MASUI (@masuidrive) - 73 Hiroshi Mimaki (@mimaki)* 71 Tatsuhiko Kubo (@cubicdaiya)* 65 Yuichiro Kaneko (@yui-knk)+ 64 Paolo Bosetti (@pbosetti)* @@ -63,6 +63,7 @@ 12 Kouki Ooyatsu (kaishuu0123)* 12 NAKAMURA Usaku (@unak)* 12 RIZAL Reckordp (@Reckordp)+ + 12 Ray Chason (@chasonr)* 12 Takashi Sawanaka (@sdottaka)* 12 Ukrainskiy Sergey (@ukrainskiysergey) 12 Xuejie "Rafael" Xiao (@xxuejie)* @@ -73,7 +74,6 @@ 11 takkaw (@takkaw) 10 Miura Hideki (@miura1729) 10 Narihiro Nakamura (@authorNari) - 10 Ray Chason (@chasonr)* 10 Yuichi Nishiwaki (@nyuichi) 9 Akira Mitsui (@murasesyuka)* 9 Frank Celler (@fceller) @@ -96,6 +96,7 @@ 6 Kenji Okimoto (@okkez)+ 6 Selman ULUG (@selman) 6 Yusuke Endoh (@mame)* + 6 masahino (@masahino) 5 Chris Reuter (@suetanvil) 5 Davide D'Agostino (@DAddYE) 5 Eric Hodel (@drbrain) @@ -109,7 +110,6 @@ 5 TOMITA Masahiro (@tmtm) 5 Yurie Yamane (@yurie)+ 5 dreamedge (@dreamedge) - 5 masahino (@masahino) 5 nkshigeru (@nkshigeru) 5 xuejianqing (@joans321) 4 Dante Catalfamo (@dantecatalfamo) @@ -137,10 +137,12 @@ 3 Jan Berdajs (@mrbrdo) 3 Jonas Minnberg (@sasq64) 3 Joseph McCullough (@joequery) + 3 Lanza (@LanzaSchneider) 3 Mark McCurry (@fundamental) 3 Nobuhiro Iwamatsu (@iwamatsu) 3 Per Lundberg (@perlun)* 3 Rob Fors (@robfors)* + 3 Robert Rowe (@CaptainJet) 3 Sebastián Katzer (@katzer)* 3 Shouji Kuboyama (@Shokuji)* 3 Shuta Kimura (@kimushu)+ @@ -173,7 +175,6 @@ 2 Kazuhiko Yamashita (@pyama86)+ 2 Kazuhiro Sera (@seratch) 2 Kuroda Daisuke (@dycoon)+ - 2 Lanza (@LanzaSchneider) 2 Lothar Scholz (@llothar) 2 Lukas Joeressen (@kext) 2 Masahiro Wakame (@vvkame)+ @@ -196,11 +197,13 @@ 1 A-Sat (@asatou)+ 1 Abinoam Praxedes Marques Junior (@abinoam) 1 Alex Wang (@nanamiwang)+ + 1 AlexDenisov (@AlexDenisov) 1 Andrew Nordman (@cadwallion) 1 Ashish Kurmi (@boahc077) 1 Atsushi Morimoto (@mynz) 1 Ben A Morgan (@BenMorganIO) 1 Benoit Daloze (@eregon) + 1 Colin MacKenzie IV (@sinisterchipmunk) 1 Daehyub Kim (@lateau) 1 Daniel Varga (@vargad) 1 Edgar Boda-Majer (@eboda) @@ -257,7 +260,6 @@ 1 Prayag Verma (@pra85) 1 Ranmocy (@ranmocy) 1 Robert McNally (@wolfmcnally) - 1 Robert Rowe (@CaptainJet) 1 Ryan Scott Lewis (@RyanScottLewis) 1 Ryo Okubo (@syucream) 1 SAkira a.k.a. Akira Suzuki (@sakisakira) @@ -285,6 +287,7 @@ 1 Yurii Nakonechnyi (@inobelar) 1 Yusuke Suzuki (@Constellation)+ 1 Yusuke Tanaka (@csouls) + 1 alpha.netzilla (@alpha-netzilla) 1 arton (@arton) 1 duangsuse (@duangsuse) 1 fl0l0u (@fl0l0u) diff --git a/mruby/CONTRIBUTING.md b/mruby/CONTRIBUTING.md index 61d67312..a797b137 100644 --- a/mruby/CONTRIBUTING.md +++ b/mruby/CONTRIBUTING.md @@ -26,8 +26,8 @@ A framework for managing and maintaining multi-language `pre-commit` hooks. You need to first install `pre-commit` and then install the `pre-commit` hooks with `pre-commit install`. Now `pre-commit` will run automatically on git commit! -It's usually a good idea to run the hooks against all the files when adding new hooks (usually `pre-commit` will only run on the changed files during git hooks). -Use `pre-commit run --all-files` to check all files. +It's usually a good idea to run the hooks against all the files when adding new hooks (usually `pre-commit` +will only run on the changed files during git hooks). Use `pre-commit run --all-files` to check all files. To run a single hook use `pre-commit run --all-files ` @@ -37,12 +37,16 @@ Sometimes you might need to skip one or more hooks which can be done with the `S `$ SKIP=yamllint git commit -m "foo"` -For convenience, we have added `pre-commit run --all-files` and `pre-commit autoupdate` +For convenience, we have added `pre-commit run --all-files`, `pre-commit install` and `pre-commit autoupdate` to both the Makefile and the Rakefile. Run them with: - `make check` or `rake check` +- `make checkinstall` or `rake checkinstall` - `make checkupdate` or `rake checkupdate` +To configure `pre-commit` you can modify the config file [.pre-commit-config.yaml](.pre-commit-config.yaml). +We use [GitHub Actions](.github/workflows/lint.yml) to run `pre-commit` on every pull request. + ### pre-commit quick links - [Quick start](https://pre-commit.com/#quick-start) @@ -50,21 +54,73 @@ to both the Makefile and the Rakefile. Run them with: - [pre-commit autoupdate](https://pre-commit.com/#pre-commit-autoupdate) - [Temporarily disabling hooks](https://pre-commit.com/#temporarily-disabling-hooks) -## Spell Checking +## Docker + +We have both a `Dockerfile` and `docker-compose.yml` files in the repository root. +You can run these with the command line or use +[Docker Desktop](https://www.docker.com/products/docker-desktop/). + +The Docker image is running Debian bullseye with Ruby and Python installed. +You can build the Docker image with: + +`$ docker-compose build test` + +So far we just have one service: `test`. Running the default `docker-compose` +command will create the Docker image, spin up a container and then build and +run all mruby tests. -We are running [misspell](https://github.com/client9/misspell) which is mainly written in -[Golang](https://golang.org/) to check spelling with [GitHub Actions](.github/workflows/lint.yml). -Correct commonly misspelled English words quickly with `misspell`. You can run `misspell` locally -against all files with: +The default `docker-compose` command is: -```bash -find . -type f | xargs ./misspell -error +`$ docker-compose -p mruby run test` + +You can also use Make or Rake to run the default `docker-compose` +command from above: + +- `make composetest` +- `rake composetest` + +List your Docker images with: + +```console +$ docker images +REPOSITORY TAG IMAGE ID CREATED SIZE +mruby-test latest ec60f9536948 29 seconds ago 1.29GB ``` -Notable `misspell` help options or flags are: +You can also run any custom `docker-compose` command which will override +the default. For example to run `pre-commit run --all-files` type: + +`$ docker-compose -p mruby run test pre-commit run --all-files` + +For convenience, you can also run `pre-commit` with: + +- `make composecheck` +- `rake composecheck` + +The bonus of running `pre-commit` with `docker-compose` is that you won't need +to install `pre-commit` and the hooks on your local machine. And that also +means you won't need to install `brew`, `conda` or `pip`. + +Note limitation: currently running `pre-commit` with `docker-compose` we +skip the `check-executables-have-shebangs` hook. + +Two more examples of custom `docker-compose` commands are: + +- `$ docker-compose -p mruby run test ls` +- `$ docker-compose -p mruby run test rake doc:api` + +If you want to test using a different `docker-compose` YAML config file you +can use the `-f` flag: + +`$ docker-compose -p mruby -f docker-compose.test.yml run test` + +- +- + +## Spell Checking -- `-i` string: ignore the following corrections, comma separated -- `-w`: Overwrite file with corrections (default is just to display) +We are using `pre-commit` to run [codespell](https://github.com/codespell-project/codespell) +to check code for common misspellings. We have a small custom dictionary file [codespell.txt](codespell.txt). ## Coding conventions @@ -120,7 +176,7 @@ unless there's a clear reason, e.g. the latest Ruby has changed behavior from IS ### mruby API - [YARD](https://yardoc.org/) - YARD is a documentation generation tool for the Ruby programming language -- [yard-mruby](https://rubygems.org/gems/yard-mruby) - Document MRuby sources with YARD +- [yard-mruby](https://rubygems.org/gems/yard-mruby) - Document mruby sources with YARD - [yard-coderay](https://rubygems.org/gems/yard-coderay) - Adds coderay syntax highlighting to YARD docs ### C API diff --git a/mruby/Dockerfile b/mruby/Dockerfile new file mode 100644 index 00000000..f6699562 --- /dev/null +++ b/mruby/Dockerfile @@ -0,0 +1,17 @@ +FROM ruby:3.2.2-bullseye + +RUN apt-get update && apt-get install --no-install-recommends -y python3-pip shellcheck \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /app + +COPY Gemfile . + +COPY Gemfile.lock . + +COPY .pre-commit-config.yaml . + +RUN bundle install && pip3 install pre-commit && git init . && pre-commit install-hooks + +COPY . . diff --git a/mruby/Doxyfile b/mruby/Doxyfile index ece327c8..3a66c141 100644 --- a/mruby/Doxyfile +++ b/mruby/Doxyfile @@ -1,82 +1,97 @@ -# Doxyfile 1.8.13 +# Doxyfile 1.9.6 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). +# +# Note: +# +# Use doxygen to compare the used configuration file with the template +# configuration file: +# doxygen -x [configFile] +# Use doxygen to compare the used configuration file with the template +# configuration file without replacing the environment variables or CMake type +# replacement variables: +# doxygen -x_noenv [configFile] #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- -DOXYFILE_ENCODING = UTF-8 -PROJECT_NAME = "mruby" -PROJECT_NUMBER = 3.1.0 - -PROJECT_BRIEF = "mruby is the lightweight implementation of the Ruby language" - -PROJECT_LOGO = doc/mruby_logo_red_icon.png - -OUTPUT_DIRECTORY = doc/capi +# This tag specifies the encoding used for all characters in the configuration +# file that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. +# The default value is: UTF-8. -USE_MDFILE_AS_MAINPAGE = README.md +DOXYFILE_ENCODING = UTF-8 -INPUT = CONTRIBUTING.md \ - README.md \ - SECURITY.md \ - TODO.md \ - src \ - include \ - include/mruby \ - mrblib \ - doc \ - doc/guides \ - doc/internal \ - LEGAL \ - LICENSE \ - NEWS +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. -# Red for Ruby -HTML_COLORSTYLE_HUE = 359 +PROJECT_NAME = mruby -# The following expansions -ENABLE_PREPROCESSING = YES -MACRO_EXPANSION = YES -EXPAND_ONLY_PREDEF = NO -PREDEFINED = -EXPAND_AS_DEFINED = -SKIP_FUNCTION_MACROS = NO +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. -# This tells doxygen to search the places that make sense -SEARCH_INCLUDES = YES -INCLUDE_PATH = include include/mruby -INCLUDE_FILE_PATTERNS = *.h +PROJECT_NUMBER = 3.2.0 -CLANG_ASSISTED_PARSING = NO -CLANG_OPTIONS = -I./include +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. -# This thing creates documentation elements for everything, even when its not documented. Its a little ugly to do it right now because huge swathes of code aren't documented. -EXTRACT_ALL = NO +PROJECT_BRIEF = "mruby is the lightweight implementation of the Ruby language" -# Document MRB_INLINE functions -EXTRACT_STATIC = YES +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. -JAVADOC_AUTOBRIEF = YES -QT_AUTOBRIEF = NO +PROJECT_LOGO = doc/mruby_logo_red_icon.png -QUIET = YES -WARN_IF_UNDOCUMENTED = NO +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. -#=========================================================================== -# BELOW THIS LINE IS CRUFT GENERATED BY doxygen -g -# If you edit anything below this, bring it up here so its easier to read. -#=========================================================================== +OUTPUT_DIRECTORY = doc/capi -# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- -# directories (in 2 levels) under the output directory of each output format and -# will distribute the generated files over these directories. Enabling this +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096 +# sub-directories (in 2 levels) under the output directory of each output format +# and will distribute the generated files over these directories. Enabling this # option can be useful when feeding doxygen a huge amount of source files, where # putting all generated files in the same directory would otherwise causes -# performance problems for the file system. +# performance problems for the file system. Adapt CREATE_SUBDIRS_LEVEL to +# control the number of sub-directories. # The default value is: NO. CREATE_SUBDIRS = NO +# Controls the number of sub-directories that will be created when +# CREATE_SUBDIRS tag is set to YES. Level 0 represents 16 directories, and every +# level increment doubles the number of directories, resulting in 4096 +# directories at level 8 which is the default and also the maximum value. The +# sub-directories are organized in 2 levels, the first level always has a fixed +# number of 16 directories. +# Minimum value: 0, maximum value: 8, default value: 8. +# This tag requires that the tag CREATE_SUBDIRS is set to YES. + +CREATE_SUBDIRS_LEVEL = 8 + # If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII # characters to appear in the names of generated files. If set to NO, non-ASCII # characters will be escaped, for example _xE3_x81_x84 will be used for Unicode @@ -88,14 +103,14 @@ ALLOW_UNICODE_NAMES = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. -# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, -# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), -# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, -# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), -# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, -# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, -# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, -# Ukrainian and Vietnamese. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Bulgarian, +# Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, English +# (United States), Esperanto, Farsi (Persian), Finnish, French, German, Greek, +# Hindi, Hungarian, Indonesian, Italian, Japanese, Japanese-en (Japanese with +# English messages), Korean, Korean-en (Korean with English messages), Latvian, +# Lithuanian, Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, +# Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, +# Swedish, Turkish, Ukrainian and Vietnamese. # The default value is: English. OUTPUT_LANGUAGE = English @@ -187,6 +202,32 @@ STRIP_FROM_INC_PATH = SHORT_NAMES = NO +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = YES + +# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line +# such as +# /*************** +# as being the beginning of a Javadoc-style comment "banner". If set to NO, the +# Javadoc-style will behave just like regular comments and it will not be +# interpreted by doxygen. +# The default value is: NO. + +JAVADOC_BANNER = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a # multi-line C++ special comment block (i.e. a block of //! or /// comments) as @@ -200,6 +241,14 @@ SHORT_NAMES = NO MULTILINE_CPP_IS_BRIEF = NO +# By default Python docstrings are displayed as preformatted text and doxygen's +# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the +# doxygen's special commands can be used and the contents of the docstring +# documentation blocks is shown as doxygen documentation. +# The default value is: YES. + +PYTHON_DOCSTRING = YES + # If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the # documentation from any documented member that it re-implements. # The default value is: YES. @@ -223,20 +272,19 @@ TAB_SIZE = 4 # the documentation. An alias has the form: # name=value # For example adding -# "sideeffect=@par Side Effects:\n" +# "sideeffect=@par Side Effects:^^" # will allow you to put the command \sideeffect (or @sideeffect) in the # documentation, which will result in a user-defined paragraph with heading -# "Side Effects:". You can put \n's in the value part of an alias to insert -# newlines. +# "Side Effects:". Note that you cannot put \n's in the value part of an alias +# to insert newlines (in the resulting output). You can put ^^ in the value part +# of an alias to insert a newline as if a physical newline was in the original +# file. When you need a literal { or } or , in the value part of an alias you +# have to escape them by means of a backslash (\), this can lead to conflicts +# with the commands \{ and \} for these it is advised to use the version @{ and +# @} or use a double escape (\\{ and \\}) ALIASES = -# This tag can be used to specify a number of word-keyword mappings (TCL only). -# A mapping has the form "name=value". For example adding "class=itcl::class" -# will allow you to use the command class in the itcl::class meaning. - -TCL_SUBST = - # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. For # instance, some of the names that are used will be different. The list of all @@ -265,28 +313,40 @@ OPTIMIZE_FOR_FORTRAN = NO OPTIMIZE_OUTPUT_VHDL = NO +# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice +# sources only. Doxygen will then generate output that is more tailored for that +# language. For instance, namespaces will be presented as modules, types will be +# separated into more groups, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_SLICE = NO + # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and -# language is one of the parsers supported by doxygen: IDL, Java, Javascript, -# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: -# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: -# Fortran. In the later case the parser tries to guess whether the code is fixed -# or free formatted code, this is the default for Fortran type files), VHDL. For -# instance to make doxygen treat .inc files as Fortran files (default is PHP), -# and .f files as C (default is Fortran), use: inc=Fortran f=C. +# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, +# Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice, +# VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: +# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser +# tries to guess whether the code is fixed or free formatted code, this is the +# default for Fortran type files). For instance to make doxygen treat .inc files +# as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. # # Note: For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise -# the files are not read by doxygen. +# the files are not read by doxygen. When specifying no_extension you should add +# * to the FILE_PATTERNS. +# +# Note see also the list of default file extension mappings. EXTENSION_MAPPING = no_extension=md # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable -# documentation. See http://daringfireball.net/projects/markdown/ for details. +# documentation. See https://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you can # mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in # case of backward compatibilities issues. @@ -298,7 +358,7 @@ MARKDOWN_SUPPORT = YES # to that level are automatically included in the table of contents, even if # they do not have an id attribute. # Note: This feature currently applies only to Markdown headings. -# Minimum value: 0, maximum value: 99, default value: 0. +# Minimum value: 0, maximum value: 99, default value: 5. # This tag requires that the tag MARKDOWN_SUPPORT is set to YES. TOC_INCLUDE_HEADINGS = 0 @@ -328,7 +388,7 @@ BUILTIN_STL_SUPPORT = NO CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip (see: -# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen +# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen # will parse them like normal C++ but will assume all classes use public instead # of private inheritance when no explicit protection keyword is present. # The default value is: NO. @@ -414,6 +474,19 @@ TYPEDEF_HIDES_STRUCT = NO LOOKUP_CACHE_SIZE = 0 +# The NUM_PROC_THREADS specifies the number of threads doxygen is allowed to use +# during processing. When set to 0 doxygen will based this on the number of +# cores available in the system. You can set it explicitly to a value larger +# than 0 to get more control over the balance between CPU load and processing +# speed. At this moment only the input processing can be done using multiple +# threads. Since this is still an experimental feature the default is set to 1, +# which effectively disables parallel processing. Please report any issues you +# encounter. Generating dot graphs in parallel is controlled by the +# DOT_NUM_THREADS setting. +# Minimum value: 0, maximum value: 32, default value: 1. + +NUM_PROC_THREADS = 1 + #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- @@ -426,6 +499,7 @@ LOOKUP_CACHE_SIZE = 0 # normally produced when WARNINGS is set to YES. # The default value is: NO. +EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will # be included in the documentation. @@ -433,6 +507,12 @@ LOOKUP_CACHE_SIZE = 0 EXTRACT_PRIVATE = NO +# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual +# methods of a class will be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIV_VIRTUAL = NO + # If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # scope will be included in the documentation. # The default value is: NO. @@ -443,6 +523,7 @@ EXTRACT_PACKAGE = NO # included in the documentation. # The default value is: NO. +EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined # locally in source files will be included in the documentation. If set to NO, @@ -469,6 +550,13 @@ EXTRACT_LOCAL_METHODS = NO EXTRACT_ANON_NSPACES = NO +# If this flag is set to YES, the name of an unnamed parameter in a declaration +# will be determined by the corresponding definition. By default unnamed +# parameters remain unnamed in the output. +# The default value is: YES. + +RESOLVE_UNNAMED_PARAMS = YES + # If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all # undocumented members inside documented classes or files. If set to NO these # members will be included in the various overviews, but no documentation @@ -480,14 +568,15 @@ HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set # to NO, these classes will be included in the various overviews. This option -# has no effect if EXTRACT_ALL is enabled. +# will also hide undocumented C++ concepts if enabled. This option has no effect +# if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend -# (class|struct|union) declarations. If set to NO, these declarations will be -# included in the documentation. +# declarations. If set to NO, these declarations will be included in the +# documentation. # The default value is: NO. HIDE_FRIEND_COMPOUNDS = NO @@ -506,12 +595,20 @@ HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = NO -# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file -# names in lower-case letters. If set to YES, upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. -# The default value is: system dependent. +# With the correct setting of option CASE_SENSE_NAMES doxygen will better be +# able to match the capabilities of the underlying filesystem. In case the +# filesystem is case sensitive (i.e. it supports files in the same directory +# whose names only differ in casing), the option must be set to YES to properly +# deal with such files in case they appear in the input. For filesystems that +# are not case sensitive the option should be set to NO to properly deal with +# output files written for symbols that only differ in casing, such as for two +# classes, one named CLASS and the other named Class, and to also support +# references to files without having to specify the exact matching casing. On +# Windows (including Cygwin) and MacOS, users should typically set this option +# to NO, whereas on Linux or other Unix flavors it should typically be set to +# YES. +# Possible values are: SYSTEM, NO and YES. +# The default value is: SYSTEM. CASE_SENSE_NAMES = YES @@ -529,6 +626,12 @@ HIDE_SCOPE_NAMES = NO HIDE_COMPOUND_REFERENCE= NO +# If the SHOW_HEADERFILE tag is set to YES then the documentation for a class +# will show which file needs to be included to use the class. +# The default value is: YES. + +SHOW_HEADERFILE = YES + # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. @@ -686,7 +789,8 @@ FILE_VERSION_FILTER = # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. You can # optionally specify a file name after the option, if omitted DoxygenLayout.xml -# will be used as the name of the layout file. +# will be used as the name of the layout file. See also section "Changing the +# layout of pages" for information. # # Note that if you run doxygen from a directory containing a file called # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE @@ -697,7 +801,7 @@ LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files containing # the reference definitions. This must be a list of .bib files. The .bib # extension is automatically appended if omitted. This requires the bibtex tool -# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. # For LaTeX the style of the bibliography can be controlled using # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the # search path. See also \cite for info how to create references. @@ -708,6 +812,12 @@ CITE_BIB_FILES = # Configuration options related to warning and progress messages #--------------------------------------------------------------------------- +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = YES # The WARNINGS tag can be used to turn on/off the warning messages that are # generated to standard error (stderr) by doxygen. If WARNINGS is set to YES @@ -718,25 +828,51 @@ CITE_BIB_FILES = WARNINGS = YES +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = NO # If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some parameters -# in a documented function, or documenting parameters that don't exist or using -# markup commands wrongly. +# potential errors in the documentation, such as documenting some parameters in +# a documented function twice, or documenting parameters that don't exist or +# using markup commands wrongly. # The default value is: YES. WARN_IF_DOC_ERROR = YES +# If WARN_IF_INCOMPLETE_DOC is set to YES, doxygen will warn about incomplete +# function parameter documentation. If set to NO, doxygen will accept that some +# parameters have no documentation without warning. +# The default value is: YES. + +WARN_IF_INCOMPLETE_DOC = YES + # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return -# value. If set to NO, doxygen will only warn about wrong or incomplete -# parameter documentation, but not about the absence of documentation. +# value. If set to NO, doxygen will only warn about wrong parameter +# documentation, but not about the absence of documentation. If EXTRACT_ALL is +# set to YES then this flag will automatically be disabled. See also +# WARN_IF_INCOMPLETE_DOC # The default value is: NO. WARN_NO_PARAMDOC = NO +# If WARN_IF_UNDOC_ENUM_VAL option is set to YES, doxygen will warn about +# undocumented enumeration values. If set to NO, doxygen will accept +# undocumented enumeration values. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: NO. + +WARN_IF_UNDOC_ENUM_VAL = NO + # If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when -# a warning is encountered. +# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS +# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but +# at the end of the doxygen process doxygen will return with a non-zero status. +# Possible values are: NO, YES and FAIL_ON_WARNINGS. # The default value is: NO. WARN_AS_ERROR = NO @@ -747,13 +883,27 @@ WARN_AS_ERROR = NO # and the warning text. Optionally the format may contain $version, which will # be replaced by the version of the file (if it could be obtained via # FILE_VERSION_FILTER) +# See also: WARN_LINE_FORMAT # The default value is: $file:$line: $text. WARN_FORMAT = "$file:$line: $text" +# In the $text part of the WARN_FORMAT command it is possible that a reference +# to a more specific place is given. To make it easier to jump to this place +# (outside of doxygen) the user can define a custom "cut" / "paste" string. +# Example: +# WARN_LINE_FORMAT = "'vi $file +$line'" +# See also: WARN_FORMAT +# The default value is: at line $line of file $file. + +WARN_LINE_FORMAT = "at line $line of file $file" + # The WARN_LOGFILE tag can be used to specify a file to which warning and error # messages should be written. If left blank the output is written to standard -# error (stderr). +# error (stderr). In case the file specified cannot be opened for writing the +# warning and error messages are written to standard error. When as file - is +# specified the warning and error messages are written to standard output +# (stdout). WARN_LOGFILE = @@ -767,16 +917,41 @@ WARN_LOGFILE = # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. +INPUT = CONTRIBUTING.md \ + README.md \ + SECURITY.md \ + TODO.md \ + src \ + include \ + include/mruby \ + mrblib \ + doc \ + doc/guides \ + doc/internal \ + LEGAL \ + LICENSE \ + NEWS # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # libiconv (or the iconv built into libc) for the transcoding. See the libiconv -# documentation (see: http://www.gnu.org/software/libiconv) for the list of -# possible encodings. +# documentation (see: +# https://www.gnu.org/software/libiconv/) for the list of possible encodings. +# See also: INPUT_FILE_ENCODING # The default value is: UTF-8. INPUT_ENCODING = UTF-8 +# This tag can be used to specify the character encoding of the source files +# that doxygen parses The INPUT_FILE_ENCODING tag can be used to specify +# character encoding on a per file pattern basis. Doxygen will compare the file +# name with each pattern and apply the encoding instead of the default +# INPUT_ENCODING) if there is a match. The character encodings are a list of the +# form: pattern=encoding (like *.php=ISO-8859-1). See cfg_input_encoding +# "INPUT_ENCODING" for further information on supported encodings. + +INPUT_FILE_ENCODING = + # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and # *.h) to filter out the source-files in the directories. @@ -785,11 +960,15 @@ INPUT_ENCODING = UTF-8 # need to set EXTENSION_MAPPING for the extension otherwise the files are not # read by doxygen. # +# Note the list of default checked file patterns might differ from the list of +# default file extension mappings. +# # If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, # *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, -# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, -# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, -# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf. +# *.hh, *.hxx, *.hpp, *.h++, *.l, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, +# *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C +# comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, +# *.vhdl, *.ucf, *.qsf and *.ice. FILE_PATTERNS = *.c \ *.cc \ @@ -871,7 +1050,7 @@ EXCLUDE_PATTERNS = # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test +# ANamespace::AClass, ANamespace::*Test # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories use the pattern */test/* @@ -919,6 +1098,11 @@ IMAGE_PATH = # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. # +# Note that doxygen will use the data processed and written to standard output +# for further processing, therefore nothing else, like debug statements or used +# commands (so in case of a Windows batch file always use @echo OFF), should be +# written to standard output. +# # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # properly processed by doxygen. @@ -953,6 +1137,22 @@ FILTER_SOURCE_FILES = NO FILTER_SOURCE_PATTERNS = +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = README.md + +# The Fortran standard specifies that for fixed formatted Fortran code all +# characters from position 72 are to be considered as comment. A common +# extension is to allow longer lines before the automatic comment starts. The +# setting FORTRAN_COMMENT_AFTER will also make it possible that longer lines can +# be processed before the automatic comment starts. +# Minimum value: 7, maximum value: 10000, default value: 72. + +FORTRAN_COMMENT_AFTER = 72 + #--------------------------------------------------------------------------- # Configuration options related to source browsing #--------------------------------------------------------------------------- @@ -980,7 +1180,7 @@ INLINE_SOURCES = NO STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES then for each documented -# function all documented functions referencing it will be listed. +# entity all documented functions referencing it will be listed. # The default value is: NO. REFERENCED_BY_RELATION = NO @@ -1012,12 +1212,12 @@ SOURCE_TOOLTIPS = YES # If the USE_HTAGS tag is set to YES then the references to source code will # point to the HTML generated by the htags(1) tool instead of doxygen built-in # source browser. The htags tool is part of GNU's global source tagging system -# (see http://www.gnu.org/software/global/global.html). You will need version +# (see https://www.gnu.org/software/global/global.html). You will need version # 4.8.6 or higher. # # To use it do the following: # - Install the latest version of global -# - Enable SOURCE_BROWSER and USE_HTAGS in the config file +# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file # - Make sure the INPUT points to the root of the source tree # - Run doxygen as normal # @@ -1039,23 +1239,6 @@ USE_HTAGS = NO VERBATIM_HEADERS = YES -# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the -# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the -# cost of reduced performance. This can be particularly helpful with template -# rich C++ code for which doxygen's built-in parser lacks the necessary type -# information. -# Note: The availability of this option depends on whether or not doxygen was -# generated with the -Duse-libclang=ON option for CMake. -# The default value is: NO. - - -# If clang assisted parsing is enabled you can provide the compiler with command -# line options that you would normally use when invoking the compiler. Note that -# the include paths will already be set by doxygen for the files and directories -# specified with INPUT and INCLUDE_PATH. -# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. - - #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- @@ -1067,17 +1250,11 @@ VERBATIM_HEADERS = YES ALPHABETICAL_INDEX = YES -# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in -# which the alphabetical index list will be split. -# Minimum value: 1, maximum value: 20, default value: 5. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all classes will -# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag -# can be used to specify a prefix (or a list of prefixes) that should be ignored -# while generating the index headers. +# The IGNORE_PREFIX tag can be used to specify a prefix (or a list of prefixes) +# that should be ignored while generating the index headers. The IGNORE_PREFIX +# tag works for classes, function and member names. The entity will be placed in +# the alphabetical list under the first letter of the entity name that remains +# after removing the prefix. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. IGNORE_PREFIX = @@ -1156,7 +1333,12 @@ HTML_STYLESHEET = # Doxygen will copy the style sheet files to the output directory. # Note: The order of the extra style sheet files is of importance (e.g. the last # style sheet in the list overrules the setting of the previous ones in the -# list). For an example see the documentation. +# list). +# Note: Since the styling of scrollbars can currently not be overruled in +# Webkit/Chromium, the styling will be left out of the default doxygen.css if +# one or more extra stylesheets have been specified. So if scrollbar +# customization is desired it has to be added explicitly. For an example see the +# documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_STYLESHEET = @@ -1171,8 +1353,32 @@ HTML_EXTRA_STYLESHEET = HTML_EXTRA_FILES = +# The HTML_COLORSTYLE tag can be used to specify if the generated HTML output +# should be rendered with a dark or light theme. +# Possible values are: LIGHT always generate light mode output, DARK always +# generate dark mode output, AUTO_LIGHT automatically set the mode according to +# the user preference, use light mode if no preference is set (the default), +# AUTO_DARK automatically set the mode according to the user preference, use +# dark mode if no preference is set and TOGGLE allow to user to switch between +# light and dark mode via a button. +# The default value is: AUTO_LIGHT. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE = AUTO_LIGHT + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a color-wheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 359 + # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors -# in the HTML output. For a value of 0 the output will use grayscales only. A +# in the HTML output. For a value of 0 the output will use gray-scales only. A # value of 255 will produce the most vivid colors. # Minimum value: 0, maximum value: 255, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. @@ -1199,6 +1405,17 @@ HTML_COLORSTYLE_GAMMA = 80 HTML_TIMESTAMP = NO +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via JavaScript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have JavaScript, +# like the Qt help browser. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_MENUS = YES + # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. @@ -1222,13 +1439,14 @@ HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files will be # generated that can be used as input for Apple's Xcode 3 integrated development -# environment (see: http://developer.apple.com/tools/xcode/), introduced with -# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a -# Makefile in the HTML output directory. Running make will produce the docset in -# that directory and running make install will install the docset in +# environment (see: +# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To +# create a documentation set, doxygen will generate a Makefile in the HTML +# output directory. Running make will produce the docset in that directory and +# running make install will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at -# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. +# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy +# genXcode/_index.html for more information. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. @@ -1242,6 +1460,13 @@ GENERATE_DOCSET = NO DOCSET_FEEDNAME = "Doxygen generated docs" +# This tag determines the URL of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDURL = + # This tag specifies a string that should uniquely identify the documentation # set bundle. This should be a reverse domain-name style string, e.g. # com.mycompany.MyDocSet. Doxygen will append .docset to the name. @@ -1267,8 +1492,12 @@ DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three # additional HTML index files: index.hhp, index.hhc, and index.hhk. The # index.hhp is a project file that can be read by Microsoft's HTML Help Workshop -# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on -# Windows. +# on Windows. In the beginning of 2021 Microsoft took the original page, with +# a.o. the download links, offline the HTML help workshop was already many years +# in maintenance mode). You can download the HTML help workshop from the web +# archives at Installation executable (see: +# http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo +# ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe). # # The HTML Help Workshop contains a compiler that can convert all HTML output # generated by doxygen into a single compiled HTML file (.chm). Compiled HTML @@ -1298,7 +1527,7 @@ CHM_FILE = HHC_LOCATION = # The GENERATE_CHI flag controls if a separate .chi index file is generated -# (YES) or that it should be included in the master .chm file (NO). +# (YES) or that it should be included in the main .chm file (NO). # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. @@ -1343,7 +1572,8 @@ QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help # Project output. For more information please see Qt Help Project / Namespace -# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). +# (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_QHP is set to YES. @@ -1351,8 +1581,8 @@ QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt # Help Project output. For more information please see Qt Help Project / Virtual -# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- -# folders). +# Folders (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders). # The default value is: doc. # This tag requires that the tag GENERATE_QHP is set to YES. @@ -1360,30 +1590,30 @@ QHP_VIRTUAL_FOLDER = doc # If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom # filter to add. For more information please see Qt Help Project / Custom -# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- -# filters). +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_NAME = # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see Qt Help Project / Custom -# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- -# filters). +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's filter section matches. Qt Help Project / Filter Attributes (see: -# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_SECT_FILTER_ATTRS = -# The QHG_LOCATION tag can be used to specify the location of Qt's -# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the -# generated .qhp file. +# The QHG_LOCATION tag can be used to specify the location (absolute path +# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to +# run qhelpgenerator on the generated .qhp file. # This tag requires that the tag GENERATE_QHP is set to YES. QHG_LOCATION = @@ -1426,16 +1656,28 @@ DISABLE_INDEX = NO # to work a browser that supports JavaScript, DHTML, CSS and frames is required # (i.e. any modern browser). Windows users are probably better off using the # HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can -# further fine-tune the look of the index. As an example, the default style -# sheet generated by doxygen has an example that shows how to put an image at -# the root of the tree instead of the PROJECT_NAME. Since the tree basically has -# the same information as the tab index, you could consider setting -# DISABLE_INDEX to YES when enabling this option. +# further fine tune the look of the index (see "Fine-tuning the output"). As an +# example, the default style sheet generated by doxygen has an example that +# shows how to put an image at the root of the tree instead of the PROJECT_NAME. +# Since the tree basically has the same information as the tab index, you could +# consider setting DISABLE_INDEX to YES when enabling this option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_TREEVIEW = NO +# When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the +# FULL_SIDEBAR option determines if the side bar is limited to only the treeview +# area (value NO) or if it should extend to the full height of the window (value +# YES). Setting this to YES gives a layout similar to +# https://docs.readthedocs.io with more room for contents, but less room for the +# project logo, title, and description. If either GENERATE_TREEVIEW or +# DISABLE_INDEX is set to NO, this option has no effect. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FULL_SIDEBAR = NO + # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that # doxygen will group on one line in the generated HTML documentation. # @@ -1460,6 +1702,24 @@ TREEVIEW_WIDTH = 250 EXT_LINKS_IN_WINDOW = NO +# If the OBFUSCATE_EMAILS tag is set to YES, doxygen will obfuscate email +# addresses. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +OBFUSCATE_EMAILS = YES + +# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg +# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see +# https://inkscape.org) to generate formulas as SVG images instead of PNGs for +# the HTML output. These images will generally look nicer at scaled resolutions. +# Possible values are: png (the default) and svg (looks nicer but requires the +# pdf2svg or inkscape tool). +# The default value is: png. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FORMULA_FORMAT = png + # Use this tag to change the font size of LaTeX formulas included as images in # the HTML documentation. When you change the font size after a successful # doxygen run you need to manually remove any form_*.png images from the HTML @@ -1469,19 +1729,14 @@ EXT_LINKS_IN_WINDOW = NO FORMULA_FONTSIZE = 10 -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are not -# supported properly for IE 6.0, but are supported on all modern browsers. -# -# Note that when changing this option you need to delete any form_*.png files in -# the HTML output directory before the changes have effect. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. +# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands +# to create new LaTeX commands to be used in formulas as building blocks. See +# the section "Including formulas" for details. -FORMULA_TRANSPARENT = YES +FORMULA_MACROFILE = # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see -# http://www.mathjax.org) which uses client side Javascript for the rendering +# https://www.mathjax.org) which uses client side JavaScript for the rendering # instead of using pre-rendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path @@ -1491,11 +1746,29 @@ FORMULA_TRANSPARENT = YES USE_MATHJAX = NO +# With MATHJAX_VERSION it is possible to specify the MathJax version to be used. +# Note that the different versions of MathJax have different requirements with +# regards to the different settings, so it is possible that also other MathJax +# settings have to be changed when switching between the different MathJax +# versions. +# Possible values are: MathJax_2 and MathJax_3. +# The default value is: MathJax_2. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_VERSION = MathJax_2 + # When MathJax is enabled you can set the default output format to be used for -# the MathJax output. See the MathJax site (see: -# http://docs.mathjax.org/en/latest/output.html) for more details. +# the MathJax output. For more details about the output format see MathJax +# version 2 (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) and MathJax version 3 +# (see: +# http://docs.mathjax.org/en/latest/web/components/output.html). # Possible values are: HTML-CSS (which is slower, but has the best -# compatibility), NativeMML (i.e. MathML) and SVG. +# compatibility. This is the name for Mathjax version 2, for MathJax version 3 +# this will be translated into chtml), NativeMML (i.e. MathML. Only supported +# for NathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This +# is the name for Mathjax version 3, for MathJax version 2 this will be +# translated into HTML-CSS) and SVG. # The default value is: HTML-CSS. # This tag requires that the tag USE_MATHJAX is set to YES. @@ -1508,22 +1781,29 @@ MATHJAX_FORMAT = HTML-CSS # MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax # Content Delivery Network so you can quickly see the result without installing # MathJax. However, it is strongly recommended to install a local copy of -# MathJax from http://www.mathjax.org before deployment. -# The default value is: http://cdn.mathjax.org/mathjax/latest. +# MathJax from https://www.mathjax.org before deployment. The default value is: +# - in case of MathJax version 2: https://cdn.jsdelivr.net/npm/mathjax@2 +# - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3 # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax # extension names that should be enabled during MathJax rendering. For example +# for MathJax version 2 (see +# https://docs.mathjax.org/en/v2.7-latest/tex.html#tex-and-latex-extensions): # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# For example for MathJax version 3 (see +# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html): +# MATHJAX_EXTENSIONS = ams # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_EXTENSIONS = # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces # of code that will be used on startup of the MathJax code. See the MathJax site -# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an # example see the documentation. # This tag requires that the tag USE_MATHJAX is set to YES. @@ -1551,7 +1831,7 @@ MATHJAX_CODEFILE = SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a web server instead of a web client using Javascript. There +# implemented using a web server instead of a web client using JavaScript. There # are two flavors of web server based searching depending on the EXTERNAL_SEARCH # setting. When disabled, doxygen will generate a PHP script for searching and # an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing @@ -1570,7 +1850,8 @@ SERVER_BASED_SEARCH = NO # # Doxygen ships with an example indexer (doxyindexer) and search engine # (doxysearch.cgi) which are based on the open source search engine library -# Xapian (see: http://xapian.org/). +# Xapian (see: +# https://xapian.org/). # # See the section "External Indexing and Searching" for details. # The default value is: NO. @@ -1583,8 +1864,9 @@ EXTERNAL_SEARCH = NO # # Doxygen ships with an example indexer (doxyindexer) and search engine # (doxysearch.cgi) which are based on the open source search engine library -# Xapian (see: http://xapian.org/). See the section "External Indexing and -# Searching" for details. +# Xapian (see: +# https://xapian.org/). See the section "External Indexing and Searching" for +# details. # This tag requires that the tag SEARCHENGINE is set to YES. SEARCHENGINE_URL = @@ -1635,21 +1917,35 @@ LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. # -# Note that when enabling USE_PDFLATEX this option is only used for generating -# bitmaps for formulas in the HTML output, but not in the Makefile that is -# written to the output directory. -# The default file is: latex. +# Note that when not enabling USE_PDFLATEX the default is latex when enabling +# USE_PDFLATEX the default is pdflatex and when in the later case latex is +# chosen this is overwritten by pdflatex. For specific output languages the +# default can have been set differently, this depends on the implementation of +# the output language. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate # index for LaTeX. +# Note: This tag is used in the Makefile / make.bat. +# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file +# (.tex). # The default file is: makeindex. # This tag requires that the tag GENERATE_LATEX is set to YES. MAKEINDEX_CMD_NAME = makeindex +# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to +# generate index for LaTeX. In case there is no backslash (\) as first character +# it will be automatically added in the LaTeX code. +# Note: This tag is used in the generated output file (.tex). +# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat. +# The default value is: makeindex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_MAKEINDEX_CMD = makeindex + # If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX # documents. This may be useful for small projects and may help to save some # trees in general. @@ -1679,29 +1975,31 @@ PAPER_TYPE = a4 EXTRA_PACKAGES = -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the -# generated LaTeX document. The header should contain everything until the first -# chapter. If it is left blank doxygen will generate a standard header. See -# section "Doxygen usage" for information on how to let doxygen write the -# default header to a separate file. +# The LATEX_HEADER tag can be used to specify a user-defined LaTeX header for +# the generated LaTeX document. The header should contain everything until the +# first chapter. If it is left blank doxygen will generate a standard header. It +# is highly recommended to start with a default header using +# doxygen -w latex new_header.tex new_footer.tex new_stylesheet.sty +# and then modify the file new_header.tex. See also section "Doxygen usage" for +# information on how to generate the default header that doxygen normally uses. # -# Note: Only use a user-defined header if you know what you are doing! The -# following commands have a special meaning inside the header: $title, -# $datetime, $date, $doxygenversion, $projectname, $projectnumber, -# $projectbrief, $projectlogo. Doxygen will replace $title with the empty -# string, for the replacement values of the other commands the user is referred -# to HTML_HEADER. +# Note: Only use a user-defined header if you know what you are doing! +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. The following +# commands have a special meaning inside the header (and footer): For a +# description of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_HEADER = -# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the -# generated LaTeX document. The footer should contain everything after the last -# chapter. If it is left blank doxygen will generate a standard footer. See +# The LATEX_FOOTER tag can be used to specify a user-defined LaTeX footer for +# the generated LaTeX document. The footer should contain everything after the +# last chapter. If it is left blank doxygen will generate a standard footer. See # LATEX_HEADER for more information on how to generate a default footer and what -# special commands can be used inside the footer. -# -# Note: Only use a user-defined footer if you know what you are doing! +# special commands can be used inside the footer. See also section "Doxygen +# usage" for information on how to generate the default footer that doxygen +# normally uses. Note: Only use a user-defined footer if you know what you are +# doing! # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_FOOTER = @@ -1734,9 +2032,11 @@ LATEX_EXTRA_FILES = PDF_HYPERLINKS = YES -# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate -# the PDF file directly from the LaTeX files. Set this option to YES, to get a -# higher quality PDF documentation. +# If the USE_PDFLATEX tag is set to YES, doxygen will use the engine as +# specified with LATEX_CMD_NAME to generate the PDF file directly from the LaTeX +# files. Set this option to YES, to get a higher quality PDF documentation. +# +# See also section LATEX_CMD_NAME for selecting the engine. # The default value is: YES. # This tag requires that the tag GENERATE_LATEX is set to YES. @@ -1744,8 +2044,7 @@ USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode # command to the generated LaTeX files. This will instruct LaTeX to keep running -# if errors occur, instead of asking the user for help. This option is also used -# when generating formulas in HTML. +# if errors occur, instead of asking the user for help. # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. @@ -1758,19 +2057,9 @@ LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO -# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source -# code with syntax highlighting in the LaTeX output. -# -# Note that which sources are shown also depends on other settings such as -# SOURCE_BROWSER. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_SOURCE_CODE = NO - # The LATEX_BIB_STYLE tag can be used to specify the style to use for the # bibliography, e.g. plainnat, or ieeetr. See -# http://en.wikipedia.org/wiki/BibTeX and \cite for more info. +# https://en.wikipedia.org/wiki/BibTeX and \cite for more info. # The default value is: plain. # This tag requires that the tag GENERATE_LATEX is set to YES. @@ -1784,6 +2073,14 @@ LATEX_BIB_STYLE = plain LATEX_TIMESTAMP = NO +# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute) +# path from which the emoji images will be read. If a relative path is entered, +# it will be relative to the LATEX_OUTPUT directory. If left blank the +# LATEX_OUTPUT directory will be used. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_EMOJI_DIRECTORY = + #--------------------------------------------------------------------------- # Configuration options related to the RTF output #--------------------------------------------------------------------------- @@ -1823,9 +2120,9 @@ COMPACT_RTF = NO RTF_HYPERLINKS = NO -# Load stylesheet definitions from file. Syntax is similar to doxygen's config -# file, i.e. a series of assignments. You only have to provide replacements, -# missing definitions are set to their default value. +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# configuration file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. # # See also section "Doxygen usage" for information on how to generate the # default style sheet that doxygen normally uses. @@ -1834,22 +2131,12 @@ RTF_HYPERLINKS = NO RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an RTF document. Syntax is -# similar to doxygen's config file. A template extensions file can be generated -# using doxygen -e rtf extensionFile. +# similar to doxygen's configuration file. A template extensions file can be +# generated using doxygen -e rtf extensionFile. # This tag requires that the tag GENERATE_RTF is set to YES. RTF_EXTENSIONS_FILE = -# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code -# with syntax highlighting in the RTF output. -# -# Note that which sources are shown also depends on other settings such as -# SOURCE_BROWSER. -# The default value is: NO. -# This tag requires that the tag GENERATE_RTF is set to YES. - -RTF_SOURCE_CODE = NO - #--------------------------------------------------------------------------- # Configuration options related to the man page output #--------------------------------------------------------------------------- @@ -1921,6 +2208,13 @@ XML_OUTPUT = xml XML_PROGRAMLISTING = YES +# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include +# namespace members in file scope as well, matching the HTML output. +# The default value is: NO. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_NS_MEMB_FILE_SCOPE = NO + #--------------------------------------------------------------------------- # Configuration options related to the DOCBOOK output #--------------------------------------------------------------------------- @@ -1939,23 +2233,14 @@ GENERATE_DOCBOOK = NO DOCBOOK_OUTPUT = docbook -# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the -# program listings (including syntax highlighting and cross-referencing -# information) to the DOCBOOK output. Note that enabling this will significantly -# increase the size of the DOCBOOK output. -# The default value is: NO. -# This tag requires that the tag GENERATE_DOCBOOK is set to YES. - -DOCBOOK_PROGRAMLISTING = NO - #--------------------------------------------------------------------------- # Configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an -# AutoGen Definitions (see http://autogen.sf.net) file that captures the -# structure of the code including all documentation. Note that this feature is -# still experimental and incomplete at the moment. +# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures +# the structure of the code including all documentation. Note that this feature +# is still experimental and incomplete at the moment. # The default value is: NO. GENERATE_AUTOGEN_DEF = NO @@ -2006,6 +2291,16 @@ PERLMOD_MAKEVAR_PREFIX = # C-preprocessor directives found in the sources and include files. # The default value is: YES. +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names +# in the source code. If set to NO, only conditional compilation will be +# performed. Macro expansion can be done in a controlled way by setting +# EXPAND_ONLY_PREDEF to YES. +# The default value is: NO. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +MACRO_EXPANSION = YES # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then # the macro expansion is limited to the macros specified with the PREDEFINED and @@ -2013,7 +2308,31 @@ PERLMOD_MAKEVAR_PREFIX = # The default value is: NO. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES, the include files in the +# INCLUDE_PATH will be searched if a #include is found. +# The default value is: YES. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by the +# preprocessor. Note that the INCLUDE_PATH is not recursive, so the setting of +# RECURSIVE has no effect here. +# This tag requires that the tag SEARCH_INCLUDES is set to YES. +INCLUDE_PATH = include \ + include/mruby + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will be +# used. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +INCLUDE_FILE_PATTERNS = *.h # The PREDEFINED tag can be used to specify one or more macro names that are # defined before the preprocessor is started (similar to the -D option of e.g. @@ -2023,6 +2342,7 @@ PERLMOD_MAKEVAR_PREFIX = # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. +PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The @@ -2031,6 +2351,7 @@ PERLMOD_MAKEVAR_PREFIX = # definition found in the source code. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. +EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will # remove all references to function-like macros that are alone on a line, have @@ -2040,6 +2361,7 @@ PERLMOD_MAKEVAR_PREFIX = # The default value is: YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. +SKIP_FUNCTION_MACROS = NO #--------------------------------------------------------------------------- # Configuration options related to external references @@ -2087,34 +2409,10 @@ EXTERNAL_GROUPS = YES EXTERNAL_PAGES = YES -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of 'which perl'). -# The default file (with absolute path) is: /usr/bin/perl. - -PERL_PATH = /usr/bin/perl - #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- -# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram -# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to -# NO turns the diagrams off. Note that this option also works with HAVE_DOT -# disabled, but it is recommended to install and use dot, since it yields more -# powerful graphs. -# The default value is: YES. - -CLASS_DIAGRAMS = YES - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see: -# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - # You can include diagrams made with dia in doxygen documentation. Doxygen will # then run dia to produce the diagram and insert it in the documentation. The # DIA_PATH tag allows you to specify the directory where the dia binary resides. @@ -2133,7 +2431,7 @@ HIDE_UNDOC_RELATIONS = YES # http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent # Bell Labs. The other options in this section have no effect if this option is # set to NO -# The default value is: YES. +# The default value is: NO. HAVE_DOT = YES @@ -2147,35 +2445,50 @@ HAVE_DOT = YES DOT_NUM_THREADS = 0 -# When you want a differently looking font in the dot files that doxygen -# generates you can specify the font name using DOT_FONTNAME. You need to make -# sure dot is able to find the font, which can be done by putting it in a -# standard location or by setting the DOTFONTPATH environment variable or by -# setting DOT_FONTPATH to the directory containing the font. -# The default value is: Helvetica. +# DOT_COMMON_ATTR is common attributes for nodes, edges and labels of +# subgraphs. When you want a differently looking font in the dot files that +# doxygen generates you can specify fontname, fontcolor and fontsize attributes. +# For details please see Node, +# Edge and Graph Attributes specification You need to make sure dot is able +# to find the font, which can be done by putting it in a standard location or by +# setting the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. Default graphviz fontsize is 14. +# The default value is: fontname=Helvetica,fontsize=10. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_COMMON_ATTR = "fontname=Helvetica,fontsize=10" + +# DOT_EDGE_ATTR is concatenated with DOT_COMMON_ATTR. For elegant style you can +# add 'arrowhead=open, arrowtail=open, arrowsize=0.5'. Complete documentation about +# arrows shapes. +# The default value is: labelfontname=Helvetica,labelfontsize=10. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_FONTNAME = Helvetica +DOT_EDGE_ATTR = "labelfontname=Helvetica,labelfontsize=10" -# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of -# dot graphs. -# Minimum value: 4, maximum value: 24, default value: 10. +# DOT_NODE_ATTR is concatenated with DOT_COMMON_ATTR. For view without boxes +# around nodes set 'shape=plain' or 'shape=plaintext' Shapes specification +# The default value is: shape=box,height=0.2,width=0.4. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_FONTSIZE = 10 +DOT_NODE_ATTR = "shape=box,height=0.2,width=0.4" -# By default doxygen will tell dot to use the default font as specified with -# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set -# the path where dot can find it using this tag. +# You can set the path where dot can find font specified with fontname in +# DOT_COMMON_ATTR and others dot attributes. # This tag requires that the tag HAVE_DOT is set to YES. DOT_FONTPATH = -# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for -# each documented class showing the direct and indirect inheritance relations. -# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO. +# If the CLASS_GRAPH tag is set to YES (or GRAPH) then doxygen will generate a +# graph for each documented class showing the direct and indirect inheritance +# relations. In case HAVE_DOT is set as well dot will be used to draw the graph, +# otherwise the built-in generator will be used. If the CLASS_GRAPH tag is set +# to TEXT the direct and indirect inheritance relations will be shown as texts / +# links. +# Possible values are: NO, YES, TEXT and GRAPH. # The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. CLASS_GRAPH = YES @@ -2189,7 +2502,8 @@ CLASS_GRAPH = YES COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for -# groups, showing the direct groups dependencies. +# groups, showing the direct groups dependencies. See also the chapter Grouping +# in the manual. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2212,10 +2526,32 @@ UML_LOOK = NO # but if the number exceeds 15, the total amount of fields shown is limited to # 10. # Minimum value: 0, maximum value: 100, default value: 10. -# This tag requires that the tag HAVE_DOT is set to YES. +# This tag requires that the tag UML_LOOK is set to YES. UML_LIMIT_NUM_FIELDS = 10 +# If the DOT_UML_DETAILS tag is set to NO, doxygen will show attributes and +# methods without types and arguments in the UML graphs. If the DOT_UML_DETAILS +# tag is set to YES, doxygen will add type and arguments for attributes and +# methods in the UML graphs. If the DOT_UML_DETAILS tag is set to NONE, doxygen +# will not generate fields with class member information in the UML graphs. The +# class diagrams will look similar to the default class diagrams but using UML +# notation for the relationships. +# Possible values are: NO, YES and NONE. +# The default value is: NO. +# This tag requires that the tag UML_LOOK is set to YES. + +DOT_UML_DETAILS = NO + +# The DOT_WRAP_THRESHOLD tag can be used to set the maximum number of characters +# to display on a single line. If the actual line length exceeds this threshold +# significantly it will wrapped across multiple lines. Some heuristics are apply +# to avoid ugly line breaks. +# Minimum value: 0, maximum value: 1000, default value: 17. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_WRAP_THRESHOLD = 17 + # If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and # collaboration graphs will show the relations between templates and their # instances. @@ -2282,6 +2618,13 @@ GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES +# The DIR_GRAPH_MAX_DEPTH tag can be used to limit the maximum number of levels +# of child directories generated in directory dependency graphs by dot. +# Minimum value: 1, maximum value: 25, default value: 1. +# This tag requires that the tag DIRECTORY_GRAPH is set to YES. + +DIR_GRAPH_MAX_DEPTH = 1 + # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. For an explanation of the image formats see the section # output formats in the documentation of the dot tool (Graphviz (see: @@ -2289,9 +2632,7 @@ DIRECTORY_GRAPH = YES # Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order # to make the SVG files visible in IE 9+ (other browsers do not have this # requirement). -# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd, -# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo, -# gif:cairo:gd, gif:gd, gif:gd:gd, svg, png:gd, png:gd:gd, png:cairo, +# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo, # png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and # png:gdiplus:gdiplus. # The default value is: png. @@ -2337,10 +2678,10 @@ MSCFILE_DIRS = DIAFILE_DIRS = # When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the -# path where java can find the plantuml.jar file. If left blank, it is assumed -# PlantUML is not used or called during a preprocessing step. Doxygen will -# generate a warning when it encounters a \startuml command in this case and -# will not generate output for the diagram. +# path where java can find the plantuml.jar file or to the filename of jar file +# to be used. If left blank, it is assumed PlantUML is not used or called during +# a preprocessing step. Doxygen will generate a warning when it encounters a +# \startuml command in this case and will not generate output for the diagram. PLANTUML_JAR_PATH = @@ -2378,18 +2719,6 @@ DOT_GRAPH_MAX_NODES = 50 MAX_DOT_GRAPH_DEPTH = 0 -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not seem -# to support this out of the box. -# -# Warning: Depending on the platform used, enabling this option may lead to -# badly anti-aliased labels on the edges of a graph (i.e. they become hard to -# read). -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_TRANSPARENT = NO - # Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) support @@ -2402,14 +2731,18 @@ DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page # explaining the meaning of the various boxes and arrows in the dot generated # graphs. +# Note: This tag requires that UML_LOOK isn't set, i.e. the doxygen internal +# graphical representation for inheritance and collaboration diagrams is used. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. GENERATE_LEGEND = YES -# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot +# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate # files that are used to generate the various graphs. +# +# Note: This setting is not only used for dot files but also for msc temporary +# files. # The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. DOT_CLEANUP = YES diff --git a/mruby/Gemfile b/mruby/Gemfile new file mode 100644 index 00000000..497e42ff --- /dev/null +++ b/mruby/Gemfile @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +source 'https://rubygems.org' + +gem 'rake' +gem 'yard' +gem 'yard-coderay' +gem 'yard-mruby' diff --git a/mruby/Gemfile.lock b/mruby/Gemfile.lock new file mode 100644 index 00000000..37e5d651 --- /dev/null +++ b/mruby/Gemfile.lock @@ -0,0 +1,27 @@ +GEM + remote: https://rubygems.org/ + specs: + coderay (1.1.3) + rake (13.0.6) + webrick (1.7.0) + yard (0.9.28) + webrick (~> 1.7.0) + yard-coderay (0.1.0) + coderay + yard + yard-mruby (0.3.0) + yard (~> 0.9.0) + +PLATFORMS + ruby + x86_64-darwin-21 + x86_64-linux + +DEPENDENCIES + rake + yard + yard-coderay + yard-mruby + +BUNDLED WITH + 2.4.10 diff --git a/mruby/Makefile b/mruby/Makefile index 4e70a8e6..a62a126e 100644 --- a/mruby/Makefile +++ b/mruby/Makefile @@ -18,6 +18,18 @@ check : pre-commit run --all-files .PHONY : check +checkinstall : + pre-commit install +.PHONY : checkinstall + checkupdate : pre-commit autoupdate .PHONY : checkupdate + +composecheck : + docker-compose -p mruby run test pre-commit run --all-files +.PHONY : composecheck + +composetest : + docker-compose -p mruby run test +.PHONY : composetest diff --git a/mruby/NEWS b/mruby/NEWS index 34cf8452..36f955eb 100644 --- a/mruby/NEWS +++ b/mruby/NEWS @@ -46,7 +46,6 @@ Following CVEs are fixed. - [CVE-2022-0080](https://nvd.nist.gov/vuln/detail/CVE-2022-0080) - [CVE-2022-0240](https://nvd.nist.gov/vuln/detail/CVE-2022-0240) - [CVE-2022-0326](https://nvd.nist.gov/vuln/detail/CVE-2022-0326) -- [CVE-2022-0631](https://nvd.nist.gov/vuln/detail/CVE-2022-0631) - [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) diff --git a/mruby/README.md b/mruby/README.md index cf310e01..ed3d9302 100644 --- a/mruby/README.md +++ b/mruby/README.md @@ -1,6 +1,16 @@ -# mruby - -[![GitHub Super-Linter](https://github.com/mruby/mruby/workflows/Lint%20Code%20Base/badge.svg)](https://github.com/marketplace/actions/super-linter) +
+

+ + The mruby programming language + +

+

mruby

+ + GitHub Super-Linter + +
## What is mruby @@ -8,18 +18,22 @@ mruby is the lightweight implementation of the Ruby language complying to (part of) the [ISO standard][ISO-standard] with more recent features provided by Ruby 3.x. Also, its syntax is Ruby 3.x compatible except for pattern matching. -mruby can be linked and embedded within your application. We provide the -interpreter program "mruby", and the interactive mruby shell "mirb" as examples. -You can also compile Ruby programs into compiled byte code using the mruby -compiler "mrbc". All those tools reside in the "bin" directory. "mrbc" is -also able to generate compiled byte code in a C source file, see the "mrbtest" -program under the "test" directory for an example. +You can link and embed mruby within your application. The "mruby" interpreter +program and the interactive "mirb" shell are provided as examples. You can also +compile Ruby programs into compiled byte code using the "mrbc" compiler. All +these tools are located in the "bin" directory. "mrbc" can also generate +compiled byte code in a C source file. See the "mrbtest" program under the +"test" directory for an example. This achievement was sponsored by the Regional Innovation Creation R&D Programs of the Ministry of Economy, Trade and Industry of Japan. ## How to get mruby +To get mruby, you can download the stable version 3.2.0 from the official mruby +GitHub repository or clone the trunk of the mruby source tree with the "git +clone" command. You can also install and compile mruby using [ruby-install](https://github.com/postmodern/ruby-install), [ruby-build](https://github.com/rbenv/ruby-build) or [rvm](https://github.com/rvm/rvm). + The stable version 3.2.0 of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/archive/3.2.0.zip](https://github.com/mruby/mruby/archive/3.2.0.zip) The latest development version of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/zipball/master](https://github.com/mruby/mruby/zipball/master) @@ -27,15 +41,13 @@ The latest development version of mruby can be downloaded via the following URL: The trunk of the mruby source tree can be checked out with the following command: -``` +```console $ git clone https://github.com/mruby/mruby.git ``` -You can also install and compile mruby using [ruby-install](https://github.com/postmodern/ruby-install), [ruby-build](https://github.com/rbenv/ruby-build) or [rvm](https://github.com/rvm/rvm). - -## mruby home-page +## mruby homepage -The URL of the mruby home-page is: . +The URL of the mruby homepage is: . ## Mailing list @@ -45,7 +57,7 @@ We don't have a mailing list, but you can use [GitHub issues](https://github.com For the simplest case, type -``` +```console rake all test ``` @@ -53,27 +65,27 @@ See the [compile.md](doc/guides/compile.md) file for the detail. ## Building documentation -There are two sets of documentation in mruby: the mruby API (generated by yard) and C API (Doxygen and Graphviz) +There are two sets of documentation in mruby: the mruby API (generated by YARD) and C API (Doxygen and Graphviz) To build both of them, simply go -``` +```console rake doc ``` You can also view them in your browser -``` +```console rake view_api rake view_capi ``` ## How to customize mruby (mrbgems) -mruby contains a package manager called *mrbgems*. To create extensions -in C and/or Ruby you should create a *GEM*. For a documentation of how to -use mrbgems consult the file [mrbgems.md](doc/guides/mrbgems.md). -For example code of how to use mrbgems look into the folder [examples/mrbgems/](examples/mrbgems). +mruby contains a package manager called "mrbgems" that you can use to create +extensions in C and/or Ruby. For a guide on how to use mrbgems, consult the +[mrbgems.md](doc/guides/mrbgems.md) file, and for example code, refer to the +[examples/mrbgems/](examples/mrbgems) folder. ## License @@ -98,9 +110,8 @@ Please ask us if you want to distribute your code under another license. ## How to Contribute -See the [contribution guidelines][contribution-guidelines], and then send a pull -request to . We consider you have granted -non-exclusive right to your contributed code under MIT license. +To contribute to mruby, please refer to the [contribution guidelines][contribution-guidelines] and send a pull request to the [mruby GitHub repository](https://github.com/mruby/mruby). +By contributing, you grant non-exclusive rights to your code under the MIT License. [ISO-standard]: https://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=59579 -[contribution-guidelines]: https://github.com/mruby/mruby/blob/master/CONTRIBUTING.md +[contribution-guidelines]: CONTRIBUTING.md diff --git a/mruby/Rakefile b/mruby/Rakefile index 5a8fbdb5..79ec84f6 100644 --- a/mruby/Rakefile +++ b/mruby/Rakefile @@ -31,6 +31,7 @@ load "#{MRUBY_ROOT}/tasks/presym.rake" load "#{MRUBY_ROOT}/tasks/test.rake" load "#{MRUBY_ROOT}/tasks/benchmark.rake" load "#{MRUBY_ROOT}/tasks/doc.rake" +load "#{MRUBY_ROOT}/tasks/install.rake" ############################## # generic build targets, rules @@ -56,7 +57,7 @@ task :clean do rm_rf build.build_dir rm_f build.products end - puts "Cleaned up target build folder" + puts "Cleaned up target build directory" end desc "clean everything!" @@ -64,35 +65,9 @@ task :deep_clean => %w[clean doc:clean] do MRuby.each_target do |build| rm_rf build.gem_clone_dir end - puts "Cleaned up mrbgems build folder" -end - -PREFIX = ENV['PREFIX'] || ENV['INSTALL_PREFIX'] || '/usr/local' - -desc "install compiled products" -task :install => :install_bin do - if host = MRuby.targets['host'] - install_D host.libmruby_static, File.join(PREFIX, "lib", File.basename(host.libmruby_static)) - # install mruby.h and mrbconf.h - Dir.glob(File.join(MRUBY_ROOT, "include", "*.h")) do |src| - install_D src, File.join(PREFIX, "include", File.basename(src)) - end - Dir.glob(File.join(MRUBY_ROOT, "include", "mruby", "*.h")) do |src| - install_D src, File.join(PREFIX, "include", "mruby", File.basename(src)) - end - Dir.glob(File.join(File.join(MRUBY_ROOT, "build", "host", "include", "mruby", "presym", "*.h"))) do |src| - install_D src, File.join(PREFIX, "include", "mruby", "presym", File.basename(src)) - end - end -end - -desc "install compiled executable (on host)" -task :install_bin => :all do - if host = MRuby.targets['host'] - Dir.glob(File.join(MRUBY_ROOT, "bin", "*")) do |src| - install_D src, File.join(PREFIX, "bin", File.basename(src)) - end - end + rm_rf "#{MRUBY_ROOT}/bin" + rm_rf "#{MRUBY_ROOT}/build" + puts "Cleaned up mrbgems build directory" end desc "run all pre-commit hooks against all files" @@ -100,7 +75,22 @@ task :check do sh "pre-commit run --all-files" end +desc "install the pre-commit hooks" +task :checkinstall do + sh "pre-commit install" +end + desc "check the pre-commit hooks for updates" task :checkupdate do sh "pre-commit autoupdate" end + +desc "run all pre-commit hooks against all files with docker-compose" +task :composecheck do + sh "docker-compose -p mruby run test pre-commit run --all-files" +end + +desc "build and run all mruby tests with docker-compose" +task :composetest do + sh "docker-compose -p mruby run test" +end diff --git a/mruby/appveyor.yml b/mruby/appveyor.yml index 8782f59a..3a063dd7 100644 --- a/mruby/appveyor.yml +++ b/mruby/appveyor.yml @@ -4,6 +4,10 @@ shallow_clone: true environment: matrix: + - job_name: Visual Studio 2022 64bit + visualcpp: C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat + appveyor_build_worker_image: Visual Studio 2022 + - job_name: Visual Studio 2019 64bit visualcpp: C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat appveyor_build_worker_image: Visual Studio 2019 @@ -38,7 +42,6 @@ init: - set PATH=C:\Ruby26-x64\bin;%PATH% - ruby --version - build_script: - set MRUBY_CONFIG=ci/msvc - rake -m test:build diff --git a/mruby/benchmark/bm_ao_render.rb b/mruby/benchmark/bm_ao_render.rb index 91e2d341..ddb42d5c 100644 --- a/mruby/benchmark/bm_ao_render.rb +++ b/mruby/benchmark/bm_ao_render.rb @@ -253,6 +253,7 @@ def ambient_occlusion(isect) def render(w, h, nsubsamples) nsf = nsubsamples.to_f + nsfs = nsf * nsf h.times do |y| w.times do |x| rad = Vec.new(0.0, 0.0, 0.0) @@ -288,9 +289,9 @@ def render(w, h, nsubsamples) end end - r = rad.x / (nsf * nsf) - g = rad.y / (nsf * nsf) - b = rad.z / (nsf * nsf) + r = rad.x / nsfs + g = rad.y / nsfs + b = rad.z / nsfs printf("%c", clamp(r)) printf("%c", clamp(g)) printf("%c", clamp(b)) diff --git a/mruby/build_config/android_arm64_v8a.rb b/mruby/build_config/android_arm64_v8a.rb index 8763b008..6dda612d 100644 --- a/mruby/build_config/android_arm64_v8a.rb +++ b/mruby/build_config/android_arm64_v8a.rb @@ -2,8 +2,8 @@ MRuby::CrossBuild.new('android-arm64-v8a') do |conf| params = { :arch => 'arm64-v8a', - :sdk_version => 26, - :toolchain => :clang, + :sdk_version => 33, + :toolchain => :clang } toolchain :android, params diff --git a/mruby/build_config/android_armeabi.rb b/mruby/build_config/android_armeabi.rb deleted file mode 100644 index cef0e3ad..00000000 --- a/mruby/build_config/android_armeabi.rb +++ /dev/null @@ -1,11 +0,0 @@ -# Requires Android NDK r13 or later. -MRuby::CrossBuild.new('android-armeabi') do |conf| - params = { - :arch => 'armeabi', - :sdk_version => 26, - :toolchain => :clang, - } - toolchain :android, params - - conf.gembox 'default' -end diff --git a/mruby/build_config/android_armeabi_v7a_neon_hard.rb b/mruby/build_config/android_armeabi_v7a_neon_hard.rb index 150d1d20..3dae2418 100644 --- a/mruby/build_config/android_armeabi_v7a_neon_hard.rb +++ b/mruby/build_config/android_armeabi_v7a_neon_hard.rb @@ -4,8 +4,8 @@ :arch => 'armeabi-v7a', :mfpu => 'neon', :mfloat_abi => 'hard', - :sdk_version => 26, - :toolchain => :clang, + :sdk_version => 33, + :toolchain => :clang } toolchain :android, params diff --git a/mruby/build_config/dreamcast_shelf.rb b/mruby/build_config/dreamcast_shelf.rb index 092fde0d..53adad2a 100644 --- a/mruby/build_config/dreamcast_shelf.rb +++ b/mruby/build_config/dreamcast_shelf.rb @@ -73,7 +73,6 @@ # Some Gems are incompatible and were disabled. conf.gem :core => "mruby-array-ext" - conf.gem :core => "mruby-binding" conf.gem :core => "mruby-catch" conf.gem :core => "mruby-class-ext" conf.gem :core => "mruby-cmath" diff --git a/mruby/build_config/i586-pc-msdosdjgpp.rb b/mruby/build_config/i586-pc-msdosdjgpp.rb new file mode 100644 index 00000000..4275423c --- /dev/null +++ b/mruby/build_config/i586-pc-msdosdjgpp.rb @@ -0,0 +1,77 @@ +# Cross Compiling configuration for MS-DOS +# +# Requires DJGPP cross-compiler, see +# https://github.com/andrewwutw/build-djgpp/releases + +MRuby::CrossBuild.new("i586-pc-msdosdjgpp") do |conf| + toolchain :gcc + + # If DJGPP is not in the PATH, set this to the bin directory + DJGPP_PATH = nil + + GCC = 'i586-pc-msdosdjgpp-gcc' + GXX = 'i586-pc-msdosdjgpp-g++' + AR = 'i586-pc-msdosdjgpp-ar' + + conf.cc do |cc| + cc.command = DJGPP_PATH ? File.join(DJGPP_PATH, GCC) : GCC + cc.defines << 'MRB_WITHOUT_IO_PREAD_PWRITE' + cc.defines << 'MRB_UTF8_STRING' + end + + conf.cxx do |cxx| + cxx.command = DJGPP_PATH ? File.join(DJGPP_PATH, GXX) : GXX + cxx.defines << 'MRB_WITHOUT_IO_PREAD_PWRITE' + cxx.defines << 'MRB_UTF8_STRING' + end + + conf.linker do |linker| + linker.command = DJGPP_PATH ? File.join(DJGPP_PATH, GXX) : GXX + linker.libraries = %w(m) + end + + conf.archiver do |archiver| + archiver.command = DJGPP_PATH ? File.join(DJGPP_PATH, AR) : AR + end + + # All provided gems that can be reasonably made to compile: + # default.gembox, minus mruby-socket and replacing mruby-cmath with mruby-cmath-alt + conf.gembox "stdlib" + conf.gembox "stdlib-ext" + + conf.gem :core => 'mruby-io' # stdlib-io.gembox <- default.gembox +# No socket support in DJGPP +# conf.gem :core => 'mruby-socket' # stdlib-io.gembox <- default.gembox + conf.gem :core => 'mruby-print' # stdlib-io.gembox <- default.gembox + conf.gem :core => 'mruby-errno' # stdlib-io.gembox <- default.gembox + conf.gem :core => 'mruby-dir' # stdlib-io.gembox <- default.gembox + + conf.gem :core => 'mruby-bigint' # math.gembox <- default.gembox + conf.gem :core => 'mruby-complex' # math.gembox <- default.gembox + conf.gem :core => 'mruby-math' # math.gembox <- default.gembox + conf.gem :core => 'mruby-rational' # math.gembox <- default.gembox + # Alternative implementation of cmath, not requiring +# conf.gem :github => 'chasonr/mruby-cmath-alt' # math.gembox <- default.gembox + + conf.gembox "metaprog" + + conf.gem :core => 'mruby-bin-mrbc' # default.gembox + conf.gem :core => 'mruby-bin-debugger' # default.gembox + conf.gem :core => 'mruby-bin-mirb' # default.gembox + conf.gem :core => 'mruby-bin-mruby' # default.gembox + conf.gem :core => 'mruby-bin-strip' # default.gembox + conf.gem :core => 'mruby-bin-config' # default.gembox + + # Other compilable gems + conf.gem :core => 'mruby-binding' + conf.gem :core => 'mruby-catch' + conf.gem :core => 'mruby-enum-chain' + conf.gem :core => 'mruby-error' + conf.gem :core => 'mruby-exit' + conf.gem :core => 'mruby-os-memsize' + conf.gem :core => 'mruby-proc-binding' + conf.gem :core => 'mruby-sleep' + + # For Onigmo regular expression support + conf.gem :github => 'mattn/mruby-onig-regexp' +end diff --git a/mruby/codespell.txt b/mruby/codespell.txt index d6d80b07..9a4d7548 100644 --- a/mruby/codespell.txt +++ b/mruby/codespell.txt @@ -1,20 +1,16 @@ ans -ba +celler clen -creat delet disabl -falsy filetest fo hel -hist ist -methid nd quitt remore -ro runn sting -upto +strin +wronly diff --git a/mruby/doc/guides/compile.md b/mruby/doc/guides/compile.md index 4302d136..579a49d7 100644 --- a/mruby/doc/guides/compile.md +++ b/mruby/doc/guides/compile.md @@ -177,7 +177,7 @@ conf.linker do |linker| linker.flags_before_libraries = ... linker.libraries = ... linker.flags_after_libraries = ... - linker.library_paths = .... + linker.library_paths = ... linker.option_library = ... linker.option_library_path = ... linker.link_options = ... @@ -265,7 +265,7 @@ There is a `RubyGem` (gem for CRuby) named `mgem` that help you to manage `mrbgems`. Try `gem install mgem`. `mgem` can show you the list of registered `mrbgems`. -See doc/mrbgems/README.md for more option about mrbgems. +See [doc/guides/mrbgems.md](mrbgems.md) for more option about mrbgems. ### Mrbtest @@ -376,7 +376,7 @@ end ## Build process -During the build process the directory `build` will be created in the +During the build process the `build` directory will be created in the root directory. The structure of this directory will look like this: ``` @@ -527,7 +527,7 @@ After the build, you will get `libmruby.a`. You can link it to your application. For compiler options and library path, you can use `mruby-config` command for convenience. `mruby-config` command prints the configuration used for `libmruby.a`. -``` +```console $ mruby-config --help Usage: mruby-config [switches] switches: @@ -557,6 +557,56 @@ LDFLAGS = `$(MRB_CONFIG) --ldflags` LIBS = `$(MRB_CONFIG) --libs` ``` +## Install + +To install the files in the `bin`, `include` and `lib` directories generated by the "host" build target into a system directory, do the following: + +```console +$ rake install +``` + +If there are multiple build targets in the build configuration file, to install the products of all build targets, do the following: + +```console +$ rake install:full +``` + +To install only one of several build targets, e.g., the "its-mine" build target, do the following: + +```console +$ rake install:full:its-mine +``` + +To install only the executable files, do the following: + +```console +$ rake install_bin # only "host" build target +$ rake install:bin # all build targets +$ rake install:bin:its-mine # only "its-mine" build target +``` + +### Installation Directory + +The installation directory is `/usr/local` for the "host" build target and `/usr/local/mruby/` for the others. +To change them, you can set the environment variable `PREFIX` or use `MRuby::Build#install_prefix = dir` in your build configuration file. + +The `PREFIX` environment variable affects all build targets and changes the `/usr/local` part. + +The `MRuby::Build#install_prefix` can be set for each individual build target. +In this case, the environment variable `PREFIX` is ignored. + +Also, if the environment variable `DESTDIR` is set, it will prepend to the path obtained by `install_prefix` to determine the final write directory. +This is intended for temporary file expansion by the user's package work. + +--- + +To summarize: + +- The default value of the environment variable `PREFIX` is `/usr/local`. +- For the "host" build target, the default value of `MRuby::Build#install_prefix` is ``. +- For a build target other than "host", the default value of `MRuby::Build#install_prefix` is `/mruby/`. +- If the environment variable `DESTDIR` is set, the actual write directory is `/`. + ## Tips - If you see compilation troubles, try `rake clean` first. diff --git a/mruby/doc/guides/debugger.md b/mruby/doc/guides/debugger.md index ef48005a..40afb507 100644 --- a/mruby/doc/guides/debugger.md +++ b/mruby/doc/guides/debugger.md @@ -38,7 +38,7 @@ To confirm mrdb was installed properly, run mrdb with the `--version` option: ```bash $ mrdb --version -mruby 3.1.0 (2022-05-12) +mruby 3.2.0 (2023-02-24) ``` ## 2.2 Basic Operation diff --git a/mruby/doc/guides/gc-arena-howto.md b/mruby/doc/guides/gc-arena-howto.md index 22cd4ef1..31bee93f 100644 --- a/mruby/doc/guides/gc-arena-howto.md +++ b/mruby/doc/guides/gc-arena-howto.md @@ -3,6 +3,7 @@ _This is an English translation of [Matz's blog post][matz blog post] written in Japanese._ _Some parts are updated to reflect recent changes._ + [matz blog post]: When you are extending mruby using C language, you may encounter @@ -62,7 +63,7 @@ memory leak. As of this writing, mruby automatically extend arena to remember objects (See `MRB_GC_FIXED_ARENA` and `MRB_GC_ARENA_SIZE` in -doc/guides/mrbconf.md). +[doc/guides/mrbconf.md](mrbconf.md)). If you create many objects in C functions, memory usage will increase, since GC never kicks in. This memory usage may look like memory leaks, but will also @@ -106,7 +107,7 @@ inspect_ary(mrb_state *mrb, mrb_value ary, mrb_value list) char tail[] = { ']' }; /* check recursive */ - for(i=0; i 0) { diff --git a/mruby/doc/guides/link.md b/mruby/doc/guides/link.md index 861f7136..491efc41 100644 --- a/mruby/doc/guides/link.md +++ b/mruby/doc/guides/link.md @@ -54,7 +54,7 @@ command with following options: - `--cc` compiler name - `--cflags` options passed to compiler -``` +```console $ mruby-config --cflags -std=gnu99 -g -O3 -Wall -DMRB_GC_FIXED_ARENA -I/home/matz/work/mruby/include -I/home/matz/work/mruby/build/host/include ``` @@ -71,7 +71,7 @@ To retrieve linker options, you can use `mruby-config` with following options: - `--ldflags-before-libs` options passed to linker before linked libraries - `--libs` linked libraries -``` +```console $ mruby-config --ldflags -L/home/matz/work/mruby/build/host/lib diff --git a/mruby/doc/guides/mrbconf.md b/mruby/doc/guides/mrbconf.md index 771922a4..dc153850 100644 --- a/mruby/doc/guides/mrbconf.md +++ b/mruby/doc/guides/mrbconf.md @@ -18,10 +18,10 @@ This is the same for `MRuby::CrossBuild`. # build_config.rb MRuby::Build.new do |conf| - ..... + ... conf.defines << 'MRB_GC_FIXED_ARENA' conf.defines << 'MRB_NO_METHOD_CACHE' - ..... + ... end ``` @@ -247,6 +247,6 @@ largest value of required alignment. - Make it available `Symbol.all_symbols` in `mrbgems/mruby-symbol-ext` - Increase heap memory usage. -`MRB_NO_DIRECT_THREADING` +`MRB_USE_VM_SWITCH_DISPATCH` -- Turn off direct threading optimization in VM loop +- Turn on switch dispatch in VM loop diff --git a/mruby/doc/guides/mrbgems.md b/mruby/doc/guides/mrbgems.md index e81a30ac..999629d4 100644 --- a/mruby/doc/guides/mrbgems.md +++ b/mruby/doc/guides/mrbgems.md @@ -1,6 +1,6 @@ # mrbgems -mrbgems is a library manager to integrate C and Ruby extension in an easy and +mrbgems is a library manager to integrate C and Ruby extensions in an easy and standardised way into mruby. Conventionally, each mrbgem name is prefixed by `mruby-`, e.g. `mruby-time` for a gem that provides `Time` class functionality. @@ -92,6 +92,21 @@ end However, it should be used with caution, as it may deviate from the intent of the gem's author. +### Gem Testing + +If you enable unit tests in your build with `enable_test`, tests will be +generated for all gems and their dependencies by default. If necessary, it is +possible to suppress tests for a specific gem like so: + +```ruby +conf.gem 'mruby-noisygem' do |g| + g.skip_test = true +end +``` + +However, it is considered best practice to leave all tests enabled whenever +possible. A warning message will be generated for each gem with disabled tests. + ## GemBox There are instances when you wish to add a collection of mrbgems into mruby at @@ -160,9 +175,9 @@ The maximal GEM structure looks like this: +- test/ <- Test code (Ruby) ``` -The folder `mrblib` contains pure Ruby files to extend mruby. The folder `src` -contains C/C++ files to extend mruby. The folder `include` contains C/C++ header -files. The folder `test` contains C/C++ and pure Ruby files for testing purposes +The `mrblib` directory contains pure Ruby files to extend mruby. The `src` directory +contains C/C++ files to extend mruby. The `include` directory contains C/C++ header +files. The `test` directory contains C/C++ and pure Ruby files for testing purposes which will be used by `mrbtest`. `mrbgem.rake` contains the specification to compile C and Ruby files. `README.md` is a short description of your GEM. @@ -349,7 +364,7 @@ mrb_c_extension_example_gem_final(mrb_state* mrb) { mruby can be extended with pure Ruby. It is possible to override existing classes or add new ones in this way. Put all Ruby files into the `mrblib` -folder. +directory. ### Pre-Conditions @@ -377,7 +392,7 @@ none mruby can be extended with C and Ruby at the same time. It is possible to override existing classes or add new ones in this way. Put all Ruby files -into the `mrblib` folder and all C files into the `src` folder. +into the `mrblib` directory and all C files into the `src` directory. mruby codes under `mrblib` directory would be executed after gem init C function is called. Make sure *mruby script* depends on *C code* and diff --git a/mruby/doc/limitations.md b/mruby/doc/limitations.md index ae09ecf3..3c65f76e 100644 --- a/mruby/doc/limitations.md +++ b/mruby/doc/limitations.md @@ -64,7 +64,7 @@ p Liste.new "foobar" #### Ruby [ruby 2.0.0p645 (2015-04-13 revision 50299)] -` [] ` +`[]` #### mruby [3.1.0 (2022-05-12)] @@ -114,7 +114,7 @@ The declaration form of following visibility methods are not implemented. Especially, `module_function` method is not dummy, but no declaration form. -``` +```ruby module TestModule module_function def test_func @@ -170,7 +170,7 @@ alias $a $__a__ #### Ruby [ruby 2.0.0p645 (2015-04-13 revision 50299)] -` nil ` +`nil` #### mruby [3.1.0 (2022-05-12)] @@ -196,7 +196,7 @@ The re-defined `+` operator does not accept any arguments. #### mruby [3.1.0 (2022-05-12)] -` 'ab' ` +`'ab'` Behavior of the operator wasn't changed. ## `Kernel#binding` is not supported until [3.0.0 (2021-03-05)] @@ -205,26 +205,11 @@ Behavior of the operator wasn't changed. #### Ruby [ruby 2.5.1p57 (2018-03-29 revision 63029)] -``` +```shell $ ruby -e 'puts Proc.new {}.binding' # ``` -#### mruby [3.0.0 (2021-03-05)] - -``` -$ ./bin/mruby -e 'puts Proc.new {}.binding' -trace (most recent call last): - [0] -e:1 --e:1: undefined method 'binding' (NoMethodError) -``` - -#### mruby [3.1.0 (2022-05-12)] - -`binding` has been supported since 3.1.0. - -See also [mrbgems/mruby-binding](https://github.com/mruby/mruby/tree/master/mrbgems/mruby-binding) and [mrbgems/mruby-binding-core](https://github.com/mruby/mruby/tree/master/mrbgems/mruby-binding-core). - ## `nil?` redefinition in conditional expressions Redefinition of `nil?` is ignored in conditional expressions. @@ -259,3 +244,12 @@ f(1,[2,3]) ``` CRuby gives `[1,2,3,nil]`. mruby raises `NoMethodError` for `b`. + +Keyword argument expansion has similar restrictions. The following example, gives `[1, 1]` for CRuby, mruby raises `NoMethodError` for `b`. + +```ruby +def g(a: 1, b: a) + p [a,b] +end +g(a:1) +``` diff --git a/mruby/doc/mruby3.0.md b/mruby/doc/mruby3.0.md index c1acb5ec..3f7418c4 100644 --- a/mruby/doc/mruby3.0.md +++ b/mruby/doc/mruby3.0.md @@ -159,4 +159,4 @@ For better and faster random number generation. Preallocated symbols are interned at compile-time. They can be accessed via symbols macros (e.g. `MRB_SYM()`). -See [Symbols](https://github.com/mruby/mruby/blob/master/doc/guides/symbol.md). +See [Symbols](guides/symbol.md). diff --git a/mruby/doc/mruby3.2.md b/mruby/doc/mruby3.2.md index 1ca18d6b..59bd1e2e 100644 --- a/mruby/doc/mruby3.2.md +++ b/mruby/doc/mruby3.2.md @@ -32,9 +32,9 @@ ## New bundled gems -- mruby-errno from [https://github.com/iij/mruby-errno.git] -- mruby-set from [https://github.com/yui-knk/mruby-set.git] -- mruby-dir from [https://github.com/iij/mruby-dir.git] +- mruby-errno from +- mruby-set from +- mruby-dir from - mruby-data # Breaking Changes @@ -62,7 +62,6 @@ Following CVEs are fixed. - [CVE-2022-0080](https://nvd.nist.gov/vuln/detail/CVE-2022-0080) - [CVE-2022-0240](https://nvd.nist.gov/vuln/detail/CVE-2022-0240) - [CVE-2022-0326](https://nvd.nist.gov/vuln/detail/CVE-2022-0326) -- [CVE-2022-0631](https://nvd.nist.gov/vuln/detail/CVE-2022-0631) - [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) diff --git a/mruby/docker-compose.yml b/mruby/docker-compose.yml new file mode 100644 index 00000000..223e85af --- /dev/null +++ b/mruby/docker-compose.yml @@ -0,0 +1,13 @@ +version: '3' +services: + test: + build: + context: . + command: sh -c 'rake deep_clean && rake -m test:build && rake test:run' + environment: + - MRUBY_CONFIG=ci/gcc-clang + - CC=gcc + - CXX=g++ + - LD=gcc + - SKIP=check-executables-have-shebangs + working_dir: /app diff --git a/mruby/examples/mrbgems/cdata_extension_example/src/example.c b/mruby/examples/mrbgems/cdata_extension_example/src/example.c index ac5593e7..4be26489 100644 --- a/mruby/examples/mrbgems/cdata_extension_example/src/example.c +++ b/mruby/examples/mrbgems/cdata_extension_example/src/example.c @@ -35,7 +35,7 @@ mrb_foo_get_bar(mrb_state *mrb, mrb_value self) struct Foo *f; f = (struct Foo*)mrb_data_get_ptr(mrb, self, &mrb_foo_type); - if(f == NULL) { + if (f == NULL) { mrb_raise(mrb, E_RUNTIME_ERROR, "uninitialized data"); } @@ -49,7 +49,7 @@ mrb_foo_set_bar(mrb_state *mrb, mrb_value self) int v; f = (struct Foo*)mrb_data_get_ptr(mrb, self, &mrb_foo_type); - if(f == NULL) { + if (f == NULL) { mrb_raise(mrb, E_RUNTIME_ERROR, "uninitialized data"); } diff --git a/mruby/examples/mrbgems/mruby-YOUR-bigint/TODO-HINT.md b/mruby/examples/mrbgems/mruby-YOUR-bigint/TODO-HINT.md index 4027df96..d1877f51 100644 --- a/mruby/examples/mrbgems/mruby-YOUR-bigint/TODO-HINT.md +++ b/mruby/examples/mrbgems/mruby-YOUR-bigint/TODO-HINT.md @@ -10,7 +10,7 @@ The file structure in this example is as follows: +- mruby-YOUR-bigint/ <- Make this directory public if necessary. | Change the name of copied directory. | - +- TODO-HINT.md <- This file is currently viewing by you. + +- TODO-HINT.md <- You are currently viewing this file. | Remove this from copied directory. | +- core/ @@ -21,19 +21,19 @@ The file structure in this example is as follows: May be depended on by other GEMs. ``` -Implementors of own bigints should copy below this directory to another directory and do the following: +Implementors of their own bigints should copy below this directory to another directory and do the following: - Rewrite `spec.author`, `spec.license`, `spec.homepage` and `spec.summary` in `/mrbgem.rake` file to those of your own implementors. - Implement the respective functions in `/core/bigint.c`. - Define and use an object structure for `MRB_TT_BIGINT` type-tag. - It is recommended to use `mrb_static_assert_object_size()` to ensure that the size of the object structure is within 6 words. + It is recommended to use `mrb_static_assert_object_size()` to ensure that the size of the object structure is within six words. - Delete this file from the destination of the copy. If you wish to use it as an alternative to the `mruby-bigint` provided by mruby, please leave the GEM name in `/mrbgem.rake` as it is. This is an important factor when it is depended from other GEMs with `spec.add_dependency 'mruby-bigint'`. -The name of the top directory of GEM can be changed arbitrarily. -The name of the git repository can also be changed arbitrarily. +The name of the top directory of the GEM can be changed arbitrarily. +The name of the Git repository can also be changed arbitrarily. -Note that there is no need for an initialization function as there is in normal GEM. +Note that there is no need for an initialization function as there is in a normal GEM. If you need it, create a file `/src/bigint.c` for example, and implement the `mrb_mruby_bigint_gem_init()` function. diff --git a/mruby/include/mrbconf.h b/mruby/include/mrbconf.h index 1629a5c4..122eb2b0 100644 --- a/mruby/include/mrbconf.h +++ b/mruby/include/mrbconf.h @@ -176,8 +176,8 @@ #if defined(DISABLE_STDIO) || defined(MRB_DISABLE_STDIO) # define MRB_NO_STDIO #endif -#ifdef MRB_DISABLE_DIRECT_THREADING -# define MRB_NO_DIRECT_THREADING +#if defined(MRB_DISABLE_DIRECT_THREADING) || defined(MRB_NO_DIRECT_THREADING) +# define MRB_USE_VM_SWITCH_DISPATCH #endif #if defined(ENABLE_DEBUG) || defined(MRB_ENABLE_DEBUG_HOOK) # define MRB_USE_DEBUG_HOOK diff --git a/mruby/include/mruby.h b/mruby/include/mruby.h index 2d96b25e..5feb8d63 100644 --- a/mruby/include/mruby.h +++ b/mruby/include/mruby.h @@ -139,7 +139,7 @@ #endif /** - * MRuby C API entry point + * mruby C API entry point */ MRB_BEGIN_DECL @@ -420,7 +420,7 @@ MRB_API void mrb_prepend_module(mrb_state *mrb, struct RClass *cla, struct RClas * mrb_define_method(mrb, mrb->kernel_module, "example_method", example_method, MRB_ARGS_NONE()); * } * - * @param mrb The MRuby state reference. + * @param mrb The mruby state reference. * @param cla The class pointer where the method will be defined. * @param name The name of the method being defined. * @param func The function pointer to the method definition. @@ -448,7 +448,7 @@ MRB_API void mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, * foo = mrb_define_class(mrb, "Foo", mrb->object_class); * mrb_define_class_method(mrb, foo, "bar", bar_method, MRB_ARGS_NONE()); * } - * @param mrb The MRuby state reference. + * @param mrb The mruby state reference. * @param cla The class where the class method will be defined. * @param name The name of the class method being defined. * @param fun The function pointer to the class method definition. @@ -484,7 +484,7 @@ MRB_API void mrb_define_singleton_method_id(mrb_state *mrb, struct RObject *cla, * foo = mrb_define_module(mrb, "Foo"); * mrb_define_module_function(mrb, foo, "bar", bar_method, MRB_ARGS_NONE()); * } - * @param mrb The MRuby state reference. + * @param mrb The mruby state reference. * @param cla The module where the module function will be defined. * @param name The name of the module function being defined. * @param fun The function pointer to the module function definition. @@ -514,7 +514,7 @@ MRB_API void mrb_define_module_function_id(mrb_state *mrb, struct RClass *cla, m * mrb_value * mrb_example_gem_final(mrb_state* mrb){ * } - * @param mrb The MRuby state reference. + * @param mrb The mruby state reference. * @param cla A class or module the constant is defined in. * @param name The name of the constant being defined. * @param val The value for the constant. @@ -1017,7 +1017,7 @@ struct mrb_kwargs /** * Retrieve arguments from mrb_state. * - * @param mrb The current MRuby state. + * @param mrb The current mruby state. * @param format is a list of format specifiers * @param ... The passing variadic arguments must be a pointer of retrieving type. * @return the number of arguments retrieved. @@ -1248,7 +1248,7 @@ MRB_API mrb_state* mrb_open(void); MRB_API mrb_state* mrb_open_allocf(mrb_allocf f, void *ud); /** - * Create new mrb_state with just the MRuby core + * Create new mrb_state with just the mruby core * * @param f * Reference to the allocation function. @@ -1303,26 +1303,17 @@ MRB_API mrb_bool mrb_eql(mrb_state *mrb, mrb_value obj1, mrb_value obj2); /* mrb_cmp(mrb, obj1, obj2): 1:0:-1; -2 for error */ MRB_API mrb_int mrb_cmp(mrb_state *mrb, mrb_value obj1, mrb_value obj2); -MRB_INLINE int -mrb_gc_arena_save(mrb_state *mrb) -{ - return mrb->gc.arena_idx; -} - -MRB_INLINE void -mrb_gc_arena_restore(mrb_state *mrb, int idx) -{ - mrb->gc.arena_idx = idx; -} +#define mrb_gc_arena_save(mrb) ((mrb)->gc.arena_idx) +#define mrb_gc_arena_restore(mrb, idx) ((mrb)->gc.arena_idx = (idx)) MRB_API void mrb_garbage_collect(mrb_state*); MRB_API void mrb_full_gc(mrb_state*); -MRB_API void mrb_incremental_gc(mrb_state *); +MRB_API void mrb_incremental_gc(mrb_state*); MRB_API void mrb_gc_mark(mrb_state*,struct RBasic*); #define mrb_gc_mark_value(mrb,val) do {\ if (!mrb_immediate_p(val)) mrb_gc_mark((mrb), mrb_basic_ptr(val)); \ } while (0) -MRB_API void mrb_field_write_barrier(mrb_state *, struct RBasic*, struct RBasic*); +MRB_API void mrb_field_write_barrier(mrb_state*, struct RBasic*, struct RBasic*); #define mrb_field_write_barrier_value(mrb, obj, val) do{\ if (!mrb_immediate_p(val)) mrb_field_write_barrier((mrb), (obj), mrb_basic_ptr(val)); \ } while (0) @@ -1366,7 +1357,7 @@ MRB_API mrb_noreturn void mrb_name_error(mrb_state *mrb, mrb_sym id, const char MRB_API mrb_noreturn void mrb_frozen_error(mrb_state *mrb, void *frozen_obj); MRB_API mrb_noreturn void mrb_argnum_error(mrb_state *mrb, mrb_int argc, int min, int max); MRB_API void mrb_warn(mrb_state *mrb, const char *fmt, ...); -MRB_API mrb_noreturn void mrb_bug(mrb_state *mrb, const char *fmt, ...); +MRB_API mrb_noreturn void mrb_bug(mrb_state *mrb, const char *mesg); MRB_API void mrb_print_backtrace(mrb_state *mrb); MRB_API void mrb_print_error(mrb_state *mrb); /* function for `raisef` formatting */ @@ -1378,6 +1369,8 @@ MRB_API mrb_value mrb_vformat(mrb_state *mrb, const char *format, va_list ap); + exception objects obtained from those macros are local to mrb */ #define MRB_ERROR_SYM(sym) mrb_intern_lit(mrb, #sym) +#define E_EXCEPTION mrb->eException_class +#define E_STANDARD_ERROR mrb->eStandardError_class #define E_RUNTIME_ERROR mrb_exc_get_id(mrb, MRB_ERROR_SYM(RuntimeError)) #define E_TYPE_ERROR mrb_exc_get_id(mrb, MRB_ERROR_SYM(TypeError)) #define E_ZERODIV_ERROR mrb_exc_get_id(mrb, MRB_ERROR_SYM(ZeroDivisionError)) @@ -1436,12 +1429,8 @@ MRB_API mrb_value mrb_ensure_int_type(mrb_state *mrb, mrb_value val); /* string type checking (contrary to the name, it doesn't convert) */ MRB_API void mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t); - -MRB_INLINE void mrb_check_frozen(mrb_state *mrb, void *o) -{ - if (mrb_frozen_p((struct RBasic*)o)) mrb_frozen_error(mrb, o); -} - +MRB_API void mrb_check_frozen(mrb_state *mrb, void *); +MRB_API void mrb_check_frozen_value(mrb_state *mrb, mrb_value v); MRB_API void mrb_define_alias(mrb_state *mrb, struct RClass *c, const char *a, const char *b); MRB_API void mrb_define_alias_id(mrb_state *mrb, struct RClass *c, mrb_sym a, mrb_sym b); MRB_API const char *mrb_class_name(mrb_state *mrb, struct RClass* klass); diff --git a/mruby/include/mruby/class.h b/mruby/include/mruby/class.h index ff16f1ac..a3e1c0d1 100644 --- a/mruby/include/mruby/class.h +++ b/mruby/include/mruby/class.h @@ -26,6 +26,10 @@ struct RClass { MRB_INLINE struct RClass* mrb_class(mrb_state *mrb, mrb_value v) { + if (!mrb_immediate_p(v)) { + return mrb_obj_ptr(v)->c; + } + switch (mrb_type(v)) { case MRB_TT_FALSE: if (mrb_fixnum(v)) @@ -43,20 +47,18 @@ mrb_class(mrb_state *mrb, mrb_value v) #endif case MRB_TT_CPTR: return mrb->object_class; - case MRB_TT_ENV: - return NULL; default: - return mrb_obj_ptr(v)->c; + return NULL; } } /* flags: - 20: frozen - 19: is_prepended - 18: is_origin - 17: is_inherited (used by method cache) - 16: unused - 0-15: instance type + 20: frozen + 19: is_prepended + 18: is_origin + 17: is_inherited (used by method cache) + 6-16: unused + 0-5: instance type */ #define MRB_FL_CLASS_IS_PREPENDED (1 << 19) #define MRB_FL_CLASS_IS_ORIGIN (1 << 18) @@ -69,7 +71,7 @@ mrb_class(mrb_state *mrb, mrb_value v) }\ } while (0) #define MRB_FL_CLASS_IS_INHERITED (1 << 17) -#define MRB_INSTANCE_TT_MASK (0xFF) +#define MRB_INSTANCE_TT_MASK (0x1F) #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) diff --git a/mruby/include/mruby/common.h b/mruby/include/mruby/common.h index 59214d3c..fd5c1102 100644 --- a/mruby/include/mruby/common.h +++ b/mruby/include/mruby/common.h @@ -67,7 +67,7 @@ MRB_BEGIN_DECL #endif #define MRB_INLINE static inline -/** Declare a public MRuby API function. */ +/** Declare a public mruby API function. */ #ifndef MRB_API #if defined(MRB_BUILD_AS_DLL) #if defined(MRB_CORE) || defined(MRB_LIB) diff --git a/mruby/include/mruby/compile.h b/mruby/include/mruby/compile.h index 70cf9a93..84f09e3e 100644 --- a/mruby/include/mruby/compile.h +++ b/mruby/include/mruby/compile.h @@ -10,7 +10,7 @@ #include "common.h" /** - * MRuby Compiler + * mruby Compiler */ MRB_BEGIN_DECL diff --git a/mruby/include/mruby/data.h b/mruby/include/mruby/data.h index 7bdf1c34..a64301a5 100644 --- a/mruby/include/mruby/data.h +++ b/mruby/include/mruby/data.h @@ -41,12 +41,12 @@ MRB_API struct RData *mrb_data_object_alloc(mrb_state *mrb, struct RClass* klass #define Data_Make_Struct(mrb,klass,strct,type,sval,data_obj) do { \ (data_obj) = Data_Wrap_Struct(mrb,klass,type,NULL);\ - (sval) = (strct *)mrb_malloc(mrb, sizeof(strct)); \ + (sval) = (strct*)mrb_malloc(mrb, sizeof(strct)); \ { static const strct zero = { 0 }; *(sval) = zero; };\ (data_obj)->data = (sval);\ } while (0) -#define RDATA(obj) ((struct RData *)(mrb_ptr(obj))) +#define RDATA(obj) ((struct RData*)(mrb_ptr(obj))) #define DATA_PTR(d) (RDATA(d)->data) #define DATA_TYPE(d) (RDATA(d)->type) MRB_API void mrb_data_check_type(mrb_state *mrb, mrb_value, const mrb_data_type*); diff --git a/mruby/include/mruby/debug.h b/mruby/include/mruby/debug.h index 4a62cce4..f0409351 100644 --- a/mruby/include/mruby/debug.h +++ b/mruby/include/mruby/debug.h @@ -10,7 +10,7 @@ #include "common.h" /** - * MRuby Debugging. + * mruby Debugging. */ MRB_BEGIN_DECL @@ -46,7 +46,7 @@ typedef struct mrb_irep_debug_info { } mrb_irep_debug_info; /* - * get line from irep's debug info and program counter + * get filename from irep's debug info and program counter * @return returns NULL if not found */ MRB_API const char *mrb_debug_get_filename(mrb_state *mrb, const mrb_irep *irep, uint32_t pc); @@ -57,6 +57,12 @@ MRB_API const char *mrb_debug_get_filename(mrb_state *mrb, const mrb_irep *irep, */ MRB_API int32_t mrb_debug_get_line(mrb_state *mrb, const mrb_irep *irep, uint32_t pc); +/* + * get line and filename from irep's debug info and program counter + * @return returns FALSE if not found + */ +MRB_API mrb_bool mrb_debug_get_position(mrb_state *mrb, const mrb_irep *irep, uint32_t pc, int32_t *lp, const char **fp); + MRB_API mrb_irep_debug_info *mrb_debug_info_alloc(mrb_state *mrb, mrb_irep *irep); MRB_API mrb_irep_debug_info_file *mrb_debug_info_append_file( mrb_state *mrb, mrb_irep_debug_info *info, diff --git a/mruby/include/mruby/endian.h b/mruby/include/mruby/endian.h index 477f3bc9..940c47ea 100644 --- a/mruby/include/mruby/endian.h +++ b/mruby/include/mruby/endian.h @@ -34,7 +34,7 @@ static inline int check_little_endian(void) { unsigned int n = 1; - return (*(unsigned char *)&n == 1); + return (*(unsigned char*)&n == 1); } # define littleendian check_little_endian() #endif diff --git a/mruby/include/mruby/error.h b/mruby/include/mruby/error.h index ccf2cdb6..5f7ec43b 100644 --- a/mruby/include/mruby/error.h +++ b/mruby/include/mruby/error.h @@ -10,7 +10,7 @@ #include "common.h" /** - * MRuby error handling. + * mruby error handling. */ MRB_BEGIN_DECL @@ -34,12 +34,8 @@ struct RException { 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)) -MRB_API mrb_value mrb_make_exception(mrb_state *mrb, mrb_int argc, const mrb_value *argv); 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 */ -MRB_API mrb_value mrb_f_raise(mrb_state*, mrb_value); - #if defined(MRB_64BIT) || defined(MRB_USE_FLOAT32) || defined(MRB_NAN_BOXING) || defined(MRB_WORD_BOXING) struct RBreak { MRB_OBJECT_HEADER; @@ -74,6 +70,15 @@ mrb_break_value_set(struct RBreak *brk, mrb_value val) #define mrb_break_proc_get(brk) ((brk)->proc) #define mrb_break_proc_set(brk, p) ((brk)->proc = p) +/** + * Error check + * + */ +/* clear error status in the mrb_state structure */ +MRB_API void mrb_clear_error(mrb_state *mrb); +/* returns TRUE if error in the previous call; internally calls mrb_clear_error() */ +MRB_API mrb_bool mrb_check_error(mrb_state *mrb); + /** * Protect * diff --git a/mruby/include/mruby/gc.h b/mruby/include/mruby/gc.h index ba56cefd..ab50e08a 100644 --- a/mruby/include/mruby/gc.h +++ b/mruby/include/mruby/gc.h @@ -41,48 +41,37 @@ typedef enum { #pragma warning(disable : 4200) #endif -typedef struct mrb_heap_page { - struct RBasic *freelist; - struct mrb_heap_page *prev; - struct mrb_heap_page *next; - struct mrb_heap_page *free_next; - struct mrb_heap_page *free_prev; - mrb_bool old:1; - /* Flexible array members area a C99 feature, not C++ compatible */ - /* void* objects[]; */ -} mrb_heap_page; - #ifdef _MSC_VER #pragma warning(pop) #endif typedef struct mrb_gc { - mrb_heap_page *heaps; /* heaps for GC */ - mrb_heap_page *sweeps; - mrb_heap_page *free_heaps; - size_t live; /* count of live objects */ + struct mrb_heap_page *heaps; /* all heaps pages */ + struct mrb_heap_page *free_heaps;/* heaps for allocation */ + struct mrb_heap_page *sweeps; /* page where sweep starts */ + struct RBasic *gray_list; /* list of gray objects to be traversed incrementally */ + struct RBasic *atomic_gray_list; /* list of objects to be traversed atomically */ + size_t live; /* count of live objects */ + size_t live_after_mark; /* old generation objects */ + size_t threshold; /* threshold to start GC */ + size_t oldgen_threshold; /* threshold to kick major GC */ + mrb_gc_state state; /* current state of gc */ + int interval_ratio; + int step_ratio; + int current_white_part :2; /* make white object by white_part */ + mrb_bool iterating :1; /* currently iterating over objects */ + mrb_bool disabled :1; /* GC disabled */ + mrb_bool generational :1; /* generational GC mode */ + mrb_bool full :1; /* major GC mode */ + mrb_bool out_of_memory :1; /* out-of-memory error occurred */ + #ifdef MRB_GC_FIXED_ARENA struct RBasic *arena[MRB_GC_ARENA_SIZE]; /* GC protection array */ #else struct RBasic **arena; /* GC protection array */ - int arena_capa; + int arena_capa; /* size of protection array */ #endif int arena_idx; - - mrb_gc_state state; /* state of gc */ - int current_white_part; /* make white object by white_part */ - struct RBasic *gray_list; /* list of gray objects to be traversed incrementally */ - struct RBasic *atomic_gray_list; /* list of objects to be traversed atomically */ - size_t live_after_mark; - size_t threshold; - int interval_ratio; - int step_ratio; - mrb_bool iterating :1; - mrb_bool disabled :1; - mrb_bool full :1; - mrb_bool generational :1; - mrb_bool out_of_memory :1; - size_t majorgc_old_threshold; } mrb_gc; MRB_API mrb_bool mrb_object_dead_p(struct mrb_state *mrb, struct RBasic *object); diff --git a/mruby/include/mruby/internal.h b/mruby/include/mruby/internal.h index db64fd38..37c6fa1f 100644 --- a/mruby/include/mruby/internal.h +++ b/mruby/include/mruby/internal.h @@ -12,6 +12,8 @@ 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 +mrb_bool mrb_inspect_recursive_p(mrb_state *mrb, mrb_value self); + #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); @@ -23,11 +25,16 @@ mrb_value mrb_mod_to_s(mrb_state *, mrb_value); void mrb_method_added(mrb_state *mrb, struct RClass *c, mrb_sym mid); mrb_noreturn void mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args); mrb_method_t mrb_vm_find_method(mrb_state *mrb, struct RClass *c, struct RClass **cp, mrb_sym mid); +mrb_value mrb_mod_const_missing(mrb_state *mrb, mrb_value mod); +mrb_value mrb_const_missing(mrb_state *mrb, mrb_value mod, mrb_sym sym); +size_t mrb_class_mt_memsize(mrb_state*, struct RClass*); #endif +mrb_value mrb_obj_equal_m(mrb_state *mrb, mrb_value); + /* 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); +size_t mrb_packed_int_encode(uint32_t num, uint8_t *p); uint32_t mrb_packed_int_decode(const uint8_t *p, const uint8_t **newpos); /* dump */ @@ -51,6 +58,8 @@ 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); +mrb_value mrb_f_raise(mrb_state*, mrb_value); +mrb_value mrb_make_exception(mrb_state *mrb, mrb_value exc, mrb_value mesg); /* gc */ void mrb_gc_mark_mt(mrb_state*, struct RClass*); @@ -89,6 +98,9 @@ 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); mrb_noreturn void mrb_int_zerodiv(mrb_state *mrb); mrb_noreturn void mrb_int_overflow(mrb_state *mrb, const char *reason); +#ifndef MRB_NO_FLOAT +void mrb_check_num_exact(mrb_state *mrb, mrb_float num); +#endif #ifdef MRB_USE_COMPLEX mrb_value mrb_complex_new(mrb_state *mrb, mrb_float x, mrb_float y); @@ -112,6 +124,11 @@ 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); struct REnv *mrb_env_new(mrb_state *mrb, struct mrb_context *c, mrb_callinfo *ci, int nstacks, mrb_value *stack, struct RClass *tc); +void mrb_proc_merge_lvar(mrb_state *mrb, mrb_irep *irep, struct REnv *env, int num, const mrb_sym *lv, const mrb_value *stack); +mrb_value mrb_proc_local_variables(mrb_state *mrb, const struct RProc *proc); +const struct RProc *mrb_proc_get_caller(mrb_state *mrb, struct REnv **env); +mrb_value mrb_proc_get_self(mrb_state *mrb, struct RProc *p, struct RClass **target_class_p); +mrb_bool mrb_proc_eql(mrb_state *mrb, mrb_value self, mrb_value other); #endif /* range */ @@ -171,21 +188,28 @@ mrb_value mrb_f_send(mrb_state *mrb, mrb_value self); #ifdef MRB_USE_BIGINT mrb_value mrb_bint_new_int(mrb_state *mrb, mrb_int x); +#ifdef MRB_INT64 +#define mrb_bint_new_int64(mrb,x) mrb_bint_new_int((mrb),(mrb_int)(x)) +#else +mrb_value mrb_bint_new_int64(mrb_state *mrb, int64_t x); +#endif +mrb_value mrb_bint_new_uint64(mrb_state *mrb, uint64_t 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_add_d(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_bint_sub_d(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_powm(mrb_state *mrb, mrb_value x, mrb_value 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); @@ -198,6 +222,12 @@ 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); +#ifdef MRB_INT64 +#define mrb_bint_as_int64(mrb, x) mrb_bint_as_int((mrb), (x)) +#else +int64_t mrb_bint_as_int64(mrb_state *mrb, mrb_value x); +#endif +uint64_t mrb_bint_as_uint64(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); void mrb_bint_copy(mrb_state *mrb, mrb_value x, mrb_value y); diff --git a/mruby/include/mruby/khash.h b/mruby/include/mruby/khash.h index 1fb6eecb..c413ebbb 100644 --- a/mruby/include/mruby/khash.h +++ b/mruby/include/mruby/khash.h @@ -102,8 +102,8 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len) uint8_t *p = (uint8_t*)mrb_malloc_simple(mrb, sizeof(uint8_t)*sz/4+len*sz); \ if (!p) { return 1; } \ h->size = 0; \ - h->keys = (khkey_t *)p; \ - h->vals = kh_is_map ? (khval_t *)(p+sizeof(khkey_t)*sz) : NULL; \ + h->keys = (khkey_t*)p; \ + h->vals = kh_is_map ? (khval_t*)(p+sizeof(khkey_t)*sz) : NULL; \ h->ed_flags = p+len*sz; \ kh_fill_flags(h->ed_flags, 0xaa, sz/4); \ return 0; \ @@ -171,7 +171,7 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len) hh.n_buckets = new_n_buckets; \ kh_alloc_##name(mrb, &hh); \ /* relocate */ \ - for (i=0 ; ic->cibase`. + * + * #include + * #include + * #include + * + * int + * main(int argc, char **argv) + * { + * mrb_state *mrb; + * mrbc_context *cxt; + * mrb_value blk, ret; + * + * mrb = mrb_open(); + * cxt = mrbc_context_new(mrb); + * blk = mrb_load_string_cxt(mrb, "x, y, z = 1, 2, 3; proc { [x, y, z] }", cxt); + * mrb_vm_ci_env_clear(mrb, mrb->c->cibase); + * mrb_load_string_cxt(mrb, "x, y, z = 4, 5, 6", cxt); + * ret = mrb_funcall(mrb, blk, "call", 0); + * mrb_p(mrb, ret); // => [1, 2, 3] + * // => [4, 5, 6] if `mrb_vm_ci_env_clear()` is commented out + * mrbc_context_free(mrb, cxt); + * mrb_close(mrb); + * + * return 0; + * } + * + * The top-level local variable names stored in `mrbc_context` are retained. + * Use also `mrbc_cleanup_local_variables()` at the same time, if necessary. + */ +MRB_API void mrb_vm_ci_env_clear(mrb_state *mrb, mrb_callinfo *ci); + void mrb_vm_ci_proc_set(mrb_callinfo *ci, const struct RProc *p); struct RClass * mrb_vm_ci_target_class(const mrb_callinfo *ci); void mrb_vm_ci_target_class_set(mrb_callinfo *ci, struct RClass *tc); diff --git a/mruby/include/mruby/value.h b/mruby/include/mruby/value.h index 6666a9c1..71cdaca3 100644 --- a/mruby/include/mruby/value.h +++ b/mruby/include/mruby/value.h @@ -10,7 +10,7 @@ #include "common.h" /* - * MRuby Value definition functions and macros. + * mruby Value definition functions and macros. */ MRB_BEGIN_DECL @@ -125,7 +125,7 @@ MRB_API int mrb_msvc_snprintf(char *s, size_t n, const char *format, ...); # define isinf(n) (!_finite(n) && !_isnan(n)) # define signbit(n) (_copysign(1.0, (n)) < 0.0) static const unsigned int IEEE754_INFINITY_BITS_SINGLE = 0x7F800000; -# define INFINITY (*(float *)&IEEE754_INFINITY_BITS_SINGLE) +# define INFINITY (*(float*)&IEEE754_INFINITY_BITS_SINGLE) # define NAN ((float)(INFINITY - INFINITY)) # endif #endif @@ -186,7 +186,7 @@ MRB_VTYPE_FOREACH(MRB_VTYPE_TYPEDEF) /** * @abstract - * MRuby value boxing. + * mruby value boxing. * * Actual implementation depends on configured boxing type. * diff --git a/mruby/lib/mruby/build.rb b/mruby/lib/mruby/build.rb index 4925cee3..9dff12cf 100644 --- a/mruby/lib/mruby/build.rb +++ b/mruby/lib/mruby/build.rb @@ -1,12 +1,16 @@ require "mruby/core_ext" require "mruby/build/load_gems" require "mruby/build/command" +autoload :Find, "find" module MRuby autoload :Gem, "mruby/gem" autoload :Lockfile, "mruby/lockfile" autoload :Presym, "mruby/presym" + INSTALL_PREFIX = ENV['PREFIX'] || ENV['INSTALL_PREFIX'] || '/usr/local' + INSTALL_DESTDIR = ENV['DESTDIR'] || '' + class << self def targets @targets ||= {} @@ -97,6 +101,7 @@ def initialize(name='host', build_dir=nil, internal: false, &block) @file_separator = '/' @build_dir = "#{build_dir}/#{@name}" @gem_clone_dir = "#{build_dir}/repos/#{@name}" + @install_prefix = nil @defines = [] @cc = Command::Compiler.new(self, %w(.c), label: "CC") @cxx = Command::Compiler.new(self, %w(.cc .cxx .cpp), label: "CXX") @@ -162,9 +167,7 @@ def debug_enabled? def enable_debug compilers.each do |c| c.defines += %w(MRB_DEBUG) - if toolchains.any? { |toolchain| toolchain == "gcc" } - c.flags += %w(-g3 -O0) - end + c.setup_debug(self) end @mrbc.compile_options += ' -g' @@ -370,14 +373,35 @@ def define_rules end end - def define_installer(src) - dst = "#{self.class.install_dir}/#{File.basename(src)}" + def define_installer_outline(src, dst) file dst => src do - install_D src, dst + _pp "GEN", src.relative_path, dst.relative_path + mkdir_p(File.dirname(dst)) + yield dst end dst end + if ENV['OS'] == 'Windows_NT' + def define_installer(src) + dst = "#{self.class.install_dir}/#{File.basename(src)}".pathmap("%X.bat") + define_installer_outline(src, dst) do + File.write dst, <<~BATCHFILE + @echo off + call "#{File.expand_path(src)}" %* + BATCHFILE + end + end + else + def define_installer(src) + dst = "#{self.class.install_dir}/#{File.basename(src)}" + define_installer_outline(src, dst) do + File.unlink(dst) rescue nil + File.symlink(File.expand_path(src), dst) + end + end + end + def define_installer_if_needed(bin) exe = exefile("#{build_dir}/bin/#{bin}") host? ? define_installer(exe) : exe @@ -440,10 +464,10 @@ def run_test def run_bintest puts ">>> Bintest #{name} <<<" targets = @gems.select { |v| File.directory? "#{v.dir}/bintest" }.map { |v| filename v.dir } - targets << filename(".") if File.directory? "./bintest" mrbc = @gems["mruby-bin-mrbc"] ? exefile("#{@build_dir}/bin/mrbc") : mrbcfile env = {"BUILD_DIR" => @build_dir, "MRBCFILE" => mrbc} - sh env, "ruby test/bintest.rb#{verbose_flag} #{targets.join ' '}" + bintest = File.join(MRUBY_ROOT, "test/bintest.rb") + sh env, "ruby #{bintest}#{verbose_flag} #{targets.join ' '}" end def print_build_summary @@ -485,6 +509,29 @@ def internal? @internal end + def each_header_files(&block) + return to_enum(__method__) unless block + + basedir = File.join(MRUBY_ROOT, "include") + Find.find(basedir) do |d| + next unless File.file? d + yield d + end + + @gems.each { |g| g.each_header_files(&block) } + + self + end + + def install_prefix + @install_prefix || (self.name == "host" ? MRuby::INSTALL_PREFIX : + File.join(MRuby::INSTALL_PREFIX, "mruby/#{self.name}")) + end + + def install_prefix=(dir) + @install_prefix = dir&.to_s + end + protected attr_writer :presym @@ -554,7 +601,6 @@ def run_test def run_bintest puts ">>> Bintest #{name} <<<" targets = @gems.select { |v| File.directory? "#{v.dir}/bintest" }.map { |v| filename v.dir } - targets << filename(".") if File.directory? "./bintest" mrbc = @gems["mruby-bin-mrbc"] ? exefile("#{@build_dir}/bin/mrbc") : mrbcfile emulator = @test_runner.command @@ -565,7 +611,8 @@ def run_bintest "MRBCFILE" => mrbc, "EMULATOR" => @test_runner.emulator, } - sh env, "ruby test/bintest.rb#{verbose_flag} #{targets.join ' '}" + bintest = File.join(MRUBY_ROOT, "test/bintest.rb") + sh env, "ruby #{bintest}#{verbose_flag} #{targets.join ' '}" end protected diff --git a/mruby/lib/mruby/build/command.rb b/mruby/lib/mruby/build/command.rb index c8a3037e..e40b1553 100644 --- a/mruby/lib/mruby/build/command.rb +++ b/mruby/lib/mruby/build/command.rb @@ -99,12 +99,16 @@ def define_rules(build_dir, source_dir='', out_ext=build.exts.object) gemrake = File.join(source_dir, "mrbgem.rake") rakedep = File.exist?(gemrake) ? [ gemrake ] : [] - if build_dir.include? "mrbgems/" + bd = build_dir + if bd.start_with?(MRUBY_ROOT) + bd = bd.sub(MRUBY_ROOT, '') + end + if bd.include? "mrbgems/" generated_file_matcher = Regexp.new("^#{Regexp.escape build_dir}/(?!mrbc/)(.*)#{Regexp.escape out_ext}$") else generated_file_matcher = Regexp.new("^#{Regexp.escape build_dir}/(?!mrbc/|mrbgems/.+/)(.*)#{Regexp.escape out_ext}$") end - source_exts.each do |ext, compile| + source_exts.each do |ext| rule generated_file_matcher => [ proc { |file| file.sub(generated_file_matcher, "#{source_dir}/\\1#{ext}") @@ -129,6 +133,12 @@ def define_rules(build_dir, source_dir='', out_ext=build.exts.object) end end + # This method can be redefined as a singleton method where appropriate. + # Manipulate `flags`, `include_paths` and/or more if necessary. + def setup_debug(conf) + nil + end + private # @@ -335,7 +345,7 @@ def run(out, infiles, funcname, cdump: true, static: false) opt << " -s" if static cmd = %["#{filename @command}" #{opt} #{filename(infiles).map{|f| %["#{f}"]}.join(' ')}] puts cmd if Rake.verbose - IO.popen(cmd, 'r+') do |io| + IO.popen(cmd, 'r') do |io| out.puts io.read end # if mrbc execution fail, drop the file diff --git a/mruby/lib/mruby/core_ext.rb b/mruby/lib/mruby/core_ext.rb index 1ad528c2..ac273764 100644 --- a/mruby/lib/mruby/core_ext.rb +++ b/mruby/lib/mruby/core_ext.rb @@ -22,6 +22,27 @@ def relative_path def remove_leading_parents Pathname.new(".#{Pathname.new("/#{self}").cleanpath}").cleanpath.to_s end + + def replace_prefix_by(dirmap) + [self].replace_prefix_by(dirmap)[0] + end +end + +class Array + # Replace the prefix of each string that is a file path that contains in its own array. + # + # dirmap is a hash whose elements are `{ "path/to/old-prefix" => "path/to/new-prefix", ... }`. + # If it does not match any element of dirmap, the file path is not replaced. + def replace_prefix_by(dirmap) + dirmap = dirmap.map { |older, newer| [File.join(older, "/"), File.join(newer, "/")] } + dirmap.sort! + dirmap.reverse! + self.flatten.map do |e| + map = dirmap.find { |older, newer| e.start_with?(older) } + e = e.sub(map[0], map[1]) if map + e + end + end end def install_D(src, dst) diff --git a/mruby/lib/mruby/gem.rb b/mruby/lib/mruby/gem.rb index 64c6f3de..35aa2bd5 100644 --- a/mruby/lib/mruby/gem.rb +++ b/mruby/lib/mruby/gem.rb @@ -36,6 +36,7 @@ class Specification attr_accessor :export_include_paths attr_reader :generate_functions + attr_writer :skip_test attr_block MRuby::Build::COMMANDS @@ -62,6 +63,7 @@ def setup @test_preload = nil # 'test/assert.rb' @test_args = {} + @skip_test = false @bins = [] @cdump = true @@ -87,6 +89,10 @@ def setup build.locks[repo_url]['version'] = version if repo_url end + def skip_test? + @skip_test + end + def setup_compilers (core? ? [@cc, *(@cxx if build.cxx_exception_enabled?)] : compilers).each do |compiler| compiler.define_rules build_dir, @dir, @build.exts.presym_preprocessed if build.presym_enabled? @@ -209,7 +215,6 @@ def generate_gem_init(fname) f.puts %Q[void mrb_#{funcname}_gem_final(mrb_state *mrb);] f.puts %Q[] f.puts %Q[void GENERATED_TMP_mrb_#{funcname}_gem_init(mrb_state *mrb) {] - f.puts %Q[ int ai = mrb_gc_arena_save(mrb);] f.puts %Q[ gem_mrblib_#{funcname}_proc_init_syms(mrb);] if !rbfiles.empty? && cdump? f.puts %Q[ mrb_#{funcname}_gem_init(mrb);] if objs != [objfile("#{build_dir}/gem_init")] unless rbfiles.empty? @@ -218,16 +223,7 @@ def generate_gem_init(fname) else f.puts %Q[ mrb_load_irep(mrb, gem_mrblib_irep_#{funcname});] end - f.puts %Q[ if (mrb->exc) {] - f.puts %Q[ mrb_print_error(mrb);] - f.puts %Q[ mrb_close(mrb);] - f.puts %Q[ exit(EXIT_FAILURE);] - f.puts %Q[ }] - f.puts %Q[ struct REnv *e = mrb_vm_ci_env(mrb->c->cibase);] - f.puts %Q[ mrb_vm_ci_env_set(mrb->c->cibase, NULL);] - f.puts %Q[ mrb_env_unshare(mrb, e, FALSE);] end - f.puts %Q[ mrb_gc_arena_restore(mrb, ai);] f.puts %Q[}] f.puts %Q[] f.puts %Q[void GENERATED_TMP_mrb_#{funcname}_gem_final(mrb_state *mrb) {] @@ -241,6 +237,8 @@ def print_gem_comment(f) f.puts %Q[ * This file is loading the irep] f.puts %Q[ * Ruby GEM code.] f.puts %Q[ *] + f.puts %Q[ * This file was generated by mruby/#{__FILE__.relative_path_from(MRUBY_ROOT)}.] + f.puts %Q[ *] f.puts %Q[ * IMPORTANT:] f.puts %Q[ * This file was generated!] f.puts %Q[ * All manual changes will get lost.] @@ -292,6 +290,19 @@ def version_ok?(req_versions) end end.all? end + + def each_header_files(&block) + return to_enum(__method__) unless block + + self.export_include_paths.flatten.uniq.compact.each do |dir| + Find.find(dir) do |d| + next unless File.file? d + yield d + end + end + + self + end end # Specification class Version diff --git a/mruby/lib/mruby/presym.rb b/mruby/lib/mruby/presym.rb index 7f74569f..8ade2480 100644 --- a/mruby/lib/mruby/presym.rb +++ b/mruby/lib/mruby/presym.rb @@ -46,6 +46,18 @@ class Presym C_STR_LITERAL_RE = /"(?:[^\\\"]|\\.)*"/ + ESCAPE_SEQUENCE_MAP = { + "a" => "\a", + "b" => "\b", + "e" => "\e", + "f" => "\f", + "n" => "\n", + "r" => "\r", + "t" => "\t", + "v" => "\v", + } + ESCAPE_SEQUENCE_MAP.keys.each { |k| ESCAPE_SEQUENCE_MAP[ESCAPE_SEQUENCE_MAP[k]] = k } + def initialize(build) @build = build end @@ -93,7 +105,18 @@ def write_table_header(presyms) f.puts "};" f.puts f.puts "static const char * const presym_name_table[] = {" - presyms.each{|sym| f.puts %| "#{sym}",|} + presyms.each do |sym| + sym = sym.gsub(/([\x01-\x1f\x7f-\xff])|("|\\)/n) { + case + when $1 + e = ESCAPE_SEQUENCE_MAP[$1] + e ? "\\#{e}" : '\\x%02x""' % $1.ord + when $2 + "\\#$2" + end + } + f.puts %| "#{sym}",| + end f.puts "};" end end @@ -119,7 +142,20 @@ def table_header_path def read_preprocessed(presym_hash, path) File.binread(path).scan(/<@! (.*?) !@>/) do |part,| literals = part.scan(C_STR_LITERAL_RE) - presym_hash[literals.map{|l| l[1..-2]}.join] = true unless literals.empty? + unless literals.empty? + literals = literals.map{|l| l[1..-2]} + literals.each do |e| + e.gsub!(/\\x([0-9A-Fa-f]{1,2})|\\(0[0-7]{,3})|\\([abefnrtv])|\\(.)/) do + case + when $1; $1.hex.chr(Encoding::BINARY) + when $2; $2.oct.chr(Encoding::BINARY) + when $3; ESCAPE_SEQUENCE_MAP[$3] + when $4; $4 + end + end + end + presym_hash[literals.join] = true + end end end diff --git a/mruby/mrbgems/default.gembox b/mruby/mrbgems/default.gembox index ae2de2ac..1143b198 100644 --- a/mruby/mrbgems/default.gembox +++ b/mruby/mrbgems/default.gembox @@ -8,6 +8,9 @@ MRuby::GemBox.new do |conf| # Generate mrbc command conf.gem :core => "mruby-bin-mrbc" + # Generate mrdb command + conf.gem :core => "mruby-bin-debugger" + # Generate mirb command conf.gem :core => "mruby-bin-mirb" diff --git a/mruby/mrbgems/mruby-array-ext/src/array.c b/mruby/mrbgems/mruby-array-ext/src/array.c index 385ad511..02e7834b 100644 --- a/mruby/mrbgems/mruby-array-ext/src/array.c +++ b/mruby/mrbgems/mruby-array-ext/src/array.c @@ -27,7 +27,7 @@ */ static mrb_value -mrb_ary_assoc(mrb_state *mrb, mrb_value ary) +ary_assoc(mrb_state *mrb, mrb_value ary) { mrb_int i; mrb_value v; @@ -57,7 +57,7 @@ mrb_ary_assoc(mrb_state *mrb, mrb_value ary) */ static mrb_value -mrb_ary_rassoc(mrb_state *mrb, mrb_value ary) +ary_rassoc(mrb_state *mrb, mrb_value ary) { mrb_int i; mrb_value v; @@ -87,10 +87,9 @@ mrb_ary_rassoc(mrb_state *mrb, mrb_value ary) */ static mrb_value -mrb_ary_at(mrb_state *mrb, mrb_value ary) +ary_at(mrb_state *mrb, mrb_value ary) { - mrb_int pos; - mrb_get_args(mrb, "i", &pos); + mrb_int pos = mrb_as_int(mrb, mrb_get_arg1(mrb)); return mrb_ary_entry(ary, pos); } @@ -102,7 +101,7 @@ ary_ref(mrb_state *mrb, mrb_value ary, mrb_int n) } static mrb_value -mrb_ary_values_at(mrb_state *mrb, mrb_value self) +ary_values_at(mrb_state *mrb, mrb_value self) { mrb_int argc = mrb_get_argc(mrb); const mrb_value *argv = mrb_get_argv(mrb); @@ -134,7 +133,7 @@ mrb_value mrb_ary_delete_at(mrb_state *mrb, mrb_value self); */ static mrb_value -mrb_ary_slice_bang(mrb_state *mrb, mrb_value self) +ary_slice_bang(mrb_state *mrb, mrb_value self) { struct RArray *a = mrb_ary_ptr(self); mrb_int i, j, len, alen; @@ -187,7 +186,7 @@ mrb_ary_slice_bang(mrb_state *mrb, mrb_value self) */ static mrb_value -mrb_ary_compact(mrb_state *mrb, mrb_value self) +ary_compact(mrb_state *mrb, mrb_value self) { mrb_value ary = mrb_ary_new(mrb); mrb_int len = RARRAY_LEN(self); @@ -213,7 +212,7 @@ mrb_ary_compact(mrb_state *mrb, mrb_value self) * [ "a", "b", "c" ].compact! #=> nil */ static mrb_value -mrb_ary_compact_bang(mrb_state *mrb, mrb_value self) +ary_compact_bang(mrb_state *mrb, mrb_value self) { struct RArray *a = mrb_ary_ptr(self); mrb_int i, j = 0; @@ -250,7 +249,7 @@ mrb_ary_compact_bang(mrb_state *mrb, mrb_value self) * a.rotate(-3) #=> ["b", "c", "d", "a"] */ static mrb_value -mrb_ary_rotate(mrb_state *mrb, mrb_value self) +ary_rotate(mrb_state *mrb, mrb_value self) { mrb_int count=1; mrb_get_args(mrb, "|i", &count); @@ -301,7 +300,7 @@ rev(mrb_value *p, mrb_int beg, mrb_int end) * a.rotate!(-3) #=> ["a", "b", "c", "d"] */ static mrb_value -mrb_ary_rotate_bang(mrb_state *mrb, mrb_value self) +ary_rotate_bang(mrb_state *mrb, mrb_value self) { mrb_int count=1; mrb_get_args(mrb, "|i", &count); @@ -347,15 +346,15 @@ mrb_mruby_array_ext_gem_init(mrb_state* mrb) { struct RClass * a = mrb->array_class; - mrb_define_method(mrb, a, "assoc", mrb_ary_assoc, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, a, "at", mrb_ary_at, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, a, "rassoc", mrb_ary_rassoc, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, a, "values_at", mrb_ary_values_at, MRB_ARGS_ANY()); - mrb_define_method(mrb, a, "slice!", mrb_ary_slice_bang, MRB_ARGS_ARG(1,1)); - mrb_define_method(mrb, a, "compact", mrb_ary_compact, MRB_ARGS_NONE()); - mrb_define_method(mrb, a, "compact!", mrb_ary_compact_bang, MRB_ARGS_NONE()); - mrb_define_method(mrb, a, "rotate", mrb_ary_rotate, MRB_ARGS_OPT(1)); - mrb_define_method(mrb, a, "rotate!", mrb_ary_rotate_bang, MRB_ARGS_OPT(1)); + mrb_define_method(mrb, a, "assoc", ary_assoc, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, a, "at", ary_at, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, a, "rassoc", ary_rassoc, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, a, "values_at", ary_values_at, MRB_ARGS_ANY()); + mrb_define_method(mrb, a, "slice!", ary_slice_bang, MRB_ARGS_ARG(1,1)); + mrb_define_method(mrb, a, "compact", ary_compact, MRB_ARGS_NONE()); + mrb_define_method(mrb, a, "compact!", ary_compact_bang, MRB_ARGS_NONE()); + mrb_define_method(mrb, a, "rotate", ary_rotate, MRB_ARGS_OPT(1)); + mrb_define_method(mrb, a, "rotate!", ary_rotate_bang, MRB_ARGS_OPT(1)); } void diff --git a/mruby/mrbgems/mruby-bigint/core/bigint.c b/mruby/mrbgems/mruby-bigint/core/bigint.c index 5c757729..97f54547 100644 --- a/mruby/mrbgems/mruby-bigint/core/bigint.c +++ b/mruby/mrbgems/mruby-bigint/core/bigint.c @@ -78,7 +78,7 @@ mpz_set_int(mrb_state *mrb, mpz_t *y, mrb_int v) y->sn = 1; u = v; } - if (v < 0) { + else /* if (v < 0) */ { y->sn = -1; if (v == MRB_INT_MIN) u = v; else u = -v; @@ -97,6 +97,39 @@ mpz_set_int(mrb_state *mrb, mpz_t *y, mrb_int v) } } +static void +mpz_set_uint64(mrb_state *mrb, mpz_t *y, uint64_t u) +{ + const size_t len = sizeof(uint64_t) / sizeof(mp_limb); + + y->sn = (u != 0); + mpz_realloc(mrb, y, len); + for (size_t i=0; ip[i++] = (mp_limb)LOW(u); + u >>= DIG_SIZE; + } +} + +#ifdef MRB_INT32 +static void +mpz_set_int64(mrb_state *mrb, mpz_t *y, int64_t v) +{ + uint64_t u; + + if (v < 0) { + if (v == INT64_MIN) u = v; + else u = -v; + } + else { + u = v; + } + mpz_set_uint64(mrb, y, u); + if (v < 0) { + y->sn = -1; + } +} +#endif + static void mpz_init_set_int(mrb_state *mrb, mpz_t *y, mrb_int v) { @@ -131,7 +164,7 @@ digits(mpz_t *x) size_t i; if (x->sz == 0) return 0; - for (i = x->sz - 1; x->p[i] == 0 ; i--) + for (i = x->sz - 1; x->p[i] == 0; i--) if (i == 0) break; return i+1; } @@ -362,7 +395,7 @@ lzb(mp_limb x) int j=0; - for (mp_limb i = ((mp_limb)1 << (DIG_SIZE-1)); i && !(x&i) ; j++,i>>=1) + for (mp_limb i = ((mp_limb)1 << (DIG_SIZE-1)); i && !(x&i); j++,i>>=1) ; return j; } @@ -909,7 +942,41 @@ mpz_pow(mrb_state *mrb, mpz_t *zz, mpz_t *x, mrb_int e) } static void -mpz_powm(mrb_state *mrb, mpz_t *zz, mpz_t *x, mrb_int ex, mpz_t *n) +mpz_powm(mrb_state *mrb, mpz_t *zz, mpz_t *x, mpz_t *ex, mpz_t *n) +{ + mpz_t t, b; + + if (uzero(ex)) { + mpz_set_int(mrb, zz, 1); + return; + } + + if (ex->sn < 0) { + return; + } + + mpz_init_set_int(mrb, &t, 1); + mpz_init_set(mrb, &b, x); + + size_t len = digits(ex); + for (size_t i=0; ip[i]; + for (size_t j=0; j>= 1; + mpz_mul(mrb, &b, &b, &b); + mpz_mod(mrb, &b, &b, n); + } + } + mpz_move(mrb, zz, &t); + mpz_clear(mrb, &b); +} + +static void +mpz_powm_i(mrb_state *mrb, mpz_t *zz, mpz_t *x, mrb_int ex, mpz_t *n) { mpz_t t, b; @@ -956,16 +1023,29 @@ bint_new_int(mrb_state *mrb, mrb_int x) } mrb_value -mrb_bint_new(mrb_state *mrb) +mrb_bint_new_int(mrb_state *mrb, mrb_int x) +{ + struct RBigint *b = bint_new_int(mrb, x); + return mrb_obj_value(b); +} + +#ifdef MRB_INT32 +mrb_value +mrb_bint_new_int64(mrb_state *mrb, int64_t x) { struct RBigint *b = bint_new(mrb); + mpz_init(mrb, &b->mp); + mpz_set_int64(mrb, &b->mp, x); return mrb_obj_value(b); } +#endif mrb_value -mrb_bint_new_int(mrb_state *mrb, mrb_int x) +mrb_bint_new_uint64(mrb_state *mrb, uint64_t x) { - struct RBigint *b = bint_new_int(mrb, x); + struct RBigint *b = bint_new(mrb); + mpz_init(mrb, &b->mp); + mpz_set_uint64(mrb, &b->mp, x); return mrb_obj_value(b); } @@ -1086,6 +1166,61 @@ mrb_bint_as_int(mrb_state *mrb, mrb_value x) return i; } +#ifdef MRB_INT32 +int64_t +mrb_bint_as_int64(mrb_state *mrb, mrb_value x) +{ + struct RBigint *b = RBIGINT(x); + mpz_t *m = &b->mp; + uint64_t u = 0; + size_t len = digits(m); + + if (len*sizeof(mp_limb) > sizeof(uint64_t)) { + out_of_range: + mrb_raise(mrb, E_RANGE_ERROR, "integer out of range"); + } + for (size_t i=len-1; ; i--) { + u <<= DIG_SIZE; + u |= m->p[i]; + if (i==0) break; + } + if (u > INT64_MAX) goto out_of_range; + if (m->sn < 0) return -(int64_t)u; + return (int64_t)u; +} +#endif + +uint64_t +mrb_bint_as_uint64(mrb_state *mrb, mrb_value x) +{ + struct RBigint *b = RBIGINT(x); + mpz_t *m = &b->mp; + uint64_t u = 0; + size_t len = digits(m); + + if (m->sn < 0 || len*sizeof(mp_limb) > sizeof(uint64_t)) { + mrb_raise(mrb, E_RANGE_ERROR, "integer out of range"); + } + for (size_t i=len-1; ; i--) { + u <<= DIG_SIZE; + u |= m->p[i]; + if (i==0) break; + } + return u; +} + +/* unnormalize version of mrb_bint_add */ +mrb_value +mrb_bint_add_d(mrb_state *mrb, mrb_value x, mrb_value y) +{ + 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 mrb_obj_value(b3); +} + mrb_value mrb_bint_add(mrb_state *mrb, mrb_value x, mrb_value y) { @@ -1096,12 +1231,20 @@ mrb_bint_add(mrb_state *mrb, mrb_value x, mrb_value y) return mrb_float_value(mrb,v1+v2); } #endif + x = mrb_bint_add_d(mrb, x, y); + return bint_norm(mrb, RBIGINT(x)); +} + +/* unnormalize version of mrb_bint_sub */ +mrb_value +mrb_bint_sub_d(mrb_state *mrb, mrb_value x, mrb_value y) +{ 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); + mpz_sub(mrb, &b3->mp, &b->mp, &b2->mp); + return mrb_obj_value(b3); } mrb_value @@ -1114,12 +1257,8 @@ mrb_bint_sub(mrb_state *mrb, mrb_value x, mrb_value 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); + x = mrb_bint_sub_d(mrb, x, y); + return bint_norm(mrb, RBIGINT(x)); } mrb_value @@ -1206,20 +1345,6 @@ mrb_bint_mul_ii(mrb_state *mrb, mrb_int x, mrb_int y) 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_mod(mrb_state *mrb, mrb_value x, mrb_value y) { @@ -1334,32 +1459,36 @@ 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 exp, mrb_value mod) +mrb_bint_powm(mrb_state *mrb, mrb_value x, mrb_value exp, mrb_value mod) { struct RBigint *b = RBIGINT(x); - switch (mrb_type(mod)) { - case MRB_TT_INTEGER: - { - mrb_int m = mrb_integer(mod); - if (m == 0) mrb_int_zerodiv(mrb); - struct RBigint *b2 = bint_new_int(mrb, m); - struct RBigint *b3 = bint_new(mrb); - mpz_powm(mrb, &b3->mp, &b->mp, exp, &b2->mp); - return bint_norm(mrb, b3); + struct RBigint *b2, *b3; + + if (mrb_bigint_p(mod)) { + b2 = RBIGINT(mod); + if (uzero(&b2->mp)) mrb_int_zerodiv(mrb); + } + else { + mrb_int m = mrb_integer(mod); + if (m == 0) mrb_int_zerodiv(mrb); + b2 = bint_new_int(mrb, m); + } + b3 = bint_new(mrb); + if (mrb_bigint_p(exp)) { + struct RBigint *be = RBIGINT(exp); + if (be->mp.sn < 0) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "int.pow(n,m): n must be positive"); } - case MRB_TT_BIGINT: - { - struct RBigint *b2 = RBIGINT(mod); - struct RBigint *b3 = bint_new(mrb); - if (uzero(&b2->mp)) mrb_int_zerodiv(mrb); - mpz_powm(mrb, &b3->mp, &b->mp, exp, &b2->mp); - return bint_norm(mrb, b3); + mpz_powm(mrb, &b3->mp, &b->mp, &be->mp, &b2->mp); + } + else { + mrb_int e = mrb_integer(exp); + if (e < 0) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "int.pow(n,m): n must be positive"); } - mrb_raise(mrb, E_TYPE_ERROR, "too big power"); - default: - mrb_raisef(mrb, E_TYPE_ERROR, "%v cannot be convert to integer", mod); + mpz_powm_i(mrb, &b3->mp, &b->mp, e, &b2->mp); } - return mrb_nil_value(); + return bint_norm(mrb, b3); } mrb_value diff --git a/mruby/mrbgems/mruby-bin-config/mrbgem.rake b/mruby/mrbgems/mruby-bin-config/mrbgem.rake index b4c43764..8a484d69 100644 --- a/mruby/mrbgems/mruby-bin-config/mrbgem.rake +++ b/mruby/mrbgems/mruby-bin-config/mrbgem.rake @@ -11,7 +11,16 @@ MRuby::Gem::Specification.new('mruby-bin-config') do |spec| else mruby_config_dir = "#{build.build_dir}/bin" end - mruby_config = name + (ENV['OS'] == 'Windows_NT' ? '.bat' : '') + + if ENV['OS'] == 'Windows_NT' + suffix = '.bat' + refvar = '%\\1%' + else + suffix = '' + refvar = '${\\1}' + end + + mruby_config = name + suffix mruby_config_path = "#{mruby_config_dir}/#{mruby_config}" make_cfg = "#{build.build_dir}/lib/libmruby.flags.mak" tmplt_path = "#{__dir__}/#{mruby_config}" @@ -24,11 +33,16 @@ MRuby::Gem::Specification.new('mruby-bin-config') do |spec| directory mruby_config_dir - file mruby_config_path => [mruby_config_dir, make_cfg, tmplt_path] do |t| + file mruby_config_path => [__FILE__, mruby_config_dir, make_cfg, tmplt_path] do |t| config = Hash[File.readlines(make_cfg).map!(&:chomp).map! {|l| + l.gsub!(/\$\((\w+)\)/, refvar) l.gsub('\\"', '"').split(' = ', 2).map! {|s| s.sub(/^(?=.)/, 'echo ')} }] tmplt = File.read(tmplt_path) + tmplt.sub!(%r((?<=\A#!/bin/sh\n\n)), <<~SETDIR) + MRUBY_PACKAGE_DIR=$(dirname "$(dirname "$(readlink -f "$0")")") + + SETDIR File.write(t.name, tmplt.gsub(/(#{Regexp.union(*config.keys)})\b/, config)) chmod(0755, t.name) end diff --git a/mruby/mrbgems/mruby-bin-config/mruby-config b/mruby/mrbgems/mruby-bin-config/mruby-config index 3adda9e1..27365e65 100755 --- a/mruby/mrbgems/mruby-bin-config/mruby-config +++ b/mruby/mrbgems/mruby-bin-config/mruby-config @@ -4,8 +4,14 @@ print_help() { echo "Usage: mruby-config [switches]" echo " switches:" - echo " --cc print compiler name" - echo " --cflags print flags passed to compiler" + echo " --cc print C compiler name" + echo " --cflags print flags passed to C compiler" + echo " --cxx print C++ compiler name" + echo " --cxxflags print flags passed to C++ compiler" + echo " --as print assembler name" + echo " --asflags print flags passed to assembler" + echo " --objc print Objective C compiler name" + echo " --objcflags print flags passed to Objective C compiler" echo " --ld print linker name" echo " --ldflags print flags passed to linker" echo " --ldflags-before-libs print flags passed to linker before linked libraries" @@ -23,6 +29,12 @@ while [ $# -gt 0 ]; do case $1 in --cc) echo MRUBY_CC;; --cflags) echo MRUBY_CFLAGS;; + --cxx) echo MRUBY_CXX;; + --cxxflags) echo MRUBY_CXXFLAGS;; + --as) echo MRUBY_AS;; + --asflags) echo MRUBY_ASFLAGS;; + --objc) echo MRUBY_OBJC;; + --objcflags) echo MRUBY_OBJCFLAGS;; --ld) echo MRUBY_LD;; --ldflags) echo MRUBY_LDFLAGS;; --ldflags-before-libs) echo MRUBY_LDFLAGS_BEFORE_LIBS;; diff --git a/mruby/mrbgems/mruby-bin-config/mruby-config.bat b/mruby/mrbgems/mruby-bin-config/mruby-config.bat index 949fea06..fa7ad2a6 100644 --- a/mruby/mrbgems/mruby-bin-config/mruby-config.bat +++ b/mruby/mrbgems/mruby-bin-config/mruby-config.bat @@ -1,10 +1,28 @@ @echo off +call :init "%~dp0." +goto top + +:init +rem call init2 for treatments last directory separator +call :init2 "%~dp1." +goto :eof + +:init2 +set MRUBY_PACKAGE_DIR=%~f1 +goto :eof + :top shift if "%0" equ "" goto :eof if "%0" equ "--cc" goto cc if "%0" equ "--cflags" goto cflags +if "%0" equ "--cxx" goto cxx +if "%0" equ "--cxxflags" goto cxxflags +if "%0" equ "--as" goto as +if "%0" equ "--asflags" goto asflags +if "%0" equ "--objc" goto objc +if "%0" equ "--objcflags" goto objcflags if "%0" equ "--ld" goto ld if "%0" equ "--ldflags" goto ldflags if "%0" equ "--ldflags-before-libs" goto ldflagsbeforelibs @@ -22,6 +40,30 @@ goto top echo MRUBY_CFLAGS goto top +:cxx +echo MRUBY_CXX +goto top + +:cxxflags +echo MRUBY_CXXFLAGS +goto top + +:as +echo MRUBY_AS +goto top + +:asflags +echo MRUBY_ASFLAGS +goto top + +:objc +echo MRUBY_OBJC +goto top + +:objcflags +echo MRUBY_OBJCFLAGS +goto top + :ld echo MRUBY_LD goto top @@ -45,8 +87,14 @@ goto top :showhelp echo Usage: mruby-config [switches] echo switches: -echo --cc print compiler name -echo --cflags print flags passed to compiler +echo --cc print C compiler name +echo --cflags print flags passed to C compiler +echo --cxx print C++ compiler name +echo --cxxflags print flags passed to C++ compiler +echo --as print assembler name +echo --asflags print flags passed to assembler +echo --objc print Objective C compiler name +echo --objcflags print flags passed to Objective C compiler echo --ld print linker name echo --ldflags print flags passed to linker echo --ldflags-before-libs print flags passed to linker before linked libraries diff --git a/mruby/mrbgems/mruby-bin-debugger/mrbgem.rake b/mruby/mrbgems/mruby-bin-debugger/mrbgem.rake index 091851dd..f51c9a3d 100644 --- a/mruby/mrbgems/mruby-bin-debugger/mrbgem.rake +++ b/mruby/mrbgems/mruby-bin-debugger/mrbgem.rake @@ -2,7 +2,7 @@ MRuby::Gem::Specification.new('mruby-bin-debugger') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' spec.summary = 'mruby debugger command' - spec.build.defines |= %w(MRB_USE_DEBUG_HOOK) + spec.build.defines << "MRB_USE_DEBUG_HOOK" spec.add_dependency('mruby-eval', :core => 'mruby-eval') spec.bins = %w(mrdb) diff --git a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c index a69d65dd..e3e0e666 100644 --- a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c +++ b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c @@ -68,7 +68,7 @@ get_break_index(mrb_debug_context *dbg, uint32_t bpno) int32_t index; char hit = FALSE; - for(i = 0 ; i < dbg->bpnum; i++) { + for (i = 0; i < dbg->bpnum; i++) { if (dbg->bp[i].bpno == bpno) { hit = TRUE; index = i; @@ -341,7 +341,7 @@ mrb_debug_delete_break(mrb_state *mrb, mrb_debug_context *dbg, uint32_t bpno) free_breakpoint(mrb, &dbg->bp[index]); - for(i = index ; i < dbg->bpnum; i++) { + for (i = index; i < dbg->bpnum; i++) { if ((i + 1) == dbg->bpnum) { dbg->bp[i] = (mrb_debug_breakpoint){0}; } @@ -364,7 +364,7 @@ mrb_debug_delete_break_all(mrb_state *mrb, mrb_debug_context *dbg) return MRB_DEBUG_INVALID_ARGUMENT; } - for(i = 0 ; i < dbg->bpnum ; i++) { + for (i = 0; i < dbg->bpnum; i++) { free_breakpoint(mrb, &dbg->bp[i]); } @@ -401,7 +401,7 @@ mrb_debug_enable_break_all(mrb_state *mrb, mrb_debug_context *dbg) return MRB_DEBUG_INVALID_ARGUMENT; } - for(i = 0 ; i < dbg->bpnum; i++) { + for (i = 0; i < dbg->bpnum; i++) { dbg->bp[i].enable = TRUE; } @@ -436,7 +436,7 @@ mrb_debug_disable_break_all(mrb_state *mrb, mrb_debug_context *dbg) return MRB_DEBUG_INVALID_ARGUMENT; } - for(i = 0 ; i < dbg->bpnum; i++) { + for (i = 0; i < dbg->bpnum; i++) { dbg->bp[i].enable = FALSE; } @@ -470,7 +470,7 @@ mrb_debug_check_breakpoint_line(mrb_state *mrb, mrb_debug_context *dbg, const ch } bp = dbg->bp; - for(i=0; ibpnum; i++) { + for (i=0; ibpnum; i++) { switch (bp->type) { case MRB_DEBUG_BPTYPE_LINE: if (bp->enable == TRUE) { @@ -504,7 +504,7 @@ mrb_debug_check_breakpoint_method(mrb_state *mrb, mrb_debug_context *dbg, struct } bp = dbg->bp; - for(i=0; ibpnum; i++) { + for (i=0; ibpnum; i++) { if (bp->type == MRB_DEBUG_BPTYPE_METHOD) { if (bp->enable == TRUE) { bpno = compare_break_method(mrb, bp, class_obj, method_sym, isCfunc); diff --git a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.h b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.h index 08f1d808..cc272cbe 100644 --- a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.h +++ b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.h @@ -9,18 +9,18 @@ #include #include "mrdb.h" -int32_t mrb_debug_set_break_line(mrb_state *, mrb_debug_context *, const char *, uint16_t); -int32_t mrb_debug_set_break_method(mrb_state *, mrb_debug_context *, const char *, const char *); -int32_t mrb_debug_get_breaknum(mrb_state *, mrb_debug_context *); -int32_t mrb_debug_get_break_all(mrb_state *, mrb_debug_context *, uint32_t, mrb_debug_breakpoint bp[]); -int32_t mrb_debug_get_break(mrb_state *, mrb_debug_context *, uint32_t, mrb_debug_breakpoint *); -int32_t mrb_debug_delete_break(mrb_state *, mrb_debug_context *, uint32_t); -int32_t mrb_debug_delete_break_all(mrb_state *, mrb_debug_context *); -int32_t mrb_debug_enable_break(mrb_state *, mrb_debug_context *, uint32_t); -int32_t mrb_debug_enable_break_all(mrb_state *, mrb_debug_context *); -int32_t mrb_debug_disable_break(mrb_state *, mrb_debug_context *, uint32_t); -int32_t mrb_debug_disable_break_all(mrb_state *, mrb_debug_context *); -int32_t mrb_debug_check_breakpoint_line(mrb_state *, mrb_debug_context *, const char *, uint16_t); -int32_t mrb_debug_check_breakpoint_method(mrb_state *, mrb_debug_context *, struct RClass *, mrb_sym, mrb_bool*); +int32_t mrb_debug_set_break_line(mrb_state*, mrb_debug_context*, const char*, uint16_t); +int32_t mrb_debug_set_break_method(mrb_state*, mrb_debug_context*, const char*, const char*); +int32_t mrb_debug_get_breaknum(mrb_state*, mrb_debug_context*); +int32_t mrb_debug_get_break_all(mrb_state*, mrb_debug_context*, uint32_t, mrb_debug_breakpoint bp[]); +int32_t mrb_debug_get_break(mrb_state*, mrb_debug_context*, uint32_t, mrb_debug_breakpoint*); +int32_t mrb_debug_delete_break(mrb_state*, mrb_debug_context*, uint32_t); +int32_t mrb_debug_delete_break_all(mrb_state*, mrb_debug_context*); +int32_t mrb_debug_enable_break(mrb_state*, mrb_debug_context*, uint32_t); +int32_t mrb_debug_enable_break_all(mrb_state*, mrb_debug_context*); +int32_t mrb_debug_disable_break(mrb_state*, mrb_debug_context*, uint32_t); +int32_t mrb_debug_disable_break_all(mrb_state*, mrb_debug_context*); +int32_t mrb_debug_check_breakpoint_line(mrb_state*, mrb_debug_context*, const char*, uint16_t); +int32_t mrb_debug_check_breakpoint_method(mrb_state*, mrb_debug_context*, struct RClass*, mrb_sym, mrb_bool*); #endif /* APIBREAK_H_ */ diff --git a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c index 27db02b4..0fc087bd 100644 --- a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c +++ b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c @@ -200,7 +200,7 @@ mrb_debug_get_source(mrb_state *mrb, mrdb_state *mrdb, const char *srcpath, cons break; } - mrb_free(mrb, (void *)search_path[1]); + mrb_free(mrb, (void*)search_path[1]); return path; } diff --git a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.h b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.h index 6c410788..542fda10 100644 --- a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.h +++ b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.h @@ -8,7 +8,7 @@ #include #include "mrdb.h" -int32_t mrb_debug_list(mrb_state *, mrb_debug_context *, char *, uint16_t, uint16_t); -char* mrb_debug_get_source(mrb_state *, mrdb_state *, const char *, const char *); +int32_t mrb_debug_list(mrb_state*, mrb_debug_context*, char*, uint16_t, uint16_t); +char* mrb_debug_get_source(mrb_state*, mrdb_state*, const char*, const char *); #endif /* APILIST_H_ */ diff --git a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.c b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.c index 9093a4f0..8b3f30ff 100644 --- a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.c +++ b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.c @@ -34,7 +34,7 @@ mrdb_check_syntax(mrb_state *mrb, mrb_debug_context *dbg, const char *expr, size mrb_value mrb_debug_eval(mrb_state *mrb, mrb_debug_context *dbg, const char *expr, size_t len, mrb_bool *exc, int direct_eval) { - void (*tmp)(struct mrb_state *, const struct mrb_irep *, const mrb_code *, mrb_value *); + void (*tmp)(struct mrb_state*, const struct mrb_irep*, const mrb_code*, mrb_value*); mrb_value ruby_code; mrb_value s; mrb_value v; @@ -68,11 +68,11 @@ mrb_debug_eval(mrb_state *mrb, mrb_debug_context *dbg, const char *expr, size_t recv = dbg->regs[0]; - v = mrb_funcall_id(mrb, recv, MRB_SYM(instance_eval), 1, ruby_code); + v = mrb_funcall_argv(mrb, recv, MRB_SYM(instance_eval), 1, &ruby_code); } if (exc) { - *exc = mrb_obj_is_kind_of(mrb, v, mrb->eException_class); + *exc = mrb_obj_is_kind_of(mrb, v, E_EXCEPTION); } s = mrb_inspect(mrb, v); diff --git a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdbreak.c b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdbreak.c index bc9937e9..621bb452 100644 --- a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdbreak.c +++ b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdbreak.c @@ -42,8 +42,8 @@ #define LINENO_MAX_DIGIT 6 #define BPNO_LETTER_NUM 9 -typedef int32_t (*all_command_func)(mrb_state *, mrb_debug_context *); -typedef int32_t (*select_command_func)(mrb_state *, mrb_debug_context *, uint32_t); +typedef int32_t (*all_command_func)(mrb_state*, mrb_debug_context*); +typedef int32_t (*select_command_func)(mrb_state*, mrb_debug_context*, uint32_t); static void print_api_common_error(int32_t error) @@ -61,7 +61,7 @@ print_api_common_error(int32_t error) #define STRTOUL(ul,s) { \ int i; \ ul = 0; \ - for(i=0; ISDIGIT(s[i]); i++) ul = 10*ul + (s[i] -'0'); \ + for (i=0; ISDIGIT(s[i]); i++) ul = 10*ul + (s[i] -'0'); \ } static int32_t @@ -106,7 +106,7 @@ exe_set_command_select(mrb_state *mrb, mrdb_state *mrdb, select_command_func fun int32_t bpno = 0; int32_t i; - for(i=1; iwcnt; i++) { + for (i=1; iwcnt; i++) { ps = mrdb->words[i]; bpno = parse_breakpoint_no(ps); if (bpno == 0) { @@ -199,7 +199,7 @@ info_break_all(mrb_state *mrb, mrdb_state *mrdb) return; } puts(BREAK_INFO_MSG_HEADER); - for(i = 0 ; i < bpnum ; i++) { + for (i = 0; i < bpnum; i++) { print_breakpoint(&bp_list[i]); } @@ -216,7 +216,7 @@ info_break_select(mrb_state *mrb, mrdb_state *mrdb) mrb_bool isFirst = TRUE; int32_t i; - for(i=2; iwcnt; i++) { + for (i=2; iwcnt; i++) { ps = mrdb->words[i]; bpno = parse_breakpoint_no(ps); if (bpno == 0) { diff --git a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c index 0714f3f2..4cf635b4 100644 --- a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c +++ b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c @@ -167,7 +167,8 @@ parse_uint(char **sp, uint16_t *n) return FALSE; } - for (p = *sp; *p != '\0' && ISDIGIT(*p); p++) ; + for (p = *sp; *p != '\0' && ISDIGIT(*p); p++) + ; if (p != *sp && (i = atoi(*sp)) >= 0) { *n = (uint16_t)i; @@ -350,9 +351,9 @@ check_cmd_pattern(const char *pattern, const char *cmd) } p = lbracket + 1; - q = (char *)cmd + (lbracket - pattern); + q = (char*)cmd + (lbracket - pattern); - for ( ; p < rbracket && *q != '\0'; p++, q++) { + for (; p < rbracket && *q != '\0'; p++, q++) { if (*p != *q) { break; } @@ -479,7 +480,8 @@ dbgcmd_quit(mrb_state *mrb, mrdb_state *mrdb) break; } c = buf; - while (buf != '\n' && (buf = getchar()) != EOF) ; + while (buf != '\n' && (buf = getchar()) != EOF) + ; if (c == 'y' || c == 'Y') { mrdb->dbg->xm = DBG_QUIT; @@ -500,7 +502,7 @@ dbgcmd_quit(mrb_state *mrb, mrdb_state *mrdb) if (mrdb->dbg->xm == DBG_QUIT) { struct RClass *exc; - exc = mrb_define_class(mrb, "DebuggerExit", mrb->eException_class); + exc = mrb_define_class(mrb, "DebuggerExit", E_EXCEPTION); mrb_raise(mrb, exc, "Exit mrdb"); } return DBGST_PROMPT; diff --git a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c index fe8cf0aa..1cd463eb 100644 --- a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c +++ b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c @@ -19,7 +19,7 @@ dbgcmd_run(mrb_state *mrb, mrdb_state *mrdb) if (dbg->xphase == DBG_PHASE_RUNNING){ struct RClass *exc; puts("Start it from the beginning"); - exc = mrb_define_class(mrb, "DebuggerRestart", mrb->eException_class); + exc = mrb_define_class(mrb, "DebuggerRestart", E_EXCEPTION); mrb_raise(mrb, exc, "Restart mrdb"); } } diff --git a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c index 340a57b5..e0e3a96f 100644 --- a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c +++ b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c @@ -20,7 +20,7 @@ #include "apibreak.h" #include "apilist.h" -void mrdb_state_free(mrb_state *); +void mrdb_state_free(mrb_state*); static mrb_debug_context *_debug_context = NULL; static mrdb_state *_mrdb_state = NULL; @@ -113,7 +113,7 @@ parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args) char *buf; buflen = strlen(item) + 1; - buf = (char *)mrb_malloc(mrb, buflen); + buf = (char*)mrb_malloc(mrb, buflen); memcpy(buf, item, buflen); args->srcpath = buf; } @@ -123,8 +123,7 @@ parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args) srcpathlen = strlen(args->srcpath); itemlen = strlen(item); - args->srcpath = - (char *)mrb_realloc(mrb, args->srcpath, srcpathlen + itemlen + 2); + args->srcpath = (char*)mrb_realloc(mrb, args->srcpath, srcpathlen + itemlen + 2); args->srcpath[srcpathlen] = '\n'; memcpy(args->srcpath + srcpathlen + 1, item, itemlen + 1); } @@ -280,7 +279,7 @@ get_command(mrb_state *mrb, mrdb_state *mrdb) } if (i == MAX_COMMAND_LINE) { - for ( ; (c=getchar()) != EOF && c !='\n'; i++) ; + for (; (c=getchar()) != EOF && c !='\n'; i++) ; } if (i > MAX_COMMAND_LINE) { @@ -297,7 +296,8 @@ pick_out_word(mrb_state *mrb, char **pp) { char *ps; - for (ps=*pp; ISBLANK(*ps); ps++) ; + for (ps=*pp; ISBLANK(*ps); ps++) + ; if (*ps == '\0') { return NULL; } @@ -336,7 +336,8 @@ parse_command(mrb_state *mrb, mrdb_state *mrdb, char *buf) } mrdb->wcnt = 1; /* set remain parameter */ - for ( ; *p && ISBLANK(*p); p++) ; + for (; *p && ISBLANK(*p); p++) + ; if (*p) { mrdb->words[mrdb->wcnt++] = p; } @@ -356,7 +357,8 @@ parse_command(mrb_state *mrb, mrdb_state *mrdb, char *buf) mrdb->words[1] = pick_out_word(mrb, &p); if (mrdb->words[1]) { /* update remain parameter */ - for ( ; *p && ISBLANK(*p); p++) ; + for (; *p && ISBLANK(*p); p++) + ; if (*p) { mrdb->words[mrdb->wcnt++] = p; } @@ -364,7 +366,7 @@ parse_command(mrb_state *mrb, mrdb_state *mrdb, char *buf) } /* check word #1,#2 */ - for ( ; cmd->cmd1; cmd++) { + for (; cmd->cmd1; cmd++) { wlen = strlen(mrdb->words[0]); if (wlen < cmd->len1 || strncmp(mrdb->words[0], cmd->cmd1, wlen)) { @@ -386,7 +388,7 @@ parse_command(mrb_state *mrb, mrdb_state *mrdb, char *buf) /* divide remain parameters */ if (cmd->cmd1 && cmd->div) { p = mrdb->words[--mrdb->wcnt]; - for ( ; mrdb->wcntwcnt++) { + for (; mrdb->wcntwcnt++) { mrdb->words[mrdb->wcnt] = pick_out_word(mrb, &p); if (!mrdb->words[mrdb->wcnt]) { break; diff --git a/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c b/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c index 78c3ed40..d4cea8d5 100644 --- a/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c +++ b/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c @@ -95,7 +95,7 @@ get_history_path(mrb_state *mrb) int len = snprintf(NULL, 0, "%s/%s", home, history_file_name); if (len >= 0) { size_t size = len + 1; - path = (char *)mrb_malloc_simple(mrb, size); + path = (char*)mrb_malloc_simple(mrb, size); if (path != NULL) { int n = snprintf(path, size, "%s/%s", home, history_file_name); if (n != len) { @@ -117,7 +117,7 @@ p(mrb_state *mrb, mrb_value obj, int prompt) mrb_value val; char* msg; - val = mrb_funcall_id(mrb, obj, MRB_SYM(inspect), 0); + val = mrb_funcall_argv(mrb, obj, MRB_SYM(inspect), 0, NULL); if (prompt) { if (!mrb->exc) { fputs(" => ", stdout); @@ -508,7 +508,6 @@ main(int argc, char **argv) /* Load libraries */ for (i = 0; i < args.libc; i++) { - struct REnv *e; FILE *lfp = fopen(args.libv[i], "r"); if (lfp == NULL) { printf("Cannot open library file. (%s)\n", args.libv[i]); @@ -517,9 +516,7 @@ main(int argc, char **argv) } mrb_load_file_cxt(mrb, lfp, cxt); fclose(lfp); - e = mrb_vm_ci_env(mrb->c->cibase); - mrb_vm_ci_env_set(mrb->c->cibase, NULL); - mrb_env_unshare(mrb, e, FALSE); + mrb_vm_ci_env_clear(mrb, mrb->c->cibase); mrbc_cleanup_local_variables(mrb, cxt); } diff --git a/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c b/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c index 505d4509..88cb51ca 100644 --- a/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c +++ b/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c @@ -199,7 +199,7 @@ static int partial_hook(struct mrb_parser_state *p) { mrbc_context *c = p->cxt; - struct mrbc_args *args = (struct mrbc_args *)c->partial_data; + struct mrbc_args *args = (struct mrbc_args*)c->partial_data; const char *fn; if (p->f) fclose(p->f); @@ -368,9 +368,4 @@ void mrb_init_mrbgems(mrb_state *mrb) { } - -void -mrb_final_mrbgems(mrb_state *mrb) -{ -} #endif diff --git a/mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c b/mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c index 3faaaccd..ad8373b9 100644 --- a/mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c +++ b/mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c @@ -172,8 +172,7 @@ parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args) cmdlinelen = strlen(args->cmdline); itemlen = strlen(item); - args->cmdline = - (char *)mrb_realloc(mrb, args->cmdline, cmdlinelen + itemlen + 2); + args->cmdline = (char*)mrb_realloc(mrb, args->cmdline, cmdlinelen + itemlen + 2); args->cmdline[cmdlinelen] = '\n'; memcpy(args->cmdline + cmdlinelen + 1, item, itemlen + 1); } @@ -326,7 +325,6 @@ main(int argc, char **argv) /* Load libraries */ for (i = 0; i < args.libc; i++) { - struct REnv *e; FILE *lfp = fopen(args.libv[i], "rb"); if (lfp == NULL) { fprintf(stderr, "%s: Cannot open library file: %s\n", *argv, args.libv[i]); @@ -342,9 +340,7 @@ main(int argc, char **argv) v = mrb_load_detect_file_cxt(mrb, lfp, c); } fclose(lfp); - e = mrb_vm_ci_env(mrb->c->cibase); - mrb_vm_ci_env_set(mrb->c->cibase, NULL); - mrb_env_unshare(mrb, e, FALSE); + mrb_vm_ci_env_clear(mrb, mrb->c->cibase); mrbc_cleanup_local_variables(mrb, c); } diff --git a/mruby/mrbgems/mruby-bin-strip/mrbgem.rake b/mruby/mrbgems/mruby-bin-strip/mrbgem.rake index 2abd25ee..b98fbafc 100644 --- a/mruby/mrbgems/mruby-bin-strip/mrbgem.rake +++ b/mruby/mrbgems/mruby-bin-strip/mrbgem.rake @@ -2,5 +2,6 @@ MRuby::Gem::Specification.new('mruby-bin-strip') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' spec.summary = 'irep dump debug section remover command' + spec.add_dependency 'mruby-compiler', :core => 'mruby-compiler' spec.bins = %w(mruby-strip) end diff --git a/mruby/mrbgems/mruby-binding-core/mrbgem.rake b/mruby/mrbgems/mruby-binding-core/mrbgem.rake deleted file mode 100644 index c0ba4820..00000000 --- a/mruby/mrbgems/mruby-binding-core/mrbgem.rake +++ /dev/null @@ -1,7 +0,0 @@ -MRuby::Gem::Specification.new('mruby-binding-core') do |spec| - spec.license = 'MIT' - spec.author = 'mruby developers' - spec.summary = 'Binding class (core features only)' - - spec.add_test_dependency('mruby-proc-ext', :core => 'mruby-proc-ext') -end diff --git a/mruby/mrbgems/mruby-binding-core/src/binding-core.c b/mruby/mrbgems/mruby-binding-core/src/binding-core.c deleted file mode 100644 index 47ec34f8..00000000 --- a/mruby/mrbgems/mruby-binding-core/src/binding-core.c +++ /dev/null @@ -1,309 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -void mrb_proc_merge_lvar(mrb_state *mrb, mrb_irep *irep, struct REnv *env, int num, const mrb_sym *lv, const mrb_value *stack); -mrb_value mrb_proc_local_variables(mrb_state *mrb, const struct RProc *proc); -const struct RProc *mrb_proc_get_caller(mrb_state *mrb, struct REnv **env); - -static mrb_int -binding_extract_pc(mrb_state *mrb, mrb_value binding) -{ - mrb_value obj = mrb_iv_get(mrb, binding, MRB_SYM(pc)); - if (mrb_nil_p(obj)) { - return -1; - } - else { - mrb_check_type(mrb, obj, MRB_TT_INTEGER); - return mrb_int(mrb, obj); - } -} - -const struct RProc * -mrb_binding_extract_proc(mrb_state *mrb, mrb_value binding) -{ - mrb_value obj = mrb_iv_get(mrb, binding, MRB_SYM(proc)); - mrb_check_type(mrb, obj, MRB_TT_PROC); - return mrb_proc_ptr(obj); -} - -struct REnv * -mrb_binding_extract_env(mrb_state *mrb, mrb_value binding) -{ - mrb_value obj = mrb_iv_get(mrb, binding, MRB_SYM(env)); - if (mrb_nil_p(obj)) { - return NULL; - } - else { - mrb_check_type(mrb, obj, MRB_TT_ENV); - return (struct REnv *)mrb_obj_ptr(obj); - } -} - -static void -binding_local_variable_name_check(mrb_state *mrb, mrb_sym id) -{ - if (id == 0) { - badname: - mrb_raisef(mrb, E_NAME_ERROR, "wrong local variable name %!n for binding", id); - } - - mrb_int len; - const char *name = mrb_sym_name_len(mrb, id, &len); - if (len == 0) { - goto badname; - } - - if (ISASCII(*name) && !(*name == '_' || ISLOWER(*name))) { - goto badname; - } - len--; - name++; - - for (; len > 0; len--, name++) { - if (ISASCII(*name) && !(*name == '_' || ISALNUM(*name))) { - goto badname; - } - } -} - -static mrb_value * -binding_local_variable_search(mrb_state *mrb, const struct RProc *proc, struct REnv *env, mrb_sym varname) -{ - binding_local_variable_name_check(mrb, varname); - - while (proc) { - if (MRB_PROC_CFUNC_P(proc)) break; - - const mrb_irep *irep = proc->body.irep; - const mrb_sym *lv; - if (irep && (lv = irep->lv)) { - for (int i = 0; i + 1 < irep->nlocals; i++, lv++) { - if (varname == *lv) { - return (env && MRB_ENV_LEN(env) > i) ? &env->stack[i + 1] : NULL; - } - } - } - - if (MRB_PROC_SCOPE_P(proc)) break; - env = MRB_PROC_ENV(proc); - proc = proc->upper; - } - - return NULL; -} - -/* - * call-seq: - * local_variable_defined?(symbol) -> bool - */ -static mrb_value -binding_local_variable_defined_p(mrb_state *mrb, mrb_value self) -{ - mrb_sym varname; - mrb_get_args(mrb, "n", &varname); - - const struct RProc *proc = mrb_binding_extract_proc(mrb, self); - struct REnv *env = mrb_binding_extract_env(mrb, self); - mrb_value *e = binding_local_variable_search(mrb, proc, env, varname); - if (e) { - return mrb_true_value(); - } - else { - return mrb_false_value(); - } -} - -/* - * call-seq: - * local_variable_get(symbol) -> object - */ -static mrb_value -binding_local_variable_get(mrb_state *mrb, mrb_value self) -{ - mrb_sym varname; - mrb_get_args(mrb, "n", &varname); - - const struct RProc *proc = mrb_binding_extract_proc(mrb, self); - struct REnv *env = mrb_binding_extract_env(mrb, self); - mrb_value *e = binding_local_variable_search(mrb, proc, env, varname); - if (!e) { - mrb_raisef(mrb, E_NAME_ERROR, "local variable %!n is not defined", varname); - } - - return *e; -} - -static mrb_value -binding_local_variable_set(mrb_state *mrb, mrb_value self) -{ - mrb_sym varname; - mrb_value obj; - mrb_get_args(mrb, "no", &varname, &obj); - - const struct RProc *proc = mrb_binding_extract_proc(mrb, self); - struct REnv *env = mrb_binding_extract_env(mrb, self); - mrb_value *e = binding_local_variable_search(mrb, proc, env, varname); - if (e) { - *e = obj; - if (!mrb_immediate_p(obj)) { - mrb_field_write_barrier(mrb, (struct RBasic*)env, (struct RBasic*)mrb_obj_ptr(obj)); - } - } - else { - mrb_proc_merge_lvar(mrb, (mrb_irep*)proc->body.irep, env, 1, &varname, &obj); - } - - return obj; -} - -static mrb_value -binding_local_variables(mrb_state *mrb, mrb_value self) -{ - const struct RProc *proc = mrb_proc_ptr(mrb_iv_get(mrb, self, MRB_SYM(proc))); - return mrb_proc_local_variables(mrb, proc); -} - -static mrb_value -binding_receiver(mrb_state *mrb, mrb_value self) -{ - return mrb_iv_get(mrb, self, MRB_SYM(recv)); -} - -/* - * call-seq: - * source_location -> [String, Integer] - */ -static mrb_value -binding_source_location(mrb_state *mrb, mrb_value self) -{ - if (mrb_iv_defined(mrb, self, MRB_SYM(source_location))) { - return mrb_iv_get(mrb, self, MRB_SYM(source_location)); - } - - mrb_value srcloc; - const struct RProc *proc = mrb_binding_extract_proc(mrb, self); - if (!proc || MRB_PROC_CFUNC_P(proc) || - !proc->upper || MRB_PROC_CFUNC_P(proc->upper)) { - srcloc = mrb_nil_value(); - } - else { - const mrb_irep *irep = proc->upper->body.irep; - mrb_int pc = binding_extract_pc(mrb, self); - if (pc < 0) { - srcloc = mrb_nil_value(); - } - else { - const char *fname = mrb_debug_get_filename(mrb, irep, (uint32_t)pc); - mrb_int fline = mrb_debug_get_line(mrb, irep, (uint32_t)pc); - - if (fname && fline >= 0) { - srcloc = mrb_assoc_new(mrb, mrb_str_new_cstr(mrb, fname), mrb_fixnum_value(fline)); - } - else { - srcloc = mrb_nil_value(); - } - } - } - - if (!mrb_frozen_p(mrb_obj_ptr(self))) { - mrb_iv_set(mrb, self, MRB_SYM(source_location), srcloc); - } - return srcloc; -} - -mrb_value -mrb_binding_alloc(mrb_state *mrb) -{ - struct RObject *obj = MRB_OBJ_ALLOC(mrb, MRB_TT_OBJECT, mrb_class_get_id(mrb, MRB_SYM(Binding))); - return mrb_obj_value(obj); -} - -struct RProc* -mrb_binding_wrap_lvspace(mrb_state *mrb, const struct RProc *proc, struct REnv **envp) -{ - /* - * local variable space: It is a space to hold the top-level variable of - * binding.eval and binding.local_variable_set. - */ - - static const mrb_code iseq_dummy[] = { OP_RETURN, 0 }; - - struct RProc *lvspace = MRB_OBJ_ALLOC(mrb, MRB_TT_PROC, mrb->proc_class); - mrb_irep *irep = mrb_add_irep(mrb); - irep->flags = MRB_ISEQ_NO_FREE; - irep->iseq = iseq_dummy; - irep->ilen = sizeof(iseq_dummy) / sizeof(iseq_dummy[0]); - irep->lv = (mrb_sym*)mrb_calloc(mrb, 1, sizeof(mrb_sym)); /* initial allocation for dummy */ - irep->nlocals = 1; - irep->nregs = 1; - lvspace->body.irep = irep; - lvspace->upper = proc; - if (*envp) { - lvspace->e.env = *envp; - lvspace->flags |= MRB_PROC_ENVSET; - } - - *envp = MRB_OBJ_ALLOC(mrb, MRB_TT_ENV, NULL); - (*envp)->stack = (mrb_value*)mrb_calloc(mrb, 1, sizeof(mrb_value)); - (*envp)->stack[0] = lvspace->e.env ? lvspace->e.env->stack[0] : mrb_nil_value(); - (*envp)->cxt = lvspace->e.env ? lvspace->e.env->cxt : mrb->c; - (*envp)->mid = 0; - (*envp)->flags = MRB_ENV_CLOSED; - MRB_ENV_SET_LEN(*envp, 1); - - return lvspace; -} - -static mrb_value -mrb_f_binding(mrb_state *mrb, mrb_value self) -{ - mrb_value binding; - struct RProc *proc; - struct REnv *env; - - binding = mrb_binding_alloc(mrb); - proc = (struct RProc*)mrb_proc_get_caller(mrb, &env); - if (!env || MRB_PROC_CFUNC_P(proc)) { - proc = NULL; - env = NULL; - } - - if (proc && !MRB_PROC_CFUNC_P(proc)) { - const mrb_irep *irep = proc->body.irep; - mrb_iv_set(mrb, binding, MRB_SYM(pc), mrb_fixnum_value(mrb->c->ci[-1].pc - irep->iseq - 1 /* step back */)); - } - proc = mrb_binding_wrap_lvspace(mrb, proc, &env); - mrb_iv_set(mrb, binding, MRB_SYM(proc), mrb_obj_value(proc)); - mrb_iv_set(mrb, binding, MRB_SYM(recv), self); - mrb_iv_set(mrb, binding, MRB_SYM(env), mrb_obj_value(env)); - return binding; -} - -void -mrb_mruby_binding_core_gem_init(mrb_state *mrb) -{ - struct RClass *binding = mrb_define_class(mrb, "Binding", mrb->object_class); - mrb_undef_class_method(mrb, binding, "new"); - mrb_undef_class_method(mrb, binding, "allocate"); - - mrb_define_method(mrb, mrb->kernel_module, "binding", mrb_f_binding, MRB_ARGS_NONE()); - - mrb_define_method(mrb, binding, "local_variable_defined?", binding_local_variable_defined_p, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, binding, "local_variable_get", binding_local_variable_get, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, binding, "local_variable_set", binding_local_variable_set, MRB_ARGS_REQ(2)); - mrb_define_method(mrb, binding, "local_variables", binding_local_variables, MRB_ARGS_NONE()); - mrb_define_method(mrb, binding, "receiver", binding_receiver, MRB_ARGS_NONE()); - mrb_define_method(mrb, binding, "source_location", binding_source_location, MRB_ARGS_NONE()); - mrb_define_method(mrb, binding, "inspect", mrb_any_to_s, MRB_ARGS_NONE()); -} - -void -mrb_mruby_binding_core_gem_final(mrb_state *mrb) -{ -} diff --git a/mruby/mrbgems/mruby-binding-core/test/binding-core.rb b/mruby/mrbgems/mruby-binding-core/test/binding-core.rb deleted file mode 100644 index 066e79b1..00000000 --- a/mruby/mrbgems/mruby-binding-core/test/binding-core.rb +++ /dev/null @@ -1,40 +0,0 @@ -assert("Kernel.#binding") do - assert_kind_of Binding, binding -end - -assert("Binding#local_variables") do - block = Proc.new do |a| - b = 1 - binding - end - assert_equal [:a, :b, :block], block.call(0).local_variables.sort -end - -assert("Binding#local_variable_set") do - bind = binding - 1.times { - assert_equal(9, bind.local_variable_set(:x, 9)) - assert_raise(NameError) { x } - assert_equal([:bind, :x], bind.local_variables.sort) - } -end - -assert("Binding#local_variable_get") do - bind = binding - x = 1 - 1.times { - y = 2 - assert_equal(1, bind.local_variable_get(:x)) - x = 10 - assert_equal(10, bind.local_variable_get(:x)) - assert_raise(NameError) { bind.local_variable_get(:y) } - assert_equal([:bind, :x], bind.local_variables.sort) - } -end - -assert("Binding#source_location") do - skip unless -> {}.source_location - - bind, source_location = binding, [__FILE__, __LINE__] - assert_equal source_location, bind.source_location -end diff --git a/mruby/mrbgems/mruby-binding/mrbgem.rake b/mruby/mrbgems/mruby-binding/mrbgem.rake index 4ad5638e..fe48f3ad 100644 --- a/mruby/mrbgems/mruby-binding/mrbgem.rake +++ b/mruby/mrbgems/mruby-binding/mrbgem.rake @@ -1,11 +1,7 @@ MRuby::Gem::Specification.new('mruby-binding') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' - spec.summary = 'Binding class' + spec.summary = 'Binding class (core features only)' - spec.add_dependency('mruby-binding-core', :core => 'mruby-binding-core') - spec.add_dependency('mruby-eval', :core => 'mruby-eval') - spec.add_test_dependency('mruby-metaprog', :core => 'mruby-metaprog') - spec.add_test_dependency('mruby-method', :core => 'mruby-method') spec.add_test_dependency('mruby-proc-ext', :core => 'mruby-proc-ext') end diff --git a/mruby/mrbgems/mruby-binding/src/binding.c b/mruby/mrbgems/mruby-binding/src/binding.c index de3147f6..7a0a577f 100644 --- a/mruby/mrbgems/mruby-binding/src/binding.c +++ b/mruby/mrbgems/mruby-binding/src/binding.c @@ -1,166 +1,417 @@ #include #include #include -#include -#include +#include #include -#include -#include +#include #include +#include +#include +#include -void mrb_proc_merge_lvar(mrb_state *mrb, mrb_irep *irep, struct REnv *env, int num, const mrb_sym *lv, const mrb_value *stack); -const struct RProc *mrb_binding_extract_proc(mrb_state *mrb, mrb_value binding); -struct REnv *mrb_binding_extract_env(mrb_state *mrb, mrb_value binding); -typedef mrb_bool mrb_parser_foreach_top_variable_func(mrb_state *mrb, mrb_sym sym, void *user); -void mrb_parser_foreach_top_variable(mrb_state *mrb, struct mrb_parser_state *p, mrb_parser_foreach_top_variable_func *func, void *user); +#define BINDING_UPPER_DEFAULT 20 +#define BINDING_UPPER_MINIMUM 10 +#define BINDING_UPPER_MAXIMUM 100 -static void -binding_eval_error_check(mrb_state *mrb, struct mrb_parser_state *p, const char *file) +#ifndef MRB_BINDING_UPPER_MAX +# define BINDING_UPPER_MAX BINDING_UPPER_DEFAULT +#else +# if (MRB_BINDING_UPPER_MAX) > BINDING_UPPER_MAXIMUM +# define BINDING_UPPER_MAX BINDING_UPPER_MAXIMUM +# elif (MRB_BINDING_UPPER_MAX) < BINDING_UPPER_MINIMUM +# define BINDING_UPPER_MAX BINDING_UPPER_MINIMUM +# else +# define BINDING_UPPER_MAX MRB_BINDING_UPPER_MAX +# endif +#endif + +static mrb_int +binding_extract_pc(mrb_state *mrb, mrb_value binding) +{ + mrb_value obj = mrb_iv_get(mrb, binding, MRB_SYM(pc)); + if (mrb_nil_p(obj)) { + return -1; + } + else { + mrb_check_type(mrb, obj, MRB_TT_INTEGER); + return mrb_int(mrb, obj); + } +} + +const struct RProc * +mrb_binding_extract_proc(mrb_state *mrb, mrb_value binding) +{ + mrb_value obj = mrb_iv_get(mrb, binding, MRB_SYM(proc)); + mrb_check_type(mrb, obj, MRB_TT_PROC); + return mrb_proc_ptr(obj); +} + +struct REnv * +mrb_binding_extract_env(mrb_state *mrb, mrb_value binding) +{ + mrb_value obj = mrb_iv_get(mrb, binding, MRB_SYM(env)); + if (mrb_nil_p(obj)) { + return NULL; + } + else { + mrb_check_type(mrb, obj, MRB_TT_ENV); + return (struct REnv*)mrb_obj_ptr(obj); + } +} + +static mrb_irep * +binding_irep_new_lvspace(mrb_state *mrb) +{ + static const mrb_code iseq_dummy[] = { OP_RETURN, 0 }; + + mrb_irep *irep = mrb_add_irep(mrb); + irep->flags = MRB_ISEQ_NO_FREE; + irep->iseq = iseq_dummy; + irep->ilen = sizeof(iseq_dummy) / sizeof(iseq_dummy[0]); + irep->lv = (mrb_sym*)mrb_calloc(mrb, 1, sizeof(mrb_sym)); /* initial allocation for dummy */ + irep->nlocals = 1; + irep->nregs = 1; + return irep; +} + +static struct RProc * +binding_proc_new_lvspace(mrb_state *mrb, const struct RProc *upper, struct REnv *env) { - if (!p) { - mrb_raise(mrb, E_RUNTIME_ERROR, "Failed to create parser state (out of memory)"); + struct RProc *lvspace = MRB_OBJ_ALLOC(mrb, MRB_TT_PROC, mrb->proc_class); + lvspace->body.irep = binding_irep_new_lvspace(mrb); + lvspace->upper = upper; + if (env && env->tt == MRB_TT_ENV) { + lvspace->e.env = env; + lvspace->flags |= MRB_PROC_ENVSET; } + return lvspace; +} - if (0 < p->nerr) { - mrb_value str; +static struct REnv * +binding_env_new_lvspace(mrb_state *mrb, const struct REnv *e) +{ + struct REnv *env = MRB_OBJ_ALLOC(mrb, MRB_TT_ENV, NULL); + mrb_value *stacks = (mrb_value*)mrb_calloc(mrb, 1, sizeof(mrb_value)); + env->cxt = e ? e->cxt : mrb->c; + env->mid = 0; + env->stack = stacks; + if (e && e->stack && MRB_ENV_LEN(e) > 0) { + env->stack[0] = e->stack[0]; + } + else { + env->stack[0] = mrb_nil_value(); + } + env->flags = MRB_ENV_CLOSED; + MRB_ENV_SET_LEN(env, 1); + return env; +} - if (file) { - str = mrb_format(mrb, "file %s line %d: %s", - file, - p->error_buffer[0].lineno, - p->error_buffer[0].message); +static size_t +binding_proc_upper_count(const struct RProc *proc) +{ + size_t count = 0; + for (; proc && !MRB_PROC_CFUNC_P(proc); proc = proc->upper) { + count++; + if (MRB_PROC_SCOPE_P(proc)) break; + } + return count; +} + +mrb_bool +mrb_binding_p(mrb_state *mrb, mrb_value obj) +{ + if (!mrb_obj_is_kind_of(mrb, obj, mrb_class_get_id(mrb, MRB_SYM(Binding)))) return FALSE; + if (mrb_type(obj) != MRB_TT_OBJECT) return FALSE; + if (!mrb_obj_iv_defined(mrb, mrb_obj_ptr(obj), MRB_SYM(proc))) return FALSE; + if (!mrb_obj_iv_defined(mrb, mrb_obj_ptr(obj), MRB_SYM(recv))) return FALSE; + if (!mrb_obj_iv_defined(mrb, mrb_obj_ptr(obj), MRB_SYM(env))) return FALSE; + return TRUE; +} + +static void +binding_type_ensure(mrb_state *mrb, mrb_value obj) +{ + if (mrb_binding_p(mrb, obj)) return; + mrb_raise(mrb, E_TYPE_ERROR, "not a binding"); +} + +static struct RProc* +binding_wrap_lvspace(mrb_state *mrb, const struct RProc *proc, struct REnv **envp) +{ + /* + * local variable space: It is a space to hold the top-level variable of + * binding.eval and binding.local_variable_set. + */ + + struct RProc *lvspace = binding_proc_new_lvspace(mrb, proc, *envp); + *envp = binding_env_new_lvspace(mrb, *envp); + return lvspace; +} + +static mrb_value +binding_initialize_copy(mrb_state *mrb, mrb_value binding) +{ + mrb_value src = mrb_get_arg1(mrb); + binding_type_ensure(mrb, src); + const struct RProc *src_proc = mrb_binding_extract_proc(mrb, src); + struct REnv *src_env = mrb_binding_extract_env(mrb, src); + + mrb_check_frozen(mrb, mrb_obj_ptr(binding)); + + struct RProc *lvspace; + struct REnv *env; + if (MRB_ENV_LEN(src_env) < 2) { + /* when local variables of src are self only */ + env = src_proc->e.env; + lvspace = binding_wrap_lvspace(mrb, src_proc->upper, &env); + } + else { + if (binding_proc_upper_count(src_proc) > BINDING_UPPER_MAX) { + mrb_raise(mrb, E_RUNTIME_ERROR, + "too many upper procs for local variables (mruby limitation; maximum is " MRB_STRINGIZE(BINDING_UPPER_MAX) ")"); } - else { - str = mrb_format(mrb, "line %d: %s", - p->error_buffer[0].lineno, - p->error_buffer[0].message); + + env = src_env; + lvspace = binding_wrap_lvspace(mrb, src_proc, &env); + + // The reason for using the mrb_obj_iv_set_force() function is to allow local + // variables to be modified even if src is frozen. This behavior is CRuby imitation. + src_proc = binding_wrap_lvspace(mrb, src_proc, &src_env); + struct RObject *o = mrb_obj_ptr(src); + mrb_obj_iv_set_force(mrb, o, MRB_SYM(proc), mrb_obj_value((struct RProc*)src_proc)); + mrb_obj_iv_set_force(mrb, o, MRB_SYM(env), mrb_obj_value(src_env)); + } + mrb_iv_set(mrb, binding, MRB_SYM(proc), mrb_obj_value(lvspace)); + mrb_iv_set(mrb, binding, MRB_SYM(env), mrb_obj_value(env)); + + return binding; +} + +static void +binding_local_variable_name_check(mrb_state *mrb, mrb_sym id) +{ + if (id == 0) { + badname: + mrb_raisef(mrb, E_NAME_ERROR, "wrong local variable name %!n for binding", id); + } + + mrb_int len; + const char *name = mrb_sym_name_len(mrb, id, &len); + if (len == 0) { + goto badname; + } + + if (ISASCII(*name) && !(*name == '_' || ISLOWER(*name))) { + goto badname; + } + len--; + name++; + + for (; len > 0; len--, name++) { + if (ISASCII(*name) && !(*name == '_' || ISALNUM(*name))) { + goto badname; } - mrb_exc_raise(mrb, mrb_exc_new_str(mrb, E_SYNTAX_ERROR, str)); } } -#define LV_BUFFERS 8 +static mrb_value * +binding_local_variable_search(mrb_state *mrb, const struct RProc *proc, struct REnv *env, mrb_sym varname) +{ + binding_local_variable_name_check(mrb, varname); -struct expand_lvspace { - mrb_irep *irep; - struct REnv *env; - int numvar; - mrb_sym syms[LV_BUFFERS]; -}; - -static mrb_bool -expand_lvspace(mrb_state *mrb, mrb_sym sym, void *user) -{ - struct expand_lvspace *p = (struct expand_lvspace*)user; - mrb_int symlen; - const char *symname = mrb_sym_name_len(mrb, sym, &symlen); - - if (symname && symlen > 0) { - if (symname[0] != '&' && symname[0] != '*') { - p->syms[p->numvar++] = sym; - if (p->numvar >= LV_BUFFERS) { - mrb_proc_merge_lvar(mrb, p->irep, p->env, p->numvar, p->syms, NULL); - p->numvar = 0; + while (proc) { + if (MRB_PROC_CFUNC_P(proc)) break; + + const mrb_irep *irep = proc->body.irep; + const mrb_sym *lv; + if (irep && (lv = irep->lv)) { + for (int i = 0; i + 1 < irep->nlocals; i++, lv++) { + if (varname == *lv) { + return (env && MRB_ENV_LEN(env) > i) ? &env->stack[i + 1] : NULL; + } } } + + if (MRB_PROC_SCOPE_P(proc)) break; + env = MRB_PROC_ENV(proc); + proc = proc->upper; } - return TRUE; + return NULL; } -struct binding_eval_prepare_body { - mrb_value binding; - const char *file; - const char *expr; - mrb_int exprlen; - mrbc_context *mrbc; - struct mrb_parser_state *pstate; -}; +/* + * call-seq: + * local_variable_defined?(symbol) -> bool + */ +static mrb_value +binding_local_variable_defined_p(mrb_state *mrb, mrb_value self) +{ + mrb_sym varname; + mrb_get_args(mrb, "n", &varname); + + const struct RProc *proc = mrb_binding_extract_proc(mrb, self); + struct REnv *env = mrb_binding_extract_env(mrb, self); + mrb_value *e = binding_local_variable_search(mrb, proc, env, varname); + if (e) { + return mrb_true_value(); + } + else { + return mrb_false_value(); + } +} +/* + * call-seq: + * local_variable_get(symbol) -> object + */ static mrb_value -binding_eval_prepare_body(mrb_state *mrb, void *opaque) +binding_local_variable_get(mrb_state *mrb, mrb_value self) { - struct binding_eval_prepare_body *p = (struct binding_eval_prepare_body*)opaque; + mrb_sym varname; + mrb_get_args(mrb, "n", &varname); - const struct RProc *proc = mrb_binding_extract_proc(mrb, p->binding); - mrb_assert(!MRB_PROC_CFUNC_P(proc)); + const struct RProc *proc = mrb_binding_extract_proc(mrb, self); + struct REnv *env = mrb_binding_extract_env(mrb, self); + mrb_value *e = binding_local_variable_search(mrb, proc, env, varname); + if (!e) { + mrb_raisef(mrb, E_NAME_ERROR, "local variable %!n is not defined", varname); + } - p->mrbc = mrbc_context_new(mrb); - mrbc_filename(mrb, p->mrbc, p->file ? p->file : "(eval)"); - p->mrbc->upper = proc; - p->mrbc->capture_errors = TRUE; - p->pstate = mrb_parse_nstring(mrb, p->expr, p->exprlen, p->mrbc); - binding_eval_error_check(mrb, p->pstate, p->file); + return *e; +} - struct expand_lvspace args = { - (mrb_irep*)proc->body.irep, - mrb_binding_extract_env(mrb, p->binding), - 0, - { 0 } - }; - mrb_parser_foreach_top_variable(mrb, p->pstate, expand_lvspace, &args); - if (args.numvar > 0) { - mrb_proc_merge_lvar(mrb, args.irep, args.env, args.numvar, args.syms, NULL); +static mrb_value +binding_local_variable_set(mrb_state *mrb, mrb_value self) +{ + mrb_sym varname; + mrb_value obj; + mrb_get_args(mrb, "no", &varname, &obj); + + const struct RProc *proc = mrb_binding_extract_proc(mrb, self); + struct REnv *env = mrb_binding_extract_env(mrb, self); + mrb_value *e = binding_local_variable_search(mrb, proc, env, varname); + if (e) { + *e = obj; + if (!mrb_immediate_p(obj)) { + mrb_field_write_barrier(mrb, (struct RBasic*)env, (struct RBasic*)mrb_obj_ptr(obj)); + } + } + else { + mrb_proc_merge_lvar(mrb, (mrb_irep*)proc->body.irep, env, 1, &varname, &obj); } - return mrb_nil_value(); + return obj; } -static void -binding_eval_prepare(mrb_state *mrb, mrb_value binding) +static mrb_value +binding_local_variables(mrb_state *mrb, mrb_value self) { - struct binding_eval_prepare_body d = { binding, NULL, NULL, 0, NULL, NULL }; - mrb_int argc; - mrb_value *argv; - mrb_get_args(mrb, "s|z*!", &d.expr, &d.exprlen, &d.file, &argv, &argc); + const struct RProc *proc = mrb_proc_ptr(mrb_iv_get(mrb, self, MRB_SYM(proc))); + return mrb_proc_local_variables(mrb, proc); +} - /* `eval` should take (string[, file, line]) */ - if (argc > 3) mrb_argnum_error(mrb, argc, 1, 3); - mrb_bool error; - mrb_value ret = mrb_protect_error(mrb, binding_eval_prepare_body, &d, &error); - if (d.pstate) mrb_parser_free(d.pstate); - if (d.mrbc) mrbc_context_free(mrb, d.mrbc); - if (error) mrb_exc_raise(mrb, ret); +static mrb_value +binding_receiver(mrb_state *mrb, mrb_value self) +{ + return mrb_iv_get(mrb, self, MRB_SYM(recv)); } +/* + * call-seq: + * source_location -> [String, Integer] + */ static mrb_value -mrb_binding_eval(mrb_state *mrb, mrb_value binding) +binding_source_location(mrb_state *mrb, mrb_value self) { - binding_eval_prepare(mrb, binding); + if (mrb_iv_defined(mrb, self, MRB_SYM(source_location))) { + return mrb_iv_get(mrb, self, MRB_SYM(source_location)); + } - struct RClass *c = mrb->kernel_module; - mrb_method_t m = mrb_method_search_vm(mrb, &c, MRB_SYM(eval)); - mrb_callinfo *ci = mrb->c->ci; - int argc = ci->n; - mrb_value *argv = ci->stack + 1; - struct RProc *proc; + mrb_value srcloc; + const struct RProc *proc = mrb_binding_extract_proc(mrb, self); + if (!proc || MRB_PROC_CFUNC_P(proc) || + !proc->upper || MRB_PROC_CFUNC_P(proc->upper)) { + srcloc = mrb_nil_value(); + } + else { + const mrb_irep *irep = proc->upper->body.irep; + mrb_int pc = binding_extract_pc(mrb, self); + if (pc < 0) { + srcloc = mrb_nil_value(); + } + else { + const char *fname; + int32_t line; - if (argc < 15) { - argv[0] = mrb_ary_new_from_values(mrb, argc, argv); - argv[1] = argv[argc]; /* copy block */ - ci->n = 15; + if (!mrb_debug_get_position(mrb, irep, (uint32_t)pc, &line, &fname)) { + srcloc = mrb_nil_value(); + } + else { + srcloc = mrb_assoc_new(mrb, mrb_str_new_cstr(mrb, fname), mrb_fixnum_value(line)); + } + } } - if (MRB_METHOD_UNDEF_P(m)) { - mrb_method_missing(mrb, MRB_SYM(eval), binding, argv[0]); + + if (!mrb_frozen_p(mrb_obj_ptr(self))) { + mrb_iv_set(mrb, self, MRB_SYM(source_location), srcloc); } + return srcloc; +} - mrb_ary_splice(mrb, argv[0], 1, 0, binding); /* insert binding as 2nd argument */ - if (MRB_METHOD_FUNC_P(m)) { - proc = mrb_proc_new_cfunc(mrb, MRB_METHOD_FUNC(m)); - MRB_PROC_SET_TARGET_CLASS(proc, c); +mrb_value +mrb_binding_new(mrb_state *mrb, const struct RProc *proc, mrb_value recv, struct REnv *env) +{ + struct RObject *binding = MRB_OBJ_ALLOC(mrb, MRB_TT_OBJECT, mrb_class_get_id(mrb, MRB_SYM(Binding))); + + if (proc && !MRB_PROC_CFUNC_P(proc)) { + const mrb_irep *irep = proc->body.irep; + mrb_obj_iv_set(mrb, binding, MRB_SYM(pc), mrb_fixnum_value(mrb->c->ci[-1].pc - irep->iseq - 1 /* step back */)); } - else { - proc = MRB_METHOD_PROC(m); + proc = binding_wrap_lvspace(mrb, proc, &env); + + mrb_obj_iv_set(mrb, binding, MRB_SYM(proc), mrb_obj_value((void*)proc)); + mrb_obj_iv_set(mrb, binding, MRB_SYM(recv), recv); + mrb_obj_iv_set(mrb, binding, MRB_SYM(env), mrb_obj_value(env)); + + return mrb_obj_value(binding); +} + +static mrb_value +mrb_f_binding(mrb_state *mrb, mrb_value self) +{ + struct RProc *proc; + struct REnv *env; + + if (mrb->c->ci->cci != 0) { + caller_err: + mrb_raise(mrb, E_RUNTIME_ERROR, "Cannot create Binding object for non-Ruby caller"); } - ci->u.target_class = c; - return mrb_exec_irep(mrb, binding, proc); + proc = (struct RProc*)mrb_proc_get_caller(mrb, &env); + if (!env || MRB_PROC_CFUNC_P(proc)) { + goto caller_err; + } + return mrb_binding_new(mrb, proc, self, env); } void mrb_mruby_binding_gem_init(mrb_state *mrb) { - struct RClass *binding = mrb_class_get_id(mrb, MRB_SYM(Binding)); - mrb_define_method(mrb, binding, "eval", mrb_binding_eval, MRB_ARGS_ANY()); + struct RClass *binding = mrb_define_class(mrb, "Binding", mrb->object_class); + MRB_SET_INSTANCE_TT(binding, MRB_TT_UNDEF); + mrb_undef_class_method(mrb, binding, "new"); + mrb_undef_class_method(mrb, binding, "allocate"); + + mrb_define_method(mrb, mrb->kernel_module, "binding", mrb_f_binding, MRB_ARGS_NONE()); + + mrb_define_method(mrb, binding, "initialize_copy", binding_initialize_copy, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, binding, "local_variable_defined?", binding_local_variable_defined_p, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, binding, "local_variable_get", binding_local_variable_get, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, binding, "local_variable_set", binding_local_variable_set, MRB_ARGS_REQ(2)); + mrb_define_method(mrb, binding, "local_variables", binding_local_variables, MRB_ARGS_NONE()); + mrb_define_method(mrb, binding, "receiver", binding_receiver, MRB_ARGS_NONE()); + mrb_define_method(mrb, binding, "source_location", binding_source_location, MRB_ARGS_NONE()); + mrb_define_method(mrb, binding, "inspect", mrb_any_to_s, MRB_ARGS_NONE()); } void diff --git a/mruby/mrbgems/mruby-binding/test/binding.rb b/mruby/mrbgems/mruby-binding/test/binding.rb index bfae84c5..1f76b29f 100644 --- a/mruby/mrbgems/mruby-binding/test/binding.rb +++ b/mruby/mrbgems/mruby-binding/test/binding.rb @@ -1,9 +1,5 @@ -assert("Binding#eval") do - b = nil - 1.times { x, y, z = 1, 2, 3; [x,y,z]; b = binding } - assert_equal([1, 2, 3], b.eval("[x, y, z]")) - here = self - assert_equal(here, b.eval("self")) +assert("Kernel.#binding") do + assert_kind_of Binding, binding end assert("Binding#local_variables") do @@ -11,18 +7,15 @@ b = 1 binding end - bind = block.call(0) - assert_equal [:a, :b, :bind, :block], bind.local_variables.sort - bind.eval("x = 2") - assert_equal [:a, :b, :bind, :block, :x], bind.local_variables.sort + assert_equal [:a, :b, :block], block.call(0).local_variables.sort end assert("Binding#local_variable_set") do bind = binding 1.times { assert_equal(9, bind.local_variable_set(:x, 9)) - assert_equal(9, bind.eval("x")) - assert_equal([:bind, :x], bind.eval("local_variables.sort")) + assert_raise(NameError) { x } + assert_equal([:bind, :x], bind.local_variables.sort) } end @@ -35,36 +28,37 @@ x = 10 assert_equal(10, bind.local_variable_get(:x)) assert_raise(NameError) { bind.local_variable_get(:y) } - bind.eval("z = 3") - assert_equal(3, bind.local_variable_get(:z)) - bind.eval("y = 5") - assert_equal(5, bind.local_variable_get(:y)) - assert_equal(2, y) + assert_equal([:bind, :x], bind.local_variables.sort) } end -assert "Kernel#binding and .eval from C" do - bind = binding_in_c - assert_equal 5, bind.eval("2 + 3") - assert_nothing_raised { bind.eval("self") } -end +assert("Binding#source_location") do + skip unless -> {}.source_location -assert "Binding#eval with Binding.new via UnboundMethod" do - assert_raise(NoMethodError) { Class.instance_method(:new).bind_call(Binding) } + bind, source_location = binding, [__FILE__, __LINE__] + assert_equal source_location, bind.source_location end -assert "Binding#eval with Binding.new via Method" do - # The following test is OK if SIGSEGV does not occur - cx = Class.new(Binding) - cx.define_singleton_method(:allocate, &Object.method(:allocate)) - Class.instance_method(:new).bind_call(cx).eval("") - - assert_true true +assert("Binding#dup") do + x = 5 + bind1 = binding + bind1.local_variable_set(:y, 10) + bind2 = bind1.dup + assert_equal 5, bind2.local_variable_get(:x) + assert_equal 10, bind2.local_variable_get(:y) + x = 50 + assert_equal 50, bind1.local_variable_get(:x) + assert_equal 50, bind2.local_variable_get(:x) + bind1.local_variable_set(:y, 20) + assert_equal 20, bind1.local_variable_get(:y) + assert_equal 20, bind2.local_variable_get(:y) + bind1.local_variable_set(:z, 30) + assert_raise(NameError) { bind2.local_variable_get(:z) } + bind2.local_variable_set(:z, 40) + assert_equal 30, bind1.local_variable_get(:z) + assert_equal 40, bind2.local_variable_get(:z) end -assert "access local variables into procs" do - bx = binding - block = bx.eval("a = 1; proc { a }") - bx.eval("a = 2") - assert_equal 2, block.call +assert "Kernel#binding and .eval from C" do + assert_raise(RuntimeError) { binding_in_c } end diff --git a/mruby/mrbgems/mruby-catch/src/catch.c b/mruby/mrbgems/mruby-catch/src/catch.c index 048a4473..44852c6b 100644 --- a/mruby/mrbgems/mruby-catch/src/catch.c +++ b/mruby/mrbgems/mruby-catch/src/catch.c @@ -6,14 +6,14 @@ #include #include - MRB_PRESYM_DEFINE_VAR_AND_INITER(catch_syms_3, 1, MRB_SYM(call)) static const mrb_code catch_iseq_3[18] = { - OP_ENTER, 0x00, 0x00, 0x00, - OP_GETUPVAR, 0x02, 0x02, 0x01, - OP_GETUPVAR, 0x03, 0x01, 0x01, - OP_SEND, 0x02, 0x00, 0x01, - OP_RETURN, 0x02,}; + OP_ENTER, 0x00, 0x00, 0x00, // 000 ENTER 0:0:0:0:0:0:0 (0x0) + OP_GETUPVAR, 0x02, 0x02, 0x01, // 004 GETUPVAR R2 2 1 + OP_GETUPVAR, 0x03, 0x01, 0x01, // 008 GETUPVAR R3 1 1 + OP_SEND, 0x02, 0x00, 0x01, // 012 SEND R2 :call n=1 + OP_RETURN, 0x02, // 016 RETURN R2 +}; static const mrb_irep catch_irep_3 = { 2,5,0, MRB_IREP_STATIC,catch_iseq_3, @@ -26,10 +26,11 @@ static const mrb_irep *catch_reps_2[1] = { &catch_irep_3, }; static const mrb_code catch_iseq_2[13] = { - OP_ENTER, 0x00, 0x00, 0x00, - OP_LAMBDA, 0x02, 0x00, - OP_SEND, 0x02, 0x00, 0x00, - OP_RETURN, 0x02,}; + OP_ENTER, 0x00, 0x00, 0x00, // 000 ENTER 0:0:0:0:0:0:0 (0x0) + OP_LAMBDA, 0x02, 0x00, // 004 LAMBDA R2 I[0] + OP_SEND, 0x02, 0x00, 0x00, // 007 SEND R2 :call n=0 + OP_RETURN, 0x02, // 011 RETURN R2 +}; static const mrb_irep catch_irep_2 = { 2,4,0, MRB_IREP_STATIC,catch_iseq_2, @@ -43,15 +44,16 @@ static const mrb_irep *catch_reps_1[1] = { }; MRB_PRESYM_DEFINE_VAR_AND_INITER(catch_syms_1, 3, MRB_SYM(Object), MRB_SYM(new), MRB_SYM(call)) static const mrb_code catch_iseq_1[29] = { - OP_ENTER, 0x00, 0x20, 0x01, - OP_JMP, 0x00, 0x03, - OP_JMP, 0x00, 0x0a, - OP_GETCONST, 0x03, 0x00, - OP_SEND, 0x03, 0x01, 0x00, - OP_MOVE, 0x01, 0x03, - OP_LAMBDA, 0x03, 0x00, - OP_SEND, 0x03, 0x02, 0x00, - OP_RETURN, 0x03,}; + OP_ENTER, 0x00, 0x20, 0x01, // 000 ENTER 0:1:0:0:0:0:1 (0x2001) + OP_JMP, 0x00, 0x03, // 004 JMP 010 + OP_JMP, 0x00, 0x0a, // 007 JMP 020 + OP_GETCONST, 0x03, 0x00, // 010 GETCONST R3 Object + OP_SEND, 0x03, 0x01, 0x00, // 013 SEND R3 :new n=0 + OP_MOVE, 0x01, 0x03, // 017 MOVE R1 R3 + OP_LAMBDA, 0x03, 0x00, // 020 LAMBDA R3 I[0] + OP_SEND, 0x03, 0x02, 0x00, // 023 SEND R3 :call n=0 + OP_RETURN, 0x03, // 027 RETURN R3 +}; static const mrb_irep catch_irep = { 3,5,0, MRB_IREP_STATIC,catch_iseq_1, @@ -60,7 +62,6 @@ static const mrb_irep catch_irep = { NULL, 29,0,3,1,0 }; - static const struct RProc catch_proc = { NULL, NULL, MRB_TT_PROC, MRB_GC_RED, MRB_FL_OBJ_IS_FROZEN | MRB_PROC_SCOPE | MRB_PROC_STRICT, { &catch_irep }, NULL, { NULL } @@ -83,7 +84,7 @@ find_catcher(mrb_state *mrb, mrb_value tag) } static mrb_value -mrb_f_throw(mrb_state *mrb, mrb_value self) +throw_m(mrb_state *mrb, mrb_value self) { mrb_value tag, obj; if (mrb_get_args(mrb, "o|o", &tag, &obj) == 1) { @@ -115,7 +116,7 @@ mrb_mruby_catch_gem_init(mrb_state *mrb) MRB_METHOD_FROM_PROC(m, &catch_proc); mrb_define_method_raw(mrb, mrb->kernel_module, MRB_SYM(catch), m); - mrb_define_method(mrb, mrb->kernel_module, "throw", mrb_f_throw, MRB_ARGS_ARG(1,1)); + mrb_define_method(mrb, mrb->kernel_module, "throw", throw_m, MRB_ARGS_ARG(1,1)); } void diff --git a/mruby/mrbgems/mruby-class-ext/src/class.c b/mruby/mrbgems/mruby-class-ext/src/class.c index dbe06152..0fa0a4af 100644 --- a/mruby/mrbgems/mruby-class-ext/src/class.c +++ b/mruby/mrbgems/mruby-class-ext/src/class.c @@ -7,7 +7,7 @@ #include "mruby/presym.h" static mrb_value -mrb_mod_name(mrb_state *mrb, mrb_value self) +mod_name(mrb_state *mrb, mrb_value self) { mrb_value name = mrb_class_path(mrb, mrb_class_ptr(self)); if (mrb_string_p(name)) { @@ -17,7 +17,7 @@ mrb_mod_name(mrb_state *mrb, mrb_value self) } static mrb_value -mrb_mod_singleton_class_p(mrb_state *mrb, mrb_value self) +mod_singleton_class_p(mrb_state *mrb, mrb_value self) { return mrb_bool_value(mrb_sclass_p(self)); } @@ -42,7 +42,7 @@ mrb_mod_singleton_class_p(mrb_state *mrb, mrb_value self) */ static mrb_value -mrb_mod_module_exec(mrb_state *mrb, mrb_value self) +mod_module_exec(mrb_state *mrb, mrb_value self) { const mrb_value *argv; mrb_int argc; @@ -95,7 +95,7 @@ add_subclasses(mrb_state *mrb, struct RBasic *obj, void *data) * C.subclasses #=> [] */ static mrb_value -mrb_class_subclasses(mrb_state *mrb, mrb_value self) +class_subclasses(mrb_state *mrb, mrb_value self) { struct RClass *c; mrb_value ary; @@ -126,7 +126,7 @@ mrb_class_subclasses(mrb_state *mrb, mrb_value self) * NilClass.attached_object #=> TypeError: not a singleton class */ static mrb_value -mrb_class_attached_object(mrb_state *mrb, mrb_value self) +class_attached_object(mrb_state *mrb, mrb_value self) { struct RClass *c; @@ -142,14 +142,14 @@ mrb_mruby_class_ext_gem_init(mrb_state *mrb) { struct RClass *mod = mrb->module_class; - mrb_define_method(mrb, mod, "name", mrb_mod_name, MRB_ARGS_NONE()); - 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()); + mrb_define_method(mrb, mod, "name", mod_name, MRB_ARGS_NONE()); + mrb_define_method(mrb, mod, "singleton_class?", mod_singleton_class_p, MRB_ARGS_NONE()); + mrb_define_method(mrb, mod, "module_exec", mod_module_exec, MRB_ARGS_ANY()|MRB_ARGS_BLOCK()); + mrb_define_method(mrb, mod, "class_exec", mod_module_exec, MRB_ARGS_ANY()|MRB_ARGS_BLOCK()); struct RClass *cls = mrb->class_class; - mrb_define_method(mrb, cls, "subclasses", mrb_class_subclasses, MRB_ARGS_NONE()); - mrb_define_method(mrb, cls, "attached_object", mrb_class_attached_object, MRB_ARGS_NONE()); + mrb_define_method(mrb, cls, "subclasses", class_subclasses, MRB_ARGS_NONE()); + mrb_define_method(mrb, cls, "attached_object", class_attached_object, MRB_ARGS_NONE()); } void diff --git a/mruby/mrbgems/mruby-cmath/src/cmath.c b/mruby/mrbgems/mruby-cmath/src/cmath.c index de59adf9..b0b8d5f1 100644 --- a/mruby/mrbgems/mruby-cmath/src/cmath.c +++ b/mruby/mrbgems/mruby-cmath/src/cmath.c @@ -33,7 +33,7 @@ cmath_get_complex(mrb_state *mrb, mrb_value c, mrb_float *r, mrb_float *i) *i = 0; return FALSE; } - else if (mrb_obj_is_kind_of(mrb, c, mrb_class_get(mrb, "Complex"))) { + else if (mrb_type(c) == MRB_TT_COMPLEX) { mrb_complex_get(mrb, c, r, i); return TRUE; } @@ -76,13 +76,13 @@ CXDIVc(mrb_complex a, mrb_complex b) if ((abi = cimag(b)) < 0) abi = - abi; if (abr <= abi) { - ratio = creal(b) / cimag(b) ; + ratio = creal(b) / cimag(b); den = cimag(a) * (1 + ratio*ratio); cr = (creal(a)*ratio + cimag(a)) / den; ci = (cimag(a)*ratio - creal(a)) / den; } else { - ratio = cimag(b) / creal(b) ; + ratio = cimag(b) / creal(b); den = creal(a) * (1 + ratio*ratio); cr = (creal(a) + cimag(a)*ratio) / den; ci = (cimag(a) - creal(a)*ratio) / den; diff --git a/mruby/mrbgems/mruby-compar-ext/mrblib/compar.rb b/mruby/mrbgems/mruby-compar-ext/mrblib/compar.rb index 18bba791..cc40223d 100644 --- a/mruby/mrbgems/mruby-compar-ext/mrblib/compar.rb +++ b/mruby/mrbgems/mruby-compar-ext/mrblib/compar.rb @@ -53,8 +53,17 @@ def clamp(min, max=nil) if min.nil? min = self end + elsif min.nil? or min < self + return self else - raise TypeError, "wrong argument type #{min.class}" + return min + end + end + if min.nil? + if self < max + return self + else + return max end end c = min <=> max diff --git a/mruby/mrbgems/mruby-compiler/core/codegen.c b/mruby/mrbgems/mruby-compiler/core/codegen.c index 41e269e6..7315832b 100644 --- a/mruby/mrbgems/mruby-compiler/core/codegen.c +++ b/mruby/mrbgems/mruby-compiler/core/codegen.c @@ -771,7 +771,7 @@ get_int_operand(codegen_scope *s, struct mrb_insn_data *data, mrb_int *n) return TRUE; case OP_LOADI32: - *n = (mrb_int)((uint32_t)data->b<<16)+data->c; + *n = (int32_t)((uint32_t)data->b<<16)+data->c; return TRUE; case OP_LOADL: diff --git a/mruby/mrbgems/mruby-compiler/core/parse.y b/mruby/mrbgems/mruby-compiler/core/parse.y index 20d86480..d8760550 100644 --- a/mruby/mrbgems/mruby-compiler/core/parse.y +++ b/mruby/mrbgems/mruby-compiler/core/parse.y @@ -139,7 +139,7 @@ cons_gen(parser_state *p, node *car, node *cdr) c->filename_index = p->current_filename_index; /* beginning of next partial file; need to point the previous file */ if (p->lineno == 0 && p->current_filename_index > 0) { - c->filename_index-- ; + c->filename_index--; } return c; } @@ -1101,8 +1101,8 @@ concat_string(parser_state *p, node *a, node *b) } else { node *c; /* last node of a */ - for (c = a; c->cdr != NULL; c = c->cdr) ; - + for (c = a; c->cdr != NULL; c = c->cdr) + ; if (string_node_p(b)) { /* a == NODE_DSTR && b == NODE_STR */ if (string_node_p(c->car)) { @@ -1460,56 +1460,56 @@ heredoc_end(parser_state *p) } %token - keyword_class - keyword_module - keyword_def - keyword_begin - keyword_if - keyword_unless - keyword_while - keyword_until - keyword_for + keyword_class "'class'" + keyword_module "'module'" + keyword_def "'def'" + keyword_begin "'begin'" + keyword_if "'if'" + keyword_unless "'unless'" + keyword_while "'while'" + keyword_until "'until'" + keyword_for "'for'" %token - keyword_undef - keyword_rescue - keyword_ensure - keyword_end - keyword_then - keyword_elsif - keyword_else - keyword_case - keyword_when - keyword_break - keyword_next - keyword_redo - keyword_retry - keyword_in - keyword_do - keyword_do_cond - keyword_do_block - keyword_do_LAMBDA - keyword_return - keyword_yield - keyword_super - keyword_self - keyword_nil - keyword_true - keyword_false - keyword_and - keyword_or - keyword_not - modifier_if - modifier_unless - modifier_while - modifier_until - modifier_rescue - keyword_alias - keyword_BEGIN - keyword_END - keyword__LINE__ - keyword__FILE__ - keyword__ENCODING__ + keyword_undef "'undef'" + keyword_rescue "'rescue'" + keyword_ensure "'ensure'" + keyword_end "'end'" + keyword_then "'then'" + keyword_elsif "'elsif'" + keyword_else "'else'" + keyword_case "'case'" + keyword_when "'when'" + keyword_break "'break'" + keyword_next "'next'" + keyword_redo "'redo'" + keyword_retry "'retry'" + keyword_in "'in'" + keyword_do "'do'" + keyword_do_cond "'do' for condition" + keyword_do_block "'do' for block" + keyword_do_LAMBDA "'do' for lambda" + keyword_return "'return'" + keyword_yield "'yield'" + keyword_super "'super'" + keyword_self "'self'" + keyword_nil "'nil'" + keyword_true "'true'" + keyword_false "'false'" + keyword_and "'and'" + keyword_or "'or'" + keyword_not "'not'" + modifier_if "'if' modifier" + modifier_unless "'unless' modifier" + modifier_while "'while' modifier" + modifier_until "'until' modifier" + modifier_rescue "'rescue' modifier" + keyword_alias "'alis'" + keyword_BEGIN "'BEGIN'" + keyword_END "'END'" + keyword__LINE__ "'__LINE__'" + keyword__FILE__ "'__FILE__'" + keyword__ENCODING__ "'__ENCODING__'" %token tIDENTIFIER "local variable or method" %token tFID "method" @@ -3175,12 +3175,14 @@ do_block : keyword_do_block { local_nest(p); nvars_nest(p); + $$ = p->lineno; } opt_block_param bodystmt keyword_end { $$ = new_block(p,$3,$4); + SET_LINENO($$, $2); local_unnest(p); nvars_unnest(p); } @@ -4826,7 +4828,8 @@ heredoc_remove_indent(parser_state *p, parser_heredoc_info *hinfo) newstr[newlen] = '\0'; pair->car = (node*)newstr; pair->cdr = (node*)newlen; - } else { + } + else { spaces = (size_t)nspaces->car; heredoc_count_indent(hinfo, str, len, spaces, &offset); pair->car = (node*)(str + offset); @@ -4901,7 +4904,8 @@ parse_string(parser_state *p) if (sizeof(s1)+sizeof(s2)+strlen(hinfo->term)+1 >= sizeof(buf)) { yyerror(p, "can't find heredoc delimiter anywhere before EOF"); - } else { + } + else { strcpy(buf, s1); strcat(buf, hinfo->term); strcat(buf, s2); @@ -6737,8 +6741,9 @@ mrbc_filename(mrb_state *mrb, mrbc_context *c, const char *s) { if (s) { size_t len = strlen(s); - char *p = (char*)mrb_malloc(mrb, len + 1); + char *p = (char*)mrb_malloc_simple(mrb, len + 1); + if (p == NULL) return NULL; memcpy(p, s, len + 1); if (c->filename) { mrb_free(mrb, c->filename); diff --git a/mruby/mrbgems/mruby-compiler/core/y.tab.c b/mruby/mrbgems/mruby-compiler/core/y.tab.c index 794b5cf9..2ab6fbc5 100644 --- a/mruby/mrbgems/mruby-compiler/core/y.tab.c +++ b/mruby/mrbgems/mruby-compiler/core/y.tab.c @@ -203,7 +203,7 @@ cons_gen(parser_state *p, node *car, node *cdr) c->filename_index = p->current_filename_index; /* beginning of next partial file; need to point the previous file */ if (p->lineno == 0 && p->current_filename_index > 0) { - c->filename_index-- ; + c->filename_index--; } return c; } @@ -1165,8 +1165,8 @@ concat_string(parser_state *p, node *a, node *b) } else { node *c; /* last node of a */ - for (c = a; c->cdr != NULL; c = c->cdr) ; - + for (c = a; c->cdr != NULL; c = c->cdr) + ; if (string_node_p(b)) { /* a == NODE_DSTR && b == NODE_STR */ if (string_node_p(c->car)) { @@ -1550,54 +1550,54 @@ extern int yydebug; YYEOF = 0, /* "end of file" */ YYerror = 256, /* error */ YYUNDEF = 257, /* "invalid token" */ - keyword_class = 258, /* keyword_class */ - keyword_module = 259, /* keyword_module */ - keyword_def = 260, /* keyword_def */ - keyword_begin = 261, /* keyword_begin */ - keyword_if = 262, /* keyword_if */ - keyword_unless = 263, /* keyword_unless */ - keyword_while = 264, /* keyword_while */ - keyword_until = 265, /* keyword_until */ - keyword_for = 266, /* keyword_for */ - keyword_undef = 267, /* keyword_undef */ - keyword_rescue = 268, /* keyword_rescue */ - keyword_ensure = 269, /* keyword_ensure */ - keyword_end = 270, /* keyword_end */ - keyword_then = 271, /* keyword_then */ - keyword_elsif = 272, /* keyword_elsif */ - keyword_else = 273, /* keyword_else */ - keyword_case = 274, /* keyword_case */ - keyword_when = 275, /* keyword_when */ - keyword_break = 276, /* keyword_break */ - keyword_next = 277, /* keyword_next */ - keyword_redo = 278, /* keyword_redo */ - keyword_retry = 279, /* keyword_retry */ - keyword_in = 280, /* keyword_in */ - keyword_do = 281, /* keyword_do */ - keyword_do_cond = 282, /* keyword_do_cond */ - keyword_do_block = 283, /* keyword_do_block */ - keyword_do_LAMBDA = 284, /* keyword_do_LAMBDA */ - keyword_return = 285, /* keyword_return */ - keyword_yield = 286, /* keyword_yield */ - keyword_super = 287, /* keyword_super */ - keyword_self = 288, /* keyword_self */ - keyword_nil = 289, /* keyword_nil */ - keyword_true = 290, /* keyword_true */ - keyword_false = 291, /* keyword_false */ - keyword_and = 292, /* keyword_and */ - keyword_or = 293, /* keyword_or */ - keyword_not = 294, /* keyword_not */ - modifier_if = 295, /* modifier_if */ - modifier_unless = 296, /* modifier_unless */ - modifier_while = 297, /* modifier_while */ - modifier_until = 298, /* modifier_until */ - modifier_rescue = 299, /* modifier_rescue */ - keyword_alias = 300, /* keyword_alias */ - keyword_BEGIN = 301, /* keyword_BEGIN */ - keyword_END = 302, /* keyword_END */ - keyword__LINE__ = 303, /* keyword__LINE__ */ - keyword__FILE__ = 304, /* keyword__FILE__ */ - keyword__ENCODING__ = 305, /* keyword__ENCODING__ */ + keyword_class = 258, /* "'class'" */ + keyword_module = 259, /* "'module'" */ + keyword_def = 260, /* "'def'" */ + keyword_begin = 261, /* "'begin'" */ + keyword_if = 262, /* "'if'" */ + keyword_unless = 263, /* "'unless'" */ + keyword_while = 264, /* "'while'" */ + keyword_until = 265, /* "'until'" */ + keyword_for = 266, /* "'for'" */ + keyword_undef = 267, /* "'undef'" */ + keyword_rescue = 268, /* "'rescue'" */ + keyword_ensure = 269, /* "'ensure'" */ + keyword_end = 270, /* "'end'" */ + keyword_then = 271, /* "'then'" */ + keyword_elsif = 272, /* "'elsif'" */ + keyword_else = 273, /* "'else'" */ + keyword_case = 274, /* "'case'" */ + keyword_when = 275, /* "'when'" */ + keyword_break = 276, /* "'break'" */ + keyword_next = 277, /* "'next'" */ + keyword_redo = 278, /* "'redo'" */ + keyword_retry = 279, /* "'retry'" */ + keyword_in = 280, /* "'in'" */ + keyword_do = 281, /* "'do'" */ + keyword_do_cond = 282, /* "'do' for condition" */ + keyword_do_block = 283, /* "'do' for block" */ + keyword_do_LAMBDA = 284, /* "'do' for lambda" */ + keyword_return = 285, /* "'return'" */ + keyword_yield = 286, /* "'yield'" */ + keyword_super = 287, /* "'super'" */ + keyword_self = 288, /* "'self'" */ + keyword_nil = 289, /* "'nil'" */ + keyword_true = 290, /* "'true'" */ + keyword_false = 291, /* "'false'" */ + keyword_and = 292, /* "'and'" */ + keyword_or = 293, /* "'or'" */ + keyword_not = 294, /* "'not'" */ + modifier_if = 295, /* "'if' modifier" */ + modifier_unless = 296, /* "'unless' modifier" */ + modifier_while = 297, /* "'while' modifier" */ + modifier_until = 298, /* "'until' modifier" */ + modifier_rescue = 299, /* "'rescue' modifier" */ + keyword_alias = 300, /* "'alis'" */ + keyword_BEGIN = 301, /* "'BEGIN'" */ + keyword_END = 302, /* "'END'" */ + keyword__LINE__ = 303, /* "'__LINE__'" */ + keyword__FILE__ = 304, /* "'__FILE__'" */ + keyword__ENCODING__ = 305, /* "'__ENCODING__'" */ tIDENTIFIER = 306, /* "local variable or method" */ tFID = 307, /* "method" */ tGVAR = 308, /* "global variable" */ @@ -1708,54 +1708,54 @@ enum yysymbol_kind_t YYSYMBOL_YYEOF = 0, /* "end of file" */ YYSYMBOL_YYerror = 1, /* error */ YYSYMBOL_YYUNDEF = 2, /* "invalid token" */ - YYSYMBOL_keyword_class = 3, /* keyword_class */ - YYSYMBOL_keyword_module = 4, /* keyword_module */ - YYSYMBOL_keyword_def = 5, /* keyword_def */ - YYSYMBOL_keyword_begin = 6, /* keyword_begin */ - YYSYMBOL_keyword_if = 7, /* keyword_if */ - YYSYMBOL_keyword_unless = 8, /* keyword_unless */ - YYSYMBOL_keyword_while = 9, /* keyword_while */ - YYSYMBOL_keyword_until = 10, /* keyword_until */ - YYSYMBOL_keyword_for = 11, /* keyword_for */ - YYSYMBOL_keyword_undef = 12, /* keyword_undef */ - YYSYMBOL_keyword_rescue = 13, /* keyword_rescue */ - YYSYMBOL_keyword_ensure = 14, /* keyword_ensure */ - YYSYMBOL_keyword_end = 15, /* keyword_end */ - YYSYMBOL_keyword_then = 16, /* keyword_then */ - YYSYMBOL_keyword_elsif = 17, /* keyword_elsif */ - YYSYMBOL_keyword_else = 18, /* keyword_else */ - YYSYMBOL_keyword_case = 19, /* keyword_case */ - YYSYMBOL_keyword_when = 20, /* keyword_when */ - YYSYMBOL_keyword_break = 21, /* keyword_break */ - YYSYMBOL_keyword_next = 22, /* keyword_next */ - YYSYMBOL_keyword_redo = 23, /* keyword_redo */ - YYSYMBOL_keyword_retry = 24, /* keyword_retry */ - YYSYMBOL_keyword_in = 25, /* keyword_in */ - YYSYMBOL_keyword_do = 26, /* keyword_do */ - YYSYMBOL_keyword_do_cond = 27, /* keyword_do_cond */ - YYSYMBOL_keyword_do_block = 28, /* keyword_do_block */ - YYSYMBOL_keyword_do_LAMBDA = 29, /* keyword_do_LAMBDA */ - YYSYMBOL_keyword_return = 30, /* keyword_return */ - YYSYMBOL_keyword_yield = 31, /* keyword_yield */ - YYSYMBOL_keyword_super = 32, /* keyword_super */ - YYSYMBOL_keyword_self = 33, /* keyword_self */ - YYSYMBOL_keyword_nil = 34, /* keyword_nil */ - YYSYMBOL_keyword_true = 35, /* keyword_true */ - YYSYMBOL_keyword_false = 36, /* keyword_false */ - YYSYMBOL_keyword_and = 37, /* keyword_and */ - YYSYMBOL_keyword_or = 38, /* keyword_or */ - YYSYMBOL_keyword_not = 39, /* keyword_not */ - YYSYMBOL_modifier_if = 40, /* modifier_if */ - YYSYMBOL_modifier_unless = 41, /* modifier_unless */ - YYSYMBOL_modifier_while = 42, /* modifier_while */ - YYSYMBOL_modifier_until = 43, /* modifier_until */ - YYSYMBOL_modifier_rescue = 44, /* modifier_rescue */ - YYSYMBOL_keyword_alias = 45, /* keyword_alias */ - YYSYMBOL_keyword_BEGIN = 46, /* keyword_BEGIN */ - YYSYMBOL_keyword_END = 47, /* keyword_END */ - YYSYMBOL_keyword__LINE__ = 48, /* keyword__LINE__ */ - YYSYMBOL_keyword__FILE__ = 49, /* keyword__FILE__ */ - YYSYMBOL_keyword__ENCODING__ = 50, /* keyword__ENCODING__ */ + YYSYMBOL_keyword_class = 3, /* "'class'" */ + YYSYMBOL_keyword_module = 4, /* "'module'" */ + YYSYMBOL_keyword_def = 5, /* "'def'" */ + YYSYMBOL_keyword_begin = 6, /* "'begin'" */ + YYSYMBOL_keyword_if = 7, /* "'if'" */ + YYSYMBOL_keyword_unless = 8, /* "'unless'" */ + YYSYMBOL_keyword_while = 9, /* "'while'" */ + YYSYMBOL_keyword_until = 10, /* "'until'" */ + YYSYMBOL_keyword_for = 11, /* "'for'" */ + YYSYMBOL_keyword_undef = 12, /* "'undef'" */ + YYSYMBOL_keyword_rescue = 13, /* "'rescue'" */ + YYSYMBOL_keyword_ensure = 14, /* "'ensure'" */ + YYSYMBOL_keyword_end = 15, /* "'end'" */ + YYSYMBOL_keyword_then = 16, /* "'then'" */ + YYSYMBOL_keyword_elsif = 17, /* "'elsif'" */ + YYSYMBOL_keyword_else = 18, /* "'else'" */ + YYSYMBOL_keyword_case = 19, /* "'case'" */ + YYSYMBOL_keyword_when = 20, /* "'when'" */ + YYSYMBOL_keyword_break = 21, /* "'break'" */ + YYSYMBOL_keyword_next = 22, /* "'next'" */ + YYSYMBOL_keyword_redo = 23, /* "'redo'" */ + YYSYMBOL_keyword_retry = 24, /* "'retry'" */ + YYSYMBOL_keyword_in = 25, /* "'in'" */ + YYSYMBOL_keyword_do = 26, /* "'do'" */ + YYSYMBOL_keyword_do_cond = 27, /* "'do' for condition" */ + YYSYMBOL_keyword_do_block = 28, /* "'do' for block" */ + YYSYMBOL_keyword_do_LAMBDA = 29, /* "'do' for lambda" */ + YYSYMBOL_keyword_return = 30, /* "'return'" */ + YYSYMBOL_keyword_yield = 31, /* "'yield'" */ + YYSYMBOL_keyword_super = 32, /* "'super'" */ + YYSYMBOL_keyword_self = 33, /* "'self'" */ + YYSYMBOL_keyword_nil = 34, /* "'nil'" */ + YYSYMBOL_keyword_true = 35, /* "'true'" */ + YYSYMBOL_keyword_false = 36, /* "'false'" */ + YYSYMBOL_keyword_and = 37, /* "'and'" */ + YYSYMBOL_keyword_or = 38, /* "'or'" */ + YYSYMBOL_keyword_not = 39, /* "'not'" */ + YYSYMBOL_modifier_if = 40, /* "'if' modifier" */ + YYSYMBOL_modifier_unless = 41, /* "'unless' modifier" */ + YYSYMBOL_modifier_while = 42, /* "'while' modifier" */ + YYSYMBOL_modifier_until = 43, /* "'until' modifier" */ + YYSYMBOL_modifier_rescue = 44, /* "'rescue' modifier" */ + YYSYMBOL_keyword_alias = 45, /* "'alis'" */ + YYSYMBOL_keyword_BEGIN = 46, /* "'BEGIN'" */ + YYSYMBOL_keyword_END = 47, /* "'END'" */ + YYSYMBOL_keyword__LINE__ = 48, /* "'__LINE__'" */ + YYSYMBOL_keyword__FILE__ = 49, /* "'__FILE__'" */ + YYSYMBOL_keyword__ENCODING__ = 50, /* "'__ENCODING__'" */ YYSYMBOL_tIDENTIFIER = 51, /* "local variable or method" */ YYSYMBOL_tFID = 52, /* "method" */ YYSYMBOL_tGVAR = 53, /* "global variable" */ @@ -1945,7 +1945,7 @@ enum yysymbol_kind_t YYSYMBOL_f_larglist = 237, /* f_larglist */ YYSYMBOL_lambda_body = 238, /* lambda_body */ YYSYMBOL_do_block = 239, /* do_block */ - YYSYMBOL_240_26 = 240, /* $@26 */ + YYSYMBOL_240_26 = 240, /* @26 */ YYSYMBOL_block_call = 241, /* block_call */ YYSYMBOL_method_call = 242, /* method_call */ YYSYMBOL_brace_block = 243, /* brace_block */ @@ -2467,28 +2467,28 @@ static const yytype_int16 yyrline[] = 3037, 3042, 3046, 3050, 3054, 3058, 3062, 3066, 3070, 3074, 3078, 3082, 3086, 3090, 3094, 3098, 3104, 3109, 3116, 3116, 3120, 3125, 3132, 3136, 3142, 3143, 3146, 3151, 3154, 3158, - 3164, 3168, 3175, 3174, 3189, 3199, 3203, 3208, 3215, 3219, - 3223, 3227, 3231, 3235, 3239, 3243, 3247, 3254, 3253, 3268, - 3267, 3283, 3291, 3300, 3303, 3310, 3313, 3317, 3318, 3321, - 3325, 3328, 3332, 3335, 3336, 3337, 3338, 3341, 3342, 3348, - 3349, 3350, 3354, 3367, 3368, 3374, 3379, 3378, 3388, 3392, - 3398, 3402, 3415, 3419, 3425, 3428, 3429, 3432, 3438, 3444, - 3445, 3448, 3455, 3454, 3467, 3471, 3485, 3490, 3504, 3510, - 3511, 3512, 3513, 3514, 3518, 3524, 3528, 3538, 3539, 3540, - 3544, 3550, 3554, 3558, 3562, 3566, 3572, 3576, 3582, 3586, - 3590, 3594, 3598, 3602, 3610, 3617, 3623, 3624, 3628, 3632, - 3631, 3648, 3649, 3652, 3658, 3662, 3668, 3669, 3673, 3677, - 3683, 3687, 3693, 3699, 3706, 3712, 3719, 3723, 3729, 3733, - 3739, 3740, 3743, 3747, 3753, 3757, 3761, 3765, 3771, 3776, - 3781, 3785, 3789, 3793, 3797, 3801, 3805, 3809, 3813, 3817, - 3821, 3825, 3829, 3833, 3838, 3844, 3849, 3854, 3859, 3864, - 3871, 3875, 3882, 3887, 3886, 3898, 3902, 3908, 3916, 3924, - 3932, 3936, 3942, 3946, 3952, 3953, 3956, 3961, 3968, 3969, - 3972, 3976, 3982, 3986, 3992, 3997, 3997, 4022, 4023, 4029, - 4034, 4040, 4046, 4051, 4055, 4060, 4065, 4075, 4080, 4086, - 4087, 4088, 4091, 4092, 4093, 4094, 4097, 4098, 4099, 4102, - 4103, 4106, 4110, 4116, 4117, 4123, 4124, 4127, 4128, 4131, - 4134, 4135, 4136, 4139, 4140, 4143, 4148, 4151, 4152, 4156 + 3164, 3168, 3175, 3174, 3191, 3201, 3205, 3210, 3217, 3221, + 3225, 3229, 3233, 3237, 3241, 3245, 3249, 3256, 3255, 3270, + 3269, 3285, 3293, 3302, 3305, 3312, 3315, 3319, 3320, 3323, + 3327, 3330, 3334, 3337, 3338, 3339, 3340, 3343, 3344, 3350, + 3351, 3352, 3356, 3369, 3370, 3376, 3381, 3380, 3390, 3394, + 3400, 3404, 3417, 3421, 3427, 3430, 3431, 3434, 3440, 3446, + 3447, 3450, 3457, 3456, 3469, 3473, 3487, 3492, 3506, 3512, + 3513, 3514, 3515, 3516, 3520, 3526, 3530, 3540, 3541, 3542, + 3546, 3552, 3556, 3560, 3564, 3568, 3574, 3578, 3584, 3588, + 3592, 3596, 3600, 3604, 3612, 3619, 3625, 3626, 3630, 3634, + 3633, 3650, 3651, 3654, 3660, 3664, 3670, 3671, 3675, 3679, + 3685, 3689, 3695, 3701, 3708, 3714, 3721, 3725, 3731, 3735, + 3741, 3742, 3745, 3749, 3755, 3759, 3763, 3767, 3773, 3778, + 3783, 3787, 3791, 3795, 3799, 3803, 3807, 3811, 3815, 3819, + 3823, 3827, 3831, 3835, 3840, 3846, 3851, 3856, 3861, 3866, + 3873, 3877, 3884, 3889, 3888, 3900, 3904, 3910, 3918, 3926, + 3934, 3938, 3944, 3948, 3954, 3955, 3958, 3963, 3970, 3971, + 3974, 3978, 3984, 3988, 3994, 3999, 3999, 4024, 4025, 4031, + 4036, 4042, 4048, 4053, 4057, 4062, 4067, 4077, 4082, 4088, + 4089, 4090, 4093, 4094, 4095, 4096, 4099, 4100, 4101, 4104, + 4105, 4108, 4112, 4118, 4119, 4125, 4126, 4129, 4130, 4133, + 4136, 4137, 4138, 4141, 4142, 4145, 4150, 4153, 4154, 4158 }; #endif @@ -2504,68 +2504,67 @@ static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED; First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { - "\"end of file\"", "error", "\"invalid token\"", "keyword_class", - "keyword_module", "keyword_def", "keyword_begin", "keyword_if", - "keyword_unless", "keyword_while", "keyword_until", "keyword_for", - "keyword_undef", "keyword_rescue", "keyword_ensure", "keyword_end", - "keyword_then", "keyword_elsif", "keyword_else", "keyword_case", - "keyword_when", "keyword_break", "keyword_next", "keyword_redo", - "keyword_retry", "keyword_in", "keyword_do", "keyword_do_cond", - "keyword_do_block", "keyword_do_LAMBDA", "keyword_return", - "keyword_yield", "keyword_super", "keyword_self", "keyword_nil", - "keyword_true", "keyword_false", "keyword_and", "keyword_or", - "keyword_not", "modifier_if", "modifier_unless", "modifier_while", - "modifier_until", "modifier_rescue", "keyword_alias", "keyword_BEGIN", - "keyword_END", "keyword__LINE__", "keyword__FILE__", - "keyword__ENCODING__", "\"local variable or method\"", "\"method\"", - "\"global variable\"", "\"instance variable\"", "\"constant\"", - "\"class variable\"", "\"label\"", "\"integer literal\"", - "\"float literal\"", "\"character literal\"", "tXSTRING", "tREGEXP", - "tSTRING", "tSTRING_PART", "tSTRING_MID", "tNTH_REF", "tBACK_REF", - "tREGEXP_END", "\"numbered parameter\"", "\"unary plus\"", - "\"unary minus\"", "\"<=>\"", "\"==\"", "\"===\"", "\"!=\"", "\">=\"", - "\"<=\"", "\"&&\"", "\"||\"", "\"=~\"", "\"!~\"", "\"..\"", "\"...\"", - "tBDOT2", "tBDOT3", "tAREF", "tASET", "\"<<\"", "\">>\"", "\"::\"", - "tCOLON3", "tOP_ASGN", "\"=>\"", "tLPAREN", "\"(\"", "\")\"", "\"[\"", - "tLBRACE", "\"{\"", "\"*\"", "tPOW", "\"**\"", "\"&\"", "\"->\"", - "\"&.\"", "\"symbol\"", "\"string literal\"", "tXSTRING_BEG", - "tSTRING_DVAR", "tREGEXP_BEG", "tWORDS_BEG", "tSYMBOLS_BEG", "tLAMBEG", - "\"here document\"", "tHEREDOC_END", "tLITERAL_DELIM", - "tHD_LITERAL_DELIM", "tHD_STRING_PART", "tHD_STRING_MID", "tLOWEST", - "'='", "'?'", "':'", "'>'", "'<'", "'|'", "'^'", "'&'", "'+'", "'-'", - "'*'", "'/'", "'%'", "tUMINUS_NUM", "'!'", "'~'", "tLAST_TOKEN", "'{'", - "'}'", "'['", "']'", "','", "'`'", "'('", "')'", "';'", "'.'", "'\\n'", - "$accept", "program", "$@1", "top_compstmt", "top_stmts", "top_stmt", - "@2", "bodystmt", "compstmt", "stmts", "stmt", "$@3", "command_asgn", - "command_rhs", "expr", "defn_head", "defs_head", "$@4", "expr_value", - "command_call", "block_command", "cmd_brace_block", "$@5", "command", - "mlhs", "mlhs_inner", "mlhs_basic", "mlhs_item", "mlhs_list", - "mlhs_post", "mlhs_node", "lhs", "cname", "cpath", "fname", "fsym", - "undef_list", "$@6", "op", "reswords", "arg", "aref_args", "arg_rhs", - "paren_args", "opt_paren_args", "opt_call_args", "call_args", - "command_args", "@7", "block_arg", "opt_block_arg", "comma", "args", - "mrhs", "primary", "@8", "@9", "$@10", "$@11", "@12", "@13", "$@14", - "$@15", "$@16", "$@17", "$@18", "$@19", "@20", "@21", "@22", "@23", - "primary_value", "then", "do", "if_tail", "opt_else", "for_var", - "f_margs", "$@24", "block_args_tail", "opt_block_args_tail", - "block_param", "opt_block_param", "block_param_def", "$@25", - "opt_bv_decl", "bv_decls", "bvar", "f_larglist", "lambda_body", - "do_block", "$@26", "block_call", "method_call", "brace_block", "@27", - "@28", "case_body", "cases", "opt_rescue", "exc_list", "exc_var", - "opt_ensure", "literal", "string", "string_fragment", "string_rep", - "string_interp", "@29", "xstring", "regexp", "heredoc", "heredoc_bodies", - "heredoc_body", "heredoc_string_rep", "heredoc_string_interp", "@30", - "words", "symbol", "basic_symbol", "sym", "symbols", "numeric", - "variable", "var_lhs", "var_ref", "backref", "superclass", "$@31", - "f_opt_arglist_paren", "f_arglist_paren", "f_arglist", "f_label", "f_kw", - "f_block_kw", "f_block_kwarg", "f_kwarg", "kwrest_mark", "f_kwrest", - "args_tail", "opt_args_tail", "f_args", "f_bad_arg", "f_norm_arg", - "f_arg_item", "@32", "f_arg", "f_opt_asgn", "f_opt", "f_block_opt", - "f_block_optarg", "f_optarg", "restarg_mark", "f_rest_arg", - "blkarg_mark", "f_block_arg", "opt_f_block_arg", "singleton", "$@33", - "assoc_list", "assocs", "assoc", "operation", "operation2", "operation3", - "dot_or_colon", "call_op", "call_op2", "opt_terms", "opt_nl", "rparen", - "trailer", "term", "nl", "terms", "none", YY_NULLPTR + "\"end of file\"", "error", "\"invalid token\"", "\"'class'\"", + "\"'module'\"", "\"'def'\"", "\"'begin'\"", "\"'if'\"", "\"'unless'\"", + "\"'while'\"", "\"'until'\"", "\"'for'\"", "\"'undef'\"", "\"'rescue'\"", + "\"'ensure'\"", "\"'end'\"", "\"'then'\"", "\"'elsif'\"", "\"'else'\"", + "\"'case'\"", "\"'when'\"", "\"'break'\"", "\"'next'\"", "\"'redo'\"", + "\"'retry'\"", "\"'in'\"", "\"'do'\"", "\"'do' for condition\"", + "\"'do' for block\"", "\"'do' for lambda\"", "\"'return'\"", + "\"'yield'\"", "\"'super'\"", "\"'self'\"", "\"'nil'\"", "\"'true'\"", + "\"'false'\"", "\"'and'\"", "\"'or'\"", "\"'not'\"", "\"'if' modifier\"", + "\"'unless' modifier\"", "\"'while' modifier\"", "\"'until' modifier\"", + "\"'rescue' modifier\"", "\"'alis'\"", "\"'BEGIN'\"", "\"'END'\"", + "\"'__LINE__'\"", "\"'__FILE__'\"", "\"'__ENCODING__'\"", + "\"local variable or method\"", "\"method\"", "\"global variable\"", + "\"instance variable\"", "\"constant\"", "\"class variable\"", + "\"label\"", "\"integer literal\"", "\"float literal\"", + "\"character literal\"", "tXSTRING", "tREGEXP", "tSTRING", + "tSTRING_PART", "tSTRING_MID", "tNTH_REF", "tBACK_REF", "tREGEXP_END", + "\"numbered parameter\"", "\"unary plus\"", "\"unary minus\"", "\"<=>\"", + "\"==\"", "\"===\"", "\"!=\"", "\">=\"", "\"<=\"", "\"&&\"", "\"||\"", + "\"=~\"", "\"!~\"", "\"..\"", "\"...\"", "tBDOT2", "tBDOT3", "tAREF", + "tASET", "\"<<\"", "\">>\"", "\"::\"", "tCOLON3", "tOP_ASGN", "\"=>\"", + "tLPAREN", "\"(\"", "\")\"", "\"[\"", "tLBRACE", "\"{\"", "\"*\"", + "tPOW", "\"**\"", "\"&\"", "\"->\"", "\"&.\"", "\"symbol\"", + "\"string literal\"", "tXSTRING_BEG", "tSTRING_DVAR", "tREGEXP_BEG", + "tWORDS_BEG", "tSYMBOLS_BEG", "tLAMBEG", "\"here document\"", + "tHEREDOC_END", "tLITERAL_DELIM", "tHD_LITERAL_DELIM", "tHD_STRING_PART", + "tHD_STRING_MID", "tLOWEST", "'='", "'?'", "':'", "'>'", "'<'", "'|'", + "'^'", "'&'", "'+'", "'-'", "'*'", "'/'", "'%'", "tUMINUS_NUM", "'!'", + "'~'", "tLAST_TOKEN", "'{'", "'}'", "'['", "']'", "','", "'`'", "'('", + "')'", "';'", "'.'", "'\\n'", "$accept", "program", "$@1", + "top_compstmt", "top_stmts", "top_stmt", "@2", "bodystmt", "compstmt", + "stmts", "stmt", "$@3", "command_asgn", "command_rhs", "expr", + "defn_head", "defs_head", "$@4", "expr_value", "command_call", + "block_command", "cmd_brace_block", "$@5", "command", "mlhs", + "mlhs_inner", "mlhs_basic", "mlhs_item", "mlhs_list", "mlhs_post", + "mlhs_node", "lhs", "cname", "cpath", "fname", "fsym", "undef_list", + "$@6", "op", "reswords", "arg", "aref_args", "arg_rhs", "paren_args", + "opt_paren_args", "opt_call_args", "call_args", "command_args", "@7", + "block_arg", "opt_block_arg", "comma", "args", "mrhs", "primary", "@8", + "@9", "$@10", "$@11", "@12", "@13", "$@14", "$@15", "$@16", "$@17", + "$@18", "$@19", "@20", "@21", "@22", "@23", "primary_value", "then", + "do", "if_tail", "opt_else", "for_var", "f_margs", "$@24", + "block_args_tail", "opt_block_args_tail", "block_param", + "opt_block_param", "block_param_def", "$@25", "opt_bv_decl", "bv_decls", + "bvar", "f_larglist", "lambda_body", "do_block", "@26", "block_call", + "method_call", "brace_block", "@27", "@28", "case_body", "cases", + "opt_rescue", "exc_list", "exc_var", "opt_ensure", "literal", "string", + "string_fragment", "string_rep", "string_interp", "@29", "xstring", + "regexp", "heredoc", "heredoc_bodies", "heredoc_body", + "heredoc_string_rep", "heredoc_string_interp", "@30", "words", "symbol", + "basic_symbol", "sym", "symbols", "numeric", "variable", "var_lhs", + "var_ref", "backref", "superclass", "$@31", "f_opt_arglist_paren", + "f_arglist_paren", "f_arglist", "f_label", "f_kw", "f_block_kw", + "f_block_kwarg", "f_kwarg", "kwrest_mark", "f_kwrest", "args_tail", + "opt_args_tail", "f_args", "f_bad_arg", "f_norm_arg", "f_arg_item", + "@32", "f_arg", "f_opt_asgn", "f_opt", "f_block_opt", "f_block_optarg", + "f_optarg", "restarg_mark", "f_rest_arg", "blkarg_mark", "f_block_arg", + "opt_f_block_arg", "singleton", "$@33", "assoc_list", "assocs", "assoc", + "operation", "operation2", "operation3", "dot_or_colon", "call_op", + "call_op2", "opt_terms", "opt_nl", "rparen", "trailer", "term", "nl", + "terms", "none", YY_NULLPTR }; static const char * @@ -6486,7 +6485,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->lstate = EXPR_BEG; if (!p->locals) p->locals = cons(0,0); } -#line 6490 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6489 "mrbgems/mruby-compiler/core/y.tab.c" break; case 3: /* program: $@1 top_compstmt */ @@ -6495,7 +6494,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->tree = new_scope(p, (yyvsp[0].nd)); NODE_LINENO(p->tree, (yyvsp[0].nd)); } -#line 6499 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6498 "mrbgems/mruby-compiler/core/y.tab.c" break; case 4: /* top_compstmt: top_stmts opt_terms */ @@ -6503,7 +6502,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = (yyvsp[-1].nd); } -#line 6507 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6506 "mrbgems/mruby-compiler/core/y.tab.c" break; case 5: /* top_stmts: none */ @@ -6511,7 +6510,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_begin(p, 0); } -#line 6515 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6514 "mrbgems/mruby-compiler/core/y.tab.c" break; case 6: /* top_stmts: top_stmt */ @@ -6520,7 +6519,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = new_begin(p, (yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 6524 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6523 "mrbgems/mruby-compiler/core/y.tab.c" break; case 7: /* top_stmts: top_stmts terms top_stmt */ @@ -6528,7 +6527,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = push((yyvsp[-2].nd), newline_node((yyvsp[0].nd))); } -#line 6532 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6531 "mrbgems/mruby-compiler/core/y.tab.c" break; case 8: /* top_stmts: error top_stmt */ @@ -6536,7 +6535,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_begin(p, 0); } -#line 6540 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6539 "mrbgems/mruby-compiler/core/y.tab.c" break; case 10: /* @2: %empty */ @@ -6545,10 +6544,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = local_switch(p); nvars_block(p); } -#line 6549 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6548 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 11: /* top_stmt: keyword_BEGIN @2 '{' top_compstmt '}' */ + case 11: /* top_stmt: "'BEGIN'" @2 '{' top_compstmt '}' */ #line 1668 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "BEGIN not supported"); @@ -6556,7 +6555,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); nvars_unnest(p); (yyval.nd) = 0; } -#line 6560 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6559 "mrbgems/mruby-compiler/core/y.tab.c" break; case 12: /* bodystmt: compstmt opt_rescue opt_else opt_ensure */ @@ -6582,7 +6581,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } } } -#line 6586 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6585 "mrbgems/mruby-compiler/core/y.tab.c" break; case 13: /* compstmt: stmts opt_terms */ @@ -6590,7 +6589,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = (yyvsp[-1].nd); } -#line 6594 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6593 "mrbgems/mruby-compiler/core/y.tab.c" break; case 14: /* stmts: none */ @@ -6598,7 +6597,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_begin(p, 0); } -#line 6602 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6601 "mrbgems/mruby-compiler/core/y.tab.c" break; case 15: /* stmts: stmt */ @@ -6607,7 +6606,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = new_begin(p, (yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 6611 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6610 "mrbgems/mruby-compiler/core/y.tab.c" break; case 16: /* stmts: stmts terms stmt */ @@ -6615,7 +6614,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = push((yyvsp[-2].nd), newline_node((yyvsp[0].nd))); } -#line 6619 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6618 "mrbgems/mruby-compiler/core/y.tab.c" break; case 17: /* stmts: error stmt */ @@ -6623,78 +6622,78 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_begin(p, (yyvsp[0].nd)); } -#line 6627 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6626 "mrbgems/mruby-compiler/core/y.tab.c" break; case 18: /* $@3: %empty */ #line 1728 "mrbgems/mruby-compiler/core/parse.y" {p->lstate = EXPR_FNAME;} -#line 6633 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6632 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 19: /* stmt: keyword_alias fsym $@3 fsym */ + case 19: /* stmt: "'alis'" fsym $@3 fsym */ #line 1729 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_alias(p, (yyvsp[-2].id), (yyvsp[0].id)); } -#line 6641 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6640 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 20: /* stmt: keyword_undef undef_list */ + case 20: /* stmt: "'undef'" undef_list */ #line 1733 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 6649 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6648 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 21: /* stmt: stmt modifier_if expr_value */ + case 21: /* stmt: stmt "'if' modifier" expr_value */ #line 1737 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_if(p, cond((yyvsp[0].nd)), (yyvsp[-2].nd), 0); } -#line 6657 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6656 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 22: /* stmt: stmt modifier_unless expr_value */ + case 22: /* stmt: stmt "'unless' modifier" expr_value */ #line 1741 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_unless(p, cond((yyvsp[0].nd)), (yyvsp[-2].nd), 0); } -#line 6665 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6664 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 23: /* stmt: stmt modifier_while expr_value */ + case 23: /* stmt: stmt "'while' modifier" expr_value */ #line 1745 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_while(p, cond((yyvsp[0].nd)), (yyvsp[-2].nd)); } -#line 6673 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6672 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 24: /* stmt: stmt modifier_until expr_value */ + case 24: /* stmt: stmt "'until' modifier" expr_value */ #line 1749 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_until(p, cond((yyvsp[0].nd)), (yyvsp[-2].nd)); } -#line 6681 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6680 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 25: /* stmt: stmt modifier_rescue stmt */ + case 25: /* stmt: stmt "'rescue' modifier" stmt */ #line 1753 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_mod_rescue(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6689 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6688 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 26: /* stmt: keyword_END '{' compstmt '}' */ + case 26: /* stmt: "'END'" '{' compstmt '}' */ #line 1757 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "END not supported"); (yyval.nd) = new_postexe(p, (yyvsp[-1].nd)); } -#line 6698 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6697 "mrbgems/mruby-compiler/core/y.tab.c" break; case 28: /* stmt: mlhs '=' command_call */ @@ -6702,7 +6701,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_masgn(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6706 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6705 "mrbgems/mruby-compiler/core/y.tab.c" break; case 29: /* stmt: lhs '=' mrhs */ @@ -6710,7 +6709,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_asgn(p, (yyvsp[-2].nd), new_array(p, (yyvsp[0].nd))); } -#line 6714 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6713 "mrbgems/mruby-compiler/core/y.tab.c" break; case 30: /* stmt: mlhs '=' arg */ @@ -6718,7 +6717,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_masgn(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6722 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6721 "mrbgems/mruby-compiler/core/y.tab.c" break; case 31: /* stmt: mlhs '=' mrhs */ @@ -6726,7 +6725,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_masgn(p, (yyvsp[-2].nd), new_array(p, (yyvsp[0].nd))); } -#line 6730 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6729 "mrbgems/mruby-compiler/core/y.tab.c" break; case 32: /* stmt: arg "=>" "local variable or method" */ @@ -6736,7 +6735,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); assignable(p, lhs); (yyval.nd) = new_asgn(p, lhs, (yyvsp[-2].nd)); } -#line 6740 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6739 "mrbgems/mruby-compiler/core/y.tab.c" break; case 34: /* command_asgn: lhs '=' command_rhs */ @@ -6744,7 +6743,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_asgn(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6748 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6747 "mrbgems/mruby-compiler/core/y.tab.c" break; case 35: /* command_asgn: var_lhs tOP_ASGN command_rhs */ @@ -6752,7 +6751,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_op_asgn(p, (yyvsp[-2].nd), (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 6756 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6755 "mrbgems/mruby-compiler/core/y.tab.c" break; case 36: /* command_asgn: primary_value '[' opt_call_args ']' tOP_ASGN command_rhs */ @@ -6760,7 +6759,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (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 6764 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6763 "mrbgems/mruby-compiler/core/y.tab.c" break; case 37: /* command_asgn: primary_value call_op "local variable or method" tOP_ASGN command_rhs */ @@ -6768,7 +6767,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (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 6772 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6771 "mrbgems/mruby-compiler/core/y.tab.c" break; case 38: /* command_asgn: primary_value call_op "constant" tOP_ASGN command_rhs */ @@ -6776,7 +6775,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (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 6780 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6779 "mrbgems/mruby-compiler/core/y.tab.c" break; case 39: /* command_asgn: primary_value "::" "constant" tOP_ASGN command_call */ @@ -6785,7 +6784,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyerror(p, "constant re-assignment"); (yyval.nd) = 0; } -#line 6789 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6788 "mrbgems/mruby-compiler/core/y.tab.c" break; case 40: /* command_asgn: primary_value "::" "local variable or method" tOP_ASGN command_rhs */ @@ -6793,7 +6792,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_op_asgn(p, new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), 0, tCOLON2), (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 6797 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6796 "mrbgems/mruby-compiler/core/y.tab.c" break; case 41: /* command_asgn: defn_head f_opt_arglist_paren '=' command */ @@ -6806,10 +6805,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); nvars_unnest(p); p->in_def--; } -#line 6810 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6809 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 42: /* command_asgn: defn_head f_opt_arglist_paren '=' command modifier_rescue arg */ + case 42: /* command_asgn: defn_head f_opt_arglist_paren '=' command "'rescue' modifier" arg */ #line 1826 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-5].nd); @@ -6819,7 +6818,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); nvars_unnest(p); p->in_def--; } -#line 6823 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6822 "mrbgems/mruby-compiler/core/y.tab.c" break; case 43: /* command_asgn: defs_head f_opt_arglist_paren '=' command */ @@ -6832,10 +6831,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->in_def--; p->in_single--; } -#line 6836 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6835 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 44: /* command_asgn: defs_head f_opt_arglist_paren '=' command modifier_rescue arg */ + case 44: /* command_asgn: defs_head f_opt_arglist_paren '=' command "'rescue' modifier" arg */ #line 1844 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-5].nd); @@ -6845,7 +6844,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->in_def--; p->in_single--; } -#line 6849 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6848 "mrbgems/mruby-compiler/core/y.tab.c" break; case 45: /* command_asgn: backref tOP_ASGN command_rhs */ @@ -6854,39 +6853,39 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); backref_error(p, (yyvsp[-2].nd)); (yyval.nd) = new_begin(p, 0); } -#line 6858 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6857 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 47: /* command_rhs: command_call modifier_rescue stmt */ + case 47: /* command_rhs: command_call "'rescue' modifier" stmt */ #line 1861 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_mod_rescue(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6866 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6865 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 50: /* expr: expr keyword_and expr */ + case 50: /* expr: expr "'and'" expr */ #line 1870 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_and(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6874 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6873 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 51: /* expr: expr keyword_or expr */ + case 51: /* expr: expr "'or'" expr */ #line 1874 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_or(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6882 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6881 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 52: /* expr: keyword_not opt_nl expr */ + case 52: /* expr: "'not'" opt_nl expr */ #line 1878 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_uni_op(p, cond((yyvsp[0].nd)), "!"); } -#line 6890 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6889 "mrbgems/mruby-compiler/core/y.tab.c" break; case 53: /* expr: '!' command_call */ @@ -6894,10 +6893,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_uni_op(p, cond((yyvsp[0].nd)), "!"); } -#line 6898 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6897 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 55: /* defn_head: keyword_def fname */ + case 55: /* defn_head: "'def'" fname */ #line 1890 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_def(p, (yyvsp[0].id), nint(p->cmdarg_stack), local_switch(p)); @@ -6905,7 +6904,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->in_def++; nvars_block(p); } -#line 6909 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6908 "mrbgems/mruby-compiler/core/y.tab.c" break; case 56: /* $@4: %empty */ @@ -6913,10 +6912,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { p->lstate = EXPR_FNAME; } -#line 6917 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6916 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 57: /* defs_head: keyword_def singleton dot_or_colon $@4 fname */ + case 57: /* defs_head: "'def'" singleton dot_or_colon $@4 fname */ #line 1903 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_sdef(p, (yyvsp[-3].nd), (yyvsp[0].id), nint(p->cmdarg_stack), local_switch(p)); @@ -6926,7 +6925,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); nvars_block(p); p->lstate = EXPR_ENDFN; /* force for args */ } -#line 6930 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6929 "mrbgems/mruby-compiler/core/y.tab.c" break; case 58: /* expr_value: expr */ @@ -6937,7 +6936,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = (yyvsp[0].nd); } } -#line 6941 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6940 "mrbgems/mruby-compiler/core/y.tab.c" break; case 62: /* block_command: block_call call_op2 operation2 command_args */ @@ -6945,7 +6944,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), (yyvsp[-2].num)); } -#line 6949 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6948 "mrbgems/mruby-compiler/core/y.tab.c" break; case 63: /* $@5: %empty */ @@ -6954,7 +6953,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); local_nest(p); nvars_nest(p); } -#line 6958 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6957 "mrbgems/mruby-compiler/core/y.tab.c" break; case 64: /* cmd_brace_block: "{" $@5 opt_block_param compstmt '}' */ @@ -6964,7 +6963,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); local_unnest(p); nvars_unnest(p); } -#line 6968 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6967 "mrbgems/mruby-compiler/core/y.tab.c" break; case 65: /* command: operation command_args */ @@ -6972,7 +6971,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_fcall(p, (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 6976 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6975 "mrbgems/mruby-compiler/core/y.tab.c" break; case 66: /* command: operation command_args cmd_brace_block */ @@ -6981,7 +6980,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); args_with_block(p, (yyvsp[-1].nd), (yyvsp[0].nd)); (yyval.nd) = new_fcall(p, (yyvsp[-2].id), (yyvsp[-1].nd)); } -#line 6985 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6984 "mrbgems/mruby-compiler/core/y.tab.c" break; case 67: /* command: primary_value call_op operation2 command_args */ @@ -6989,7 +6988,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), (yyvsp[-2].num)); } -#line 6993 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6992 "mrbgems/mruby-compiler/core/y.tab.c" break; case 68: /* command: primary_value call_op operation2 command_args cmd_brace_block */ @@ -6998,7 +6997,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); 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 7002 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7001 "mrbgems/mruby-compiler/core/y.tab.c" break; case 69: /* command: primary_value "::" operation2 command_args */ @@ -7006,7 +7005,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), tCOLON2); } -#line 7010 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7009 "mrbgems/mruby-compiler/core/y.tab.c" break; case 70: /* command: primary_value "::" operation2 command_args cmd_brace_block */ @@ -7015,47 +7014,47 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); 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 7019 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7018 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 71: /* command: keyword_super command_args */ + case 71: /* command: "'super'" command_args */ #line 1976 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_super(p, (yyvsp[0].nd)); } -#line 7027 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7026 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 72: /* command: keyword_yield command_args */ + case 72: /* command: "'yield'" command_args */ #line 1980 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_yield(p, (yyvsp[0].nd)); } -#line 7035 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7034 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 73: /* command: keyword_return call_args */ + case 73: /* command: "'return'" call_args */ #line 1984 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_return(p, ret_args(p, (yyvsp[0].nd))); } -#line 7043 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7042 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 74: /* command: keyword_break call_args */ + case 74: /* command: "'break'" call_args */ #line 1988 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_break(p, ret_args(p, (yyvsp[0].nd))); } -#line 7051 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7050 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 75: /* command: keyword_next call_args */ + case 75: /* command: "'next'" call_args */ #line 1992 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_next(p, ret_args(p, (yyvsp[0].nd))); } -#line 7059 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7058 "mrbgems/mruby-compiler/core/y.tab.c" break; case 76: /* mlhs: mlhs_basic */ @@ -7063,7 +7062,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = (yyvsp[0].nd); } -#line 7067 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7066 "mrbgems/mruby-compiler/core/y.tab.c" break; case 77: /* mlhs: tLPAREN mlhs_inner rparen */ @@ -7071,7 +7070,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = (yyvsp[-1].nd); } -#line 7075 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7074 "mrbgems/mruby-compiler/core/y.tab.c" break; case 79: /* mlhs_inner: tLPAREN mlhs_inner rparen */ @@ -7079,7 +7078,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = (yyvsp[-1].nd); } -#line 7083 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7082 "mrbgems/mruby-compiler/core/y.tab.c" break; case 80: /* mlhs_basic: mlhs_list */ @@ -7087,7 +7086,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 7091 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7090 "mrbgems/mruby-compiler/core/y.tab.c" break; case 81: /* mlhs_basic: mlhs_list mlhs_item */ @@ -7095,7 +7094,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list1(push((yyvsp[-1].nd),(yyvsp[0].nd))); } -#line 7099 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7098 "mrbgems/mruby-compiler/core/y.tab.c" break; case 82: /* mlhs_basic: mlhs_list "*" mlhs_node */ @@ -7103,7 +7102,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list2((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7107 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7106 "mrbgems/mruby-compiler/core/y.tab.c" break; case 83: /* mlhs_basic: mlhs_list "*" mlhs_node ',' mlhs_post */ @@ -7111,7 +7110,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list3((yyvsp[-4].nd), (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7115 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7114 "mrbgems/mruby-compiler/core/y.tab.c" break; case 84: /* mlhs_basic: mlhs_list "*" */ @@ -7119,7 +7118,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list2((yyvsp[-1].nd), new_nil(p)); } -#line 7123 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7122 "mrbgems/mruby-compiler/core/y.tab.c" break; case 85: /* mlhs_basic: mlhs_list "*" ',' mlhs_post */ @@ -7127,7 +7126,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list3((yyvsp[-3].nd), new_nil(p), (yyvsp[0].nd)); } -#line 7131 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7130 "mrbgems/mruby-compiler/core/y.tab.c" break; case 86: /* mlhs_basic: "*" mlhs_node */ @@ -7135,7 +7134,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list2(0, (yyvsp[0].nd)); } -#line 7139 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7138 "mrbgems/mruby-compiler/core/y.tab.c" break; case 87: /* mlhs_basic: "*" mlhs_node ',' mlhs_post */ @@ -7143,7 +7142,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list3(0, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7147 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7146 "mrbgems/mruby-compiler/core/y.tab.c" break; case 88: /* mlhs_basic: "*" */ @@ -7151,7 +7150,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list2(0, new_nil(p)); } -#line 7155 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7154 "mrbgems/mruby-compiler/core/y.tab.c" break; case 89: /* mlhs_basic: "*" ',' mlhs_post */ @@ -7159,7 +7158,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list3(0, new_nil(p), (yyvsp[0].nd)); } -#line 7163 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7162 "mrbgems/mruby-compiler/core/y.tab.c" break; case 91: /* mlhs_item: tLPAREN mlhs_inner rparen */ @@ -7167,7 +7166,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_masgn(p, (yyvsp[-1].nd), NULL); } -#line 7171 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7170 "mrbgems/mruby-compiler/core/y.tab.c" break; case 92: /* mlhs_list: mlhs_item ',' */ @@ -7175,7 +7174,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list1((yyvsp[-1].nd)); } -#line 7179 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7178 "mrbgems/mruby-compiler/core/y.tab.c" break; case 93: /* mlhs_list: mlhs_list mlhs_item ',' */ @@ -7183,7 +7182,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[-1].nd)); } -#line 7187 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7186 "mrbgems/mruby-compiler/core/y.tab.c" break; case 94: /* mlhs_post: mlhs_item */ @@ -7191,7 +7190,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 7195 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7194 "mrbgems/mruby-compiler/core/y.tab.c" break; case 95: /* mlhs_post: mlhs_list mlhs_item */ @@ -7199,7 +7198,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = push((yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 7203 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7202 "mrbgems/mruby-compiler/core/y.tab.c" break; case 96: /* mlhs_node: variable */ @@ -7207,7 +7206,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { assignable(p, (yyvsp[0].nd)); } -#line 7211 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7210 "mrbgems/mruby-compiler/core/y.tab.c" break; case 97: /* mlhs_node: primary_value '[' opt_call_args ']' */ @@ -7215,7 +7214,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_call(p, (yyvsp[-3].nd), intern_op(aref), (yyvsp[-1].nd), '.'); } -#line 7219 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7218 "mrbgems/mruby-compiler/core/y.tab.c" break; case 98: /* mlhs_node: primary_value call_op "local variable or method" */ @@ -7223,7 +7222,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, (yyvsp[-1].num)); } -#line 7227 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7226 "mrbgems/mruby-compiler/core/y.tab.c" break; case 99: /* mlhs_node: primary_value "::" "local variable or method" */ @@ -7231,7 +7230,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, tCOLON2); } -#line 7235 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7234 "mrbgems/mruby-compiler/core/y.tab.c" break; case 100: /* mlhs_node: primary_value call_op "constant" */ @@ -7239,7 +7238,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, (yyvsp[-1].num)); } -#line 7243 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7242 "mrbgems/mruby-compiler/core/y.tab.c" break; case 101: /* mlhs_node: primary_value "::" "constant" */ @@ -7249,7 +7248,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyerror(p, "dynamic constant assignment"); (yyval.nd) = new_colon2(p, (yyvsp[-2].nd), (yyvsp[0].id)); } -#line 7253 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7252 "mrbgems/mruby-compiler/core/y.tab.c" break; case 102: /* mlhs_node: tCOLON3 "constant" */ @@ -7259,7 +7258,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyerror(p, "dynamic constant assignment"); (yyval.nd) = new_colon3(p, (yyvsp[0].id)); } -#line 7263 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7262 "mrbgems/mruby-compiler/core/y.tab.c" break; case 103: /* mlhs_node: backref */ @@ -7268,7 +7267,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); backref_error(p, (yyvsp[0].nd)); (yyval.nd) = 0; } -#line 7272 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7271 "mrbgems/mruby-compiler/core/y.tab.c" break; case 104: /* lhs: variable */ @@ -7276,7 +7275,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { assignable(p, (yyvsp[0].nd)); } -#line 7280 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7279 "mrbgems/mruby-compiler/core/y.tab.c" break; case 105: /* lhs: primary_value '[' opt_call_args ']' */ @@ -7284,7 +7283,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_call(p, (yyvsp[-3].nd), intern_op(aref), (yyvsp[-1].nd), '.'); } -#line 7288 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7287 "mrbgems/mruby-compiler/core/y.tab.c" break; case 106: /* lhs: primary_value call_op "local variable or method" */ @@ -7292,7 +7291,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, (yyvsp[-1].num)); } -#line 7296 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7295 "mrbgems/mruby-compiler/core/y.tab.c" break; case 107: /* lhs: primary_value "::" "local variable or method" */ @@ -7300,7 +7299,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, tCOLON2); } -#line 7304 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7303 "mrbgems/mruby-compiler/core/y.tab.c" break; case 108: /* lhs: primary_value call_op "constant" */ @@ -7308,7 +7307,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, (yyvsp[-1].num)); } -#line 7312 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7311 "mrbgems/mruby-compiler/core/y.tab.c" break; case 109: /* lhs: primary_value "::" "constant" */ @@ -7318,7 +7317,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyerror(p, "dynamic constant assignment"); (yyval.nd) = new_colon2(p, (yyvsp[-2].nd), (yyvsp[0].id)); } -#line 7322 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7321 "mrbgems/mruby-compiler/core/y.tab.c" break; case 110: /* lhs: tCOLON3 "constant" */ @@ -7328,7 +7327,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyerror(p, "dynamic constant assignment"); (yyval.nd) = new_colon3(p, (yyvsp[0].id)); } -#line 7332 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7331 "mrbgems/mruby-compiler/core/y.tab.c" break; case 111: /* lhs: backref */ @@ -7337,7 +7336,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); backref_error(p, (yyvsp[0].nd)); (yyval.nd) = 0; } -#line 7341 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7340 "mrbgems/mruby-compiler/core/y.tab.c" break; case 112: /* lhs: "numbered parameter" */ @@ -7345,7 +7344,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { yyerror(p, "can't assign to numbered parameter"); } -#line 7349 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7348 "mrbgems/mruby-compiler/core/y.tab.c" break; case 113: /* cname: "local variable or method" */ @@ -7353,7 +7352,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { yyerror(p, "class/module name must be CONSTANT"); } -#line 7357 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7356 "mrbgems/mruby-compiler/core/y.tab.c" break; case 115: /* cpath: tCOLON3 cname */ @@ -7361,7 +7360,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = cons(nint(1), nsym((yyvsp[0].id))); } -#line 7365 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7364 "mrbgems/mruby-compiler/core/y.tab.c" break; case 116: /* cpath: cname */ @@ -7369,7 +7368,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = cons(nint(0), nsym((yyvsp[0].id))); } -#line 7373 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7372 "mrbgems/mruby-compiler/core/y.tab.c" break; case 117: /* cpath: primary_value "::" cname */ @@ -7378,7 +7377,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); void_expr_error(p, (yyvsp[-2].nd)); (yyval.nd) = cons((yyvsp[-2].nd), nsym((yyvsp[0].id))); } -#line 7382 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7381 "mrbgems/mruby-compiler/core/y.tab.c" break; case 121: /* fname: op */ @@ -7387,7 +7386,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->lstate = EXPR_ENDFN; (yyval.id) = (yyvsp[0].id); } -#line 7391 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7390 "mrbgems/mruby-compiler/core/y.tab.c" break; case 122: /* fname: reswords */ @@ -7396,7 +7395,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->lstate = EXPR_ENDFN; (yyval.id) = (yyvsp[0].id); } -#line 7400 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7399 "mrbgems/mruby-compiler/core/y.tab.c" break; case 125: /* undef_list: fsym */ @@ -7404,13 +7403,13 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_undef(p, (yyvsp[0].id)); } -#line 7408 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7407 "mrbgems/mruby-compiler/core/y.tab.c" break; case 126: /* $@6: %empty */ #line 2210 "mrbgems/mruby-compiler/core/parse.y" {p->lstate = EXPR_FNAME;} -#line 7414 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7413 "mrbgems/mruby-compiler/core/y.tab.c" break; case 127: /* undef_list: undef_list ',' $@6 fsym */ @@ -7418,187 +7417,187 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = push((yyvsp[-3].nd), nsym((yyvsp[0].id))); } -#line 7422 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7421 "mrbgems/mruby-compiler/core/y.tab.c" break; case 128: /* op: '|' */ #line 2216 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(or); } -#line 7428 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7427 "mrbgems/mruby-compiler/core/y.tab.c" break; case 129: /* op: '^' */ #line 2217 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(xor); } -#line 7434 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7433 "mrbgems/mruby-compiler/core/y.tab.c" break; case 130: /* op: '&' */ #line 2218 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(and); } -#line 7440 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7439 "mrbgems/mruby-compiler/core/y.tab.c" break; case 131: /* op: "<=>" */ #line 2219 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(cmp); } -#line 7446 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7445 "mrbgems/mruby-compiler/core/y.tab.c" break; case 132: /* op: "==" */ #line 2220 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(eq); } -#line 7452 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7451 "mrbgems/mruby-compiler/core/y.tab.c" break; case 133: /* op: "===" */ #line 2221 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(eqq); } -#line 7458 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7457 "mrbgems/mruby-compiler/core/y.tab.c" break; case 134: /* op: "=~" */ #line 2222 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(match); } -#line 7464 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7463 "mrbgems/mruby-compiler/core/y.tab.c" break; case 135: /* op: "!~" */ #line 2223 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(nmatch); } -#line 7470 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7469 "mrbgems/mruby-compiler/core/y.tab.c" break; case 136: /* op: '>' */ #line 2224 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(gt); } -#line 7476 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7475 "mrbgems/mruby-compiler/core/y.tab.c" break; case 137: /* op: ">=" */ #line 2225 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(ge); } -#line 7482 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7481 "mrbgems/mruby-compiler/core/y.tab.c" break; case 138: /* op: '<' */ #line 2226 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(lt); } -#line 7488 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7487 "mrbgems/mruby-compiler/core/y.tab.c" break; case 139: /* op: "<=" */ #line 2227 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(le); } -#line 7494 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7493 "mrbgems/mruby-compiler/core/y.tab.c" break; case 140: /* op: "!=" */ #line 2228 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(neq); } -#line 7500 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7499 "mrbgems/mruby-compiler/core/y.tab.c" break; case 141: /* op: "<<" */ #line 2229 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(lshift); } -#line 7506 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7505 "mrbgems/mruby-compiler/core/y.tab.c" break; case 142: /* op: ">>" */ #line 2230 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(rshift); } -#line 7512 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7511 "mrbgems/mruby-compiler/core/y.tab.c" break; case 143: /* op: '+' */ #line 2231 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(add); } -#line 7518 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7517 "mrbgems/mruby-compiler/core/y.tab.c" break; case 144: /* op: '-' */ #line 2232 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(sub); } -#line 7524 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7523 "mrbgems/mruby-compiler/core/y.tab.c" break; case 145: /* op: '*' */ #line 2233 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(mul); } -#line 7530 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7529 "mrbgems/mruby-compiler/core/y.tab.c" break; case 146: /* op: "*" */ #line 2234 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(mul); } -#line 7536 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7535 "mrbgems/mruby-compiler/core/y.tab.c" break; case 147: /* op: '/' */ #line 2235 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(div); } -#line 7542 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7541 "mrbgems/mruby-compiler/core/y.tab.c" break; case 148: /* op: '%' */ #line 2236 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(mod); } -#line 7548 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7547 "mrbgems/mruby-compiler/core/y.tab.c" break; case 149: /* op: tPOW */ #line 2237 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(pow); } -#line 7554 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7553 "mrbgems/mruby-compiler/core/y.tab.c" break; case 150: /* op: "**" */ #line 2238 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(pow); } -#line 7560 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7559 "mrbgems/mruby-compiler/core/y.tab.c" break; case 151: /* op: '!' */ #line 2239 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(not); } -#line 7566 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7565 "mrbgems/mruby-compiler/core/y.tab.c" break; case 152: /* op: '~' */ #line 2240 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(neg); } -#line 7572 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7571 "mrbgems/mruby-compiler/core/y.tab.c" break; case 153: /* op: "unary plus" */ #line 2241 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(plus); } -#line 7578 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7577 "mrbgems/mruby-compiler/core/y.tab.c" break; case 154: /* op: "unary minus" */ #line 2242 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(minus); } -#line 7584 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7583 "mrbgems/mruby-compiler/core/y.tab.c" break; case 155: /* op: tAREF */ #line 2243 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(aref); } -#line 7590 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7589 "mrbgems/mruby-compiler/core/y.tab.c" break; case 156: /* op: tASET */ #line 2244 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(aset); } -#line 7596 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7595 "mrbgems/mruby-compiler/core/y.tab.c" break; case 157: /* op: '`' */ #line 2245 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(tick); } -#line 7602 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7601 "mrbgems/mruby-compiler/core/y.tab.c" break; case 198: /* arg: lhs '=' arg_rhs */ @@ -7606,7 +7605,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_asgn(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7610 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7609 "mrbgems/mruby-compiler/core/y.tab.c" break; case 199: /* arg: var_lhs tOP_ASGN arg_rhs */ @@ -7614,7 +7613,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_op_asgn(p, (yyvsp[-2].nd), (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 7618 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7617 "mrbgems/mruby-compiler/core/y.tab.c" break; case 200: /* arg: primary_value '[' opt_call_args ']' tOP_ASGN arg_rhs */ @@ -7622,7 +7621,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (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 7626 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7625 "mrbgems/mruby-compiler/core/y.tab.c" break; case 201: /* arg: primary_value call_op "local variable or method" tOP_ASGN arg_rhs */ @@ -7630,7 +7629,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (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 7634 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7633 "mrbgems/mruby-compiler/core/y.tab.c" break; case 202: /* arg: primary_value call_op "constant" tOP_ASGN arg_rhs */ @@ -7638,7 +7637,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (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 7642 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7641 "mrbgems/mruby-compiler/core/y.tab.c" break; case 203: /* arg: primary_value "::" "local variable or method" tOP_ASGN arg_rhs */ @@ -7646,7 +7645,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_op_asgn(p, new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), 0, tCOLON2), (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 7650 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7649 "mrbgems/mruby-compiler/core/y.tab.c" break; case 204: /* arg: primary_value "::" "constant" tOP_ASGN arg_rhs */ @@ -7655,7 +7654,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyerror(p, "constant re-assignment"); (yyval.nd) = new_begin(p, 0); } -#line 7659 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7658 "mrbgems/mruby-compiler/core/y.tab.c" break; case 205: /* arg: tCOLON3 "constant" tOP_ASGN arg_rhs */ @@ -7664,7 +7663,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyerror(p, "constant re-assignment"); (yyval.nd) = new_begin(p, 0); } -#line 7668 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7667 "mrbgems/mruby-compiler/core/y.tab.c" break; case 206: /* arg: backref tOP_ASGN arg_rhs */ @@ -7673,7 +7672,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); backref_error(p, (yyvsp[-2].nd)); (yyval.nd) = new_begin(p, 0); } -#line 7677 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7676 "mrbgems/mruby-compiler/core/y.tab.c" break; case 207: /* arg: arg ".." arg */ @@ -7681,7 +7680,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_dot2(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7685 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7684 "mrbgems/mruby-compiler/core/y.tab.c" break; case 208: /* arg: arg ".." */ @@ -7689,7 +7688,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_dot2(p, (yyvsp[-1].nd), new_nil(p)); } -#line 7693 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7692 "mrbgems/mruby-compiler/core/y.tab.c" break; case 209: /* arg: tBDOT2 arg */ @@ -7697,7 +7696,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_dot2(p, new_nil(p), (yyvsp[0].nd)); } -#line 7701 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7700 "mrbgems/mruby-compiler/core/y.tab.c" break; case 210: /* arg: arg "..." arg */ @@ -7705,7 +7704,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_dot3(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7709 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7708 "mrbgems/mruby-compiler/core/y.tab.c" break; case 211: /* arg: arg "..." */ @@ -7713,7 +7712,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_dot3(p, (yyvsp[-1].nd), new_nil(p)); } -#line 7717 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7716 "mrbgems/mruby-compiler/core/y.tab.c" break; case 212: /* arg: tBDOT3 arg */ @@ -7721,7 +7720,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_dot3(p, new_nil(p), (yyvsp[0].nd)); } -#line 7725 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7724 "mrbgems/mruby-compiler/core/y.tab.c" break; case 213: /* arg: arg '+' arg */ @@ -7729,7 +7728,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "+", (yyvsp[0].nd)); } -#line 7733 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7732 "mrbgems/mruby-compiler/core/y.tab.c" break; case 214: /* arg: arg '-' arg */ @@ -7737,7 +7736,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "-", (yyvsp[0].nd)); } -#line 7741 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7740 "mrbgems/mruby-compiler/core/y.tab.c" break; case 215: /* arg: arg '*' arg */ @@ -7745,7 +7744,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "*", (yyvsp[0].nd)); } -#line 7749 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7748 "mrbgems/mruby-compiler/core/y.tab.c" break; case 216: /* arg: arg '/' arg */ @@ -7753,7 +7752,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "/", (yyvsp[0].nd)); } -#line 7757 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7756 "mrbgems/mruby-compiler/core/y.tab.c" break; case 217: /* arg: arg '%' arg */ @@ -7761,7 +7760,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "%", (yyvsp[0].nd)); } -#line 7765 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7764 "mrbgems/mruby-compiler/core/y.tab.c" break; case 218: /* arg: arg tPOW arg */ @@ -7769,7 +7768,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "**", (yyvsp[0].nd)); } -#line 7773 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7772 "mrbgems/mruby-compiler/core/y.tab.c" break; case 219: /* arg: tUMINUS_NUM "integer literal" tPOW arg */ @@ -7777,7 +7776,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_negate(p, call_bin_op(p, (yyvsp[-2].nd), "**", (yyvsp[0].nd))); } -#line 7781 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7780 "mrbgems/mruby-compiler/core/y.tab.c" break; case 220: /* arg: tUMINUS_NUM "float literal" tPOW arg */ @@ -7785,7 +7784,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_negate(p, call_bin_op(p, (yyvsp[-2].nd), "**", (yyvsp[0].nd))); } -#line 7789 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7788 "mrbgems/mruby-compiler/core/y.tab.c" break; case 221: /* arg: "unary plus" arg */ @@ -7793,7 +7792,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_uni_op(p, (yyvsp[0].nd), "+@"); } -#line 7797 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7796 "mrbgems/mruby-compiler/core/y.tab.c" break; case 222: /* arg: "unary minus" arg */ @@ -7801,7 +7800,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_negate(p, (yyvsp[0].nd)); } -#line 7805 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7804 "mrbgems/mruby-compiler/core/y.tab.c" break; case 223: /* arg: arg '|' arg */ @@ -7809,7 +7808,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "|", (yyvsp[0].nd)); } -#line 7813 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7812 "mrbgems/mruby-compiler/core/y.tab.c" break; case 224: /* arg: arg '^' arg */ @@ -7817,7 +7816,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "^", (yyvsp[0].nd)); } -#line 7821 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7820 "mrbgems/mruby-compiler/core/y.tab.c" break; case 225: /* arg: arg '&' arg */ @@ -7825,7 +7824,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "&", (yyvsp[0].nd)); } -#line 7829 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7828 "mrbgems/mruby-compiler/core/y.tab.c" break; case 226: /* arg: arg "<=>" arg */ @@ -7833,7 +7832,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "<=>", (yyvsp[0].nd)); } -#line 7837 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7836 "mrbgems/mruby-compiler/core/y.tab.c" break; case 227: /* arg: arg '>' arg */ @@ -7841,7 +7840,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), ">", (yyvsp[0].nd)); } -#line 7845 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7844 "mrbgems/mruby-compiler/core/y.tab.c" break; case 228: /* arg: arg ">=" arg */ @@ -7849,7 +7848,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), ">=", (yyvsp[0].nd)); } -#line 7853 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7852 "mrbgems/mruby-compiler/core/y.tab.c" break; case 229: /* arg: arg '<' arg */ @@ -7857,7 +7856,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "<", (yyvsp[0].nd)); } -#line 7861 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7860 "mrbgems/mruby-compiler/core/y.tab.c" break; case 230: /* arg: arg "<=" arg */ @@ -7865,7 +7864,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "<=", (yyvsp[0].nd)); } -#line 7869 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7868 "mrbgems/mruby-compiler/core/y.tab.c" break; case 231: /* arg: arg "==" arg */ @@ -7873,7 +7872,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "==", (yyvsp[0].nd)); } -#line 7877 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7876 "mrbgems/mruby-compiler/core/y.tab.c" break; case 232: /* arg: arg "===" arg */ @@ -7881,7 +7880,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "===", (yyvsp[0].nd)); } -#line 7885 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7884 "mrbgems/mruby-compiler/core/y.tab.c" break; case 233: /* arg: arg "!=" arg */ @@ -7889,7 +7888,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "!=", (yyvsp[0].nd)); } -#line 7893 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7892 "mrbgems/mruby-compiler/core/y.tab.c" break; case 234: /* arg: arg "=~" arg */ @@ -7897,7 +7896,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "=~", (yyvsp[0].nd)); } -#line 7901 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7900 "mrbgems/mruby-compiler/core/y.tab.c" break; case 235: /* arg: arg "!~" arg */ @@ -7905,7 +7904,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "!~", (yyvsp[0].nd)); } -#line 7909 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7908 "mrbgems/mruby-compiler/core/y.tab.c" break; case 236: /* arg: '!' arg */ @@ -7913,7 +7912,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_uni_op(p, cond((yyvsp[0].nd)), "!"); } -#line 7917 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7916 "mrbgems/mruby-compiler/core/y.tab.c" break; case 237: /* arg: '~' arg */ @@ -7921,7 +7920,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_uni_op(p, cond((yyvsp[0].nd)), "~"); } -#line 7925 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7924 "mrbgems/mruby-compiler/core/y.tab.c" break; case 238: /* arg: arg "<<" arg */ @@ -7929,7 +7928,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "<<", (yyvsp[0].nd)); } -#line 7933 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7932 "mrbgems/mruby-compiler/core/y.tab.c" break; case 239: /* arg: arg ">>" arg */ @@ -7937,7 +7936,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), ">>", (yyvsp[0].nd)); } -#line 7941 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7940 "mrbgems/mruby-compiler/core/y.tab.c" break; case 240: /* arg: arg "&&" arg */ @@ -7945,7 +7944,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_and(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7949 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7948 "mrbgems/mruby-compiler/core/y.tab.c" break; case 241: /* arg: arg "||" arg */ @@ -7953,7 +7952,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_or(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7957 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7956 "mrbgems/mruby-compiler/core/y.tab.c" break; case 242: /* arg: arg '?' arg opt_nl ':' arg */ @@ -7961,7 +7960,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_if(p, cond((yyvsp[-5].nd)), (yyvsp[-3].nd), (yyvsp[0].nd)); } -#line 7965 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7964 "mrbgems/mruby-compiler/core/y.tab.c" break; case 243: /* arg: arg '?' arg opt_nl "label" arg */ @@ -7969,7 +7968,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_if(p, cond((yyvsp[-5].nd)), (yyvsp[-3].nd), (yyvsp[0].nd)); } -#line 7973 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7972 "mrbgems/mruby-compiler/core/y.tab.c" break; case 244: /* arg: defn_head f_opt_arglist_paren '=' arg */ @@ -7982,10 +7981,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); nvars_unnest(p); p->in_def--; } -#line 7986 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7985 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 245: /* arg: defn_head f_opt_arglist_paren '=' arg modifier_rescue arg */ + case 245: /* arg: defn_head f_opt_arglist_paren '=' arg "'rescue' modifier" arg */ #line 2459 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-5].nd); @@ -7995,7 +7994,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); nvars_unnest(p); p->in_def--; } -#line 7999 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7998 "mrbgems/mruby-compiler/core/y.tab.c" break; case 246: /* arg: defs_head f_opt_arglist_paren '=' arg */ @@ -8008,10 +8007,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->in_def--; p->in_single--; } -#line 8012 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8011 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 247: /* arg: defs_head f_opt_arglist_paren '=' arg modifier_rescue arg */ + case 247: /* arg: defs_head f_opt_arglist_paren '=' arg "'rescue' modifier" arg */ #line 2477 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-5].nd); @@ -8021,7 +8020,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->in_def--; p->in_single--; } -#line 8025 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8024 "mrbgems/mruby-compiler/core/y.tab.c" break; case 248: /* arg: primary */ @@ -8029,7 +8028,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = (yyvsp[0].nd); } -#line 8033 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8032 "mrbgems/mruby-compiler/core/y.tab.c" break; case 250: /* aref_args: args trailer */ @@ -8038,7 +8037,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = (yyvsp[-1].nd); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 8042 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8041 "mrbgems/mruby-compiler/core/y.tab.c" break; case 251: /* aref_args: args comma assocs trailer */ @@ -8046,7 +8045,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = push((yyvsp[-3].nd), new_hash(p, (yyvsp[-1].nd))); } -#line 8050 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8049 "mrbgems/mruby-compiler/core/y.tab.c" break; case 252: /* aref_args: assocs trailer */ @@ -8055,7 +8054,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = cons(new_kw_hash(p, (yyvsp[-1].nd)), 0); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 8059 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8058 "mrbgems/mruby-compiler/core/y.tab.c" break; case 253: /* arg_rhs: arg */ @@ -8063,16 +8062,16 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = (yyvsp[0].nd); } -#line 8067 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8066 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 254: /* arg_rhs: arg modifier_rescue arg */ + case 254: /* arg_rhs: arg "'rescue' modifier" arg */ #line 2513 "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 8076 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8075 "mrbgems/mruby-compiler/core/y.tab.c" break; case 255: /* paren_args: '(' opt_call_args ')' */ @@ -8080,7 +8079,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = (yyvsp[-1].nd); } -#line 8084 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8083 "mrbgems/mruby-compiler/core/y.tab.c" break; case 256: /* paren_args: '(' args comma tBDOT3 rparen */ @@ -8093,7 +8092,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); 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 8097 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8096 "mrbgems/mruby-compiler/core/y.tab.c" break; case 257: /* paren_args: '(' tBDOT3 rparen */ @@ -8112,7 +8111,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = 0; } } -#line 8116 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8115 "mrbgems/mruby-compiler/core/y.tab.c" break; case 262: /* opt_call_args: args comma */ @@ -8121,7 +8120,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = new_callargs(p,(yyvsp[-1].nd),0,0); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 8125 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8124 "mrbgems/mruby-compiler/core/y.tab.c" break; case 263: /* opt_call_args: args comma assocs comma */ @@ -8130,7 +8129,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = new_callargs(p,(yyvsp[-3].nd),new_kw_hash(p,(yyvsp[-1].nd)),0); NODE_LINENO((yyval.nd), (yyvsp[-3].nd)); } -#line 8134 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8133 "mrbgems/mruby-compiler/core/y.tab.c" break; case 264: /* opt_call_args: assocs comma */ @@ -8139,7 +8138,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = new_callargs(p,0,new_kw_hash(p,(yyvsp[-1].nd)),0); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 8143 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8142 "mrbgems/mruby-compiler/core/y.tab.c" break; case 265: /* call_args: command */ @@ -8149,7 +8148,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = new_callargs(p, list1((yyvsp[0].nd)), 0, 0); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 8153 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8152 "mrbgems/mruby-compiler/core/y.tab.c" break; case 266: /* call_args: args opt_block_arg */ @@ -8158,7 +8157,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = new_callargs(p, (yyvsp[-1].nd), 0, (yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 8162 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8161 "mrbgems/mruby-compiler/core/y.tab.c" break; case 267: /* call_args: assocs opt_block_arg */ @@ -8167,7 +8166,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = new_callargs(p, 0, new_kw_hash(p, (yyvsp[-1].nd)), (yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 8171 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8170 "mrbgems/mruby-compiler/core/y.tab.c" break; case 268: /* call_args: args comma assocs opt_block_arg */ @@ -8176,7 +8175,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (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 8180 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8179 "mrbgems/mruby-compiler/core/y.tab.c" break; case 269: /* call_args: block_arg */ @@ -8185,7 +8184,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = new_callargs(p, 0, 0, (yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 8189 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8188 "mrbgems/mruby-compiler/core/y.tab.c" break; case 270: /* @7: %empty */ @@ -8194,7 +8193,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.stack) = p->cmdarg_stack; CMDARG_PUSH(1); } -#line 8198 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8197 "mrbgems/mruby-compiler/core/y.tab.c" break; case 271: /* command_args: @7 call_args */ @@ -8203,7 +8202,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->cmdarg_stack = (yyvsp[-1].stack); (yyval.nd) = (yyvsp[0].nd); } -#line 8207 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8206 "mrbgems/mruby-compiler/core/y.tab.c" break; case 272: /* block_arg: "&" arg */ @@ -8211,7 +8210,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_block_arg(p, (yyvsp[0].nd)); } -#line 8215 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8214 "mrbgems/mruby-compiler/core/y.tab.c" break; case 273: /* block_arg: "&" */ @@ -8219,7 +8218,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_block_arg(p, 0); } -#line 8223 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8222 "mrbgems/mruby-compiler/core/y.tab.c" break; case 274: /* opt_block_arg: comma block_arg */ @@ -8227,7 +8226,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = (yyvsp[0].nd); } -#line 8231 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8230 "mrbgems/mruby-compiler/core/y.tab.c" break; case 275: /* opt_block_arg: none */ @@ -8235,7 +8234,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = 0; } -#line 8239 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8238 "mrbgems/mruby-compiler/core/y.tab.c" break; case 277: /* args: arg */ @@ -8245,7 +8244,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = list1((yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 8249 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8248 "mrbgems/mruby-compiler/core/y.tab.c" break; case 278: /* args: "*" */ @@ -8253,7 +8252,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list1(new_splat(p, new_lvar(p, intern_op(mul)))); } -#line 8257 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8256 "mrbgems/mruby-compiler/core/y.tab.c" break; case 279: /* args: "*" arg */ @@ -8262,7 +8261,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = list1(new_splat(p, (yyvsp[0].nd))); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 8266 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8265 "mrbgems/mruby-compiler/core/y.tab.c" break; case 280: /* args: args comma arg */ @@ -8271,7 +8270,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 8275 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8274 "mrbgems/mruby-compiler/core/y.tab.c" break; case 281: /* args: args comma "*" */ @@ -8279,7 +8278,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = push((yyvsp[-2].nd), new_splat(p, new_lvar(p, intern_op(mul)))); } -#line 8283 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8282 "mrbgems/mruby-compiler/core/y.tab.c" break; case 282: /* args: args comma "*" arg */ @@ -8287,7 +8286,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = push((yyvsp[-3].nd), new_splat(p, (yyvsp[0].nd))); } -#line 8291 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8290 "mrbgems/mruby-compiler/core/y.tab.c" break; case 283: /* mrhs: args comma arg */ @@ -8296,7 +8295,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 8300 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8299 "mrbgems/mruby-compiler/core/y.tab.c" break; case 284: /* mrhs: args comma "*" arg */ @@ -8304,7 +8303,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = push((yyvsp[-3].nd), new_splat(p, (yyvsp[0].nd))); } -#line 8308 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8307 "mrbgems/mruby-compiler/core/y.tab.c" break; case 285: /* mrhs: "*" arg */ @@ -8312,7 +8311,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list1(new_splat(p, (yyvsp[0].nd))); } -#line 8316 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8315 "mrbgems/mruby-compiler/core/y.tab.c" break; case 293: /* primary: "numbered parameter" */ @@ -8320,7 +8319,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_nvar(p, (yyvsp[0].num)); } -#line 8324 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8323 "mrbgems/mruby-compiler/core/y.tab.c" break; case 294: /* primary: "method" */ @@ -8328,7 +8327,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_fcall(p, (yyvsp[0].id), 0); } -#line 8332 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8331 "mrbgems/mruby-compiler/core/y.tab.c" break; case 295: /* @8: %empty */ @@ -8337,16 +8336,16 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.stack) = p->cmdarg_stack; p->cmdarg_stack = 0; } -#line 8341 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8340 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 296: /* primary: keyword_begin @8 bodystmt keyword_end */ + case 296: /* primary: "'begin'" @8 bodystmt "'end'" */ #line 2701 "mrbgems/mruby-compiler/core/parse.y" { p->cmdarg_stack = (yyvsp[-2].stack); (yyval.nd) = (yyvsp[-1].nd); } -#line 8350 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8349 "mrbgems/mruby-compiler/core/y.tab.c" break; case 297: /* @9: %empty */ @@ -8355,13 +8354,13 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.stack) = p->cmdarg_stack; p->cmdarg_stack = 0; } -#line 8359 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8358 "mrbgems/mruby-compiler/core/y.tab.c" break; case 298: /* $@10: %empty */ #line 2710 "mrbgems/mruby-compiler/core/parse.y" {p->lstate = EXPR_ENDARG;} -#line 8365 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8364 "mrbgems/mruby-compiler/core/y.tab.c" break; case 299: /* primary: "(" @9 stmt $@10 rparen */ @@ -8370,13 +8369,13 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->cmdarg_stack = (yyvsp[-3].stack); (yyval.nd) = (yyvsp[-2].nd); } -#line 8374 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8373 "mrbgems/mruby-compiler/core/y.tab.c" break; case 300: /* $@11: %empty */ #line 2715 "mrbgems/mruby-compiler/core/parse.y" {p->lstate = EXPR_ENDARG;} -#line 8380 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8379 "mrbgems/mruby-compiler/core/y.tab.c" break; case 301: /* primary: "(" $@11 rparen */ @@ -8384,7 +8383,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_nil(p); } -#line 8388 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8387 "mrbgems/mruby-compiler/core/y.tab.c" break; case 302: /* primary: tLPAREN compstmt ')' */ @@ -8392,7 +8391,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = (yyvsp[-1].nd); } -#line 8396 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8395 "mrbgems/mruby-compiler/core/y.tab.c" break; case 303: /* primary: primary_value "::" "constant" */ @@ -8400,7 +8399,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_colon2(p, (yyvsp[-2].nd), (yyvsp[0].id)); } -#line 8404 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8403 "mrbgems/mruby-compiler/core/y.tab.c" break; case 304: /* primary: tCOLON3 "constant" */ @@ -8408,7 +8407,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_colon3(p, (yyvsp[0].id)); } -#line 8412 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8411 "mrbgems/mruby-compiler/core/y.tab.c" break; case 305: /* primary: "[" aref_args ']' */ @@ -8417,7 +8416,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = new_array(p, (yyvsp[-1].nd)); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 8421 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8420 "mrbgems/mruby-compiler/core/y.tab.c" break; case 306: /* primary: tLBRACE assoc_list '}' */ @@ -8426,39 +8425,39 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = new_hash(p, (yyvsp[-1].nd)); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 8430 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8429 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 307: /* primary: keyword_return */ + case 307: /* primary: "'return'" */ #line 2742 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_return(p, 0); } -#line 8438 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8437 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 308: /* primary: keyword_yield opt_paren_args */ + case 308: /* primary: "'yield'" opt_paren_args */ #line 2746 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_yield(p, (yyvsp[0].nd)); } -#line 8446 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8445 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 309: /* primary: keyword_not '(' expr rparen */ + case 309: /* primary: "'not'" '(' expr rparen */ #line 2750 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_uni_op(p, cond((yyvsp[-1].nd)), "!"); } -#line 8454 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8453 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 310: /* primary: keyword_not '(' rparen */ + case 310: /* primary: "'not'" '(' rparen */ #line 2754 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_uni_op(p, new_nil(p), "!"); } -#line 8462 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8461 "mrbgems/mruby-compiler/core/y.tab.c" break; case 311: /* primary: operation brace_block */ @@ -8466,7 +8465,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_fcall(p, (yyvsp[-1].id), new_callargs(p, 0, 0, (yyvsp[0].nd))); } -#line 8470 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8469 "mrbgems/mruby-compiler/core/y.tab.c" break; case 313: /* primary: method_call brace_block */ @@ -8475,7 +8474,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); call_with_block(p, (yyvsp[-1].nd), (yyvsp[0].nd)); (yyval.nd) = (yyvsp[-1].nd); } -#line 8479 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8478 "mrbgems/mruby-compiler/core/y.tab.c" break; case 314: /* @12: %empty */ @@ -8486,7 +8485,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.num) = p->lpar_beg; p->lpar_beg = ++p->paren_nest; } -#line 8490 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8489 "mrbgems/mruby-compiler/core/y.tab.c" break; case 315: /* @13: %empty */ @@ -8495,7 +8494,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.stack) = p->cmdarg_stack; p->cmdarg_stack = 0; } -#line 8499 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8498 "mrbgems/mruby-compiler/core/y.tab.c" break; case 316: /* primary: "->" @12 f_larglist @13 lambda_body */ @@ -8508,104 +8507,104 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->cmdarg_stack = (yyvsp[-1].stack); CMDARG_LEXPOP(); } -#line 8512 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8511 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 317: /* primary: keyword_if expr_value then compstmt if_tail keyword_end */ + case 317: /* primary: "'if'" expr_value then compstmt if_tail "'end'" */ #line 2792 "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 8521 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8520 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 318: /* primary: keyword_unless expr_value then compstmt opt_else keyword_end */ + case 318: /* primary: "'unless'" expr_value then compstmt opt_else "'end'" */ #line 2800 "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 8530 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8529 "mrbgems/mruby-compiler/core/y.tab.c" break; case 319: /* $@14: %empty */ #line 2804 "mrbgems/mruby-compiler/core/parse.y" {COND_PUSH(1);} -#line 8536 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8535 "mrbgems/mruby-compiler/core/y.tab.c" break; case 320: /* $@15: %empty */ #line 2804 "mrbgems/mruby-compiler/core/parse.y" {COND_POP();} -#line 8542 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8541 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 321: /* primary: keyword_while $@14 expr_value do $@15 compstmt keyword_end */ + case 321: /* primary: "'while'" $@14 expr_value do $@15 compstmt "'end'" */ #line 2807 "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 8551 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8550 "mrbgems/mruby-compiler/core/y.tab.c" break; case 322: /* $@16: %empty */ #line 2811 "mrbgems/mruby-compiler/core/parse.y" {COND_PUSH(1);} -#line 8557 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8556 "mrbgems/mruby-compiler/core/y.tab.c" break; case 323: /* $@17: %empty */ #line 2811 "mrbgems/mruby-compiler/core/parse.y" {COND_POP();} -#line 8563 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8562 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 324: /* primary: keyword_until $@16 expr_value do $@17 compstmt keyword_end */ + case 324: /* primary: "'until'" $@16 expr_value do $@17 compstmt "'end'" */ #line 2814 "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 8572 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8571 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 325: /* primary: keyword_case expr_value opt_terms case_body keyword_end */ + case 325: /* primary: "'case'" expr_value opt_terms case_body "'end'" */ #line 2821 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_case(p, (yyvsp[-3].nd), (yyvsp[-1].nd)); } -#line 8580 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8579 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 326: /* primary: keyword_case opt_terms case_body keyword_end */ + case 326: /* primary: "'case'" opt_terms case_body "'end'" */ #line 2825 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_case(p, 0, (yyvsp[-1].nd)); } -#line 8588 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8587 "mrbgems/mruby-compiler/core/y.tab.c" break; case 327: /* $@18: %empty */ #line 2829 "mrbgems/mruby-compiler/core/parse.y" {COND_PUSH(1);} -#line 8594 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8593 "mrbgems/mruby-compiler/core/y.tab.c" break; case 328: /* $@19: %empty */ #line 2831 "mrbgems/mruby-compiler/core/parse.y" {COND_POP();} -#line 8600 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8599 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 329: /* primary: keyword_for for_var keyword_in $@18 expr_value do $@19 compstmt keyword_end */ + case 329: /* primary: "'for'" for_var "'in'" $@18 expr_value do $@19 compstmt "'end'" */ #line 2834 "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 8609 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8608 "mrbgems/mruby-compiler/core/y.tab.c" break; case 330: /* @20: %empty */ @@ -8616,10 +8615,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = local_switch(p); nvars_block(p); } -#line 8620 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8619 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 331: /* primary: keyword_class cpath superclass @20 bodystmt keyword_end */ + case 331: /* primary: "'class'" cpath superclass @20 bodystmt "'end'" */ #line 2848 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_class(p, (yyvsp[-4].nd), (yyvsp[-3].nd), (yyvsp[-1].nd)); @@ -8627,7 +8626,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); local_resume(p, (yyvsp[-2].nd)); nvars_unnest(p); } -#line 8631 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8630 "mrbgems/mruby-compiler/core/y.tab.c" break; case 332: /* @21: %empty */ @@ -8636,7 +8635,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.num) = p->in_def; p->in_def = 0; } -#line 8640 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8639 "mrbgems/mruby-compiler/core/y.tab.c" break; case 333: /* @22: %empty */ @@ -8646,10 +8645,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); nvars_block(p); p->in_single = 0; } -#line 8650 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8649 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 334: /* primary: keyword_class "<<" expr @21 term @22 bodystmt keyword_end */ + case 334: /* primary: "'class'" "<<" expr @21 term @22 bodystmt "'end'" */ #line 2868 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_sclass(p, (yyvsp[-5].nd), (yyvsp[-1].nd)); @@ -8659,7 +8658,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->in_def = (yyvsp[-4].num); p->in_single = intn((yyvsp[-2].nd)->cdr); } -#line 8663 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8662 "mrbgems/mruby-compiler/core/y.tab.c" break; case 335: /* @23: %empty */ @@ -8670,10 +8669,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = local_switch(p); nvars_block(p); } -#line 8674 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8673 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 336: /* primary: keyword_module cpath @23 bodystmt keyword_end */ + case 336: /* primary: "'module'" cpath @23 bodystmt "'end'" */ #line 2886 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_module(p, (yyvsp[-3].nd), (yyvsp[-1].nd)); @@ -8681,10 +8680,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); local_resume(p, (yyvsp[-2].nd)); nvars_unnest(p); } -#line 8685 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8684 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 337: /* primary: defn_head f_arglist bodystmt keyword_end */ + case 337: /* primary: defn_head f_arglist bodystmt "'end'" */ #line 2896 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-3].nd); @@ -8692,10 +8691,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); nvars_unnest(p); p->in_def--; } -#line 8696 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8695 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 338: /* primary: defs_head f_arglist bodystmt keyword_end */ + case 338: /* primary: defs_head f_arglist bodystmt "'end'" */ #line 2906 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-3].nd); @@ -8704,39 +8703,39 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->in_def--; p->in_single--; } -#line 8708 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8707 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 339: /* primary: keyword_break */ + case 339: /* primary: "'break'" */ #line 2914 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_break(p, 0); } -#line 8716 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8715 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 340: /* primary: keyword_next */ + case 340: /* primary: "'next'" */ #line 2918 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_next(p, 0); } -#line 8724 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8723 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 341: /* primary: keyword_redo */ + case 341: /* primary: "'redo'" */ #line 2922 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_redo(p); } -#line 8732 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8731 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 342: /* primary: keyword_retry */ + case 342: /* primary: "'retry'" */ #line 2926 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_retry(p); } -#line 8740 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8739 "mrbgems/mruby-compiler/core/y.tab.c" break; case 343: /* primary_value: primary */ @@ -8745,23 +8744,23 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = (yyvsp[0].nd); if (!(yyval.nd)) (yyval.nd) = new_nil(p); } -#line 8749 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8748 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 350: /* if_tail: keyword_elsif expr_value then compstmt if_tail */ + case 350: /* if_tail: "'elsif'" expr_value then compstmt if_tail */ #line 2951 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_if(p, cond((yyvsp[-3].nd)), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 8757 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8756 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 352: /* opt_else: keyword_else compstmt */ + case 352: /* opt_else: "'else'" compstmt */ #line 2958 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 8765 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8764 "mrbgems/mruby-compiler/core/y.tab.c" break; case 353: /* for_var: lhs */ @@ -8769,7 +8768,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list1(list1((yyvsp[0].nd))); } -#line 8773 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8772 "mrbgems/mruby-compiler/core/y.tab.c" break; case 355: /* f_margs: f_arg */ @@ -8777,7 +8776,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list3((yyvsp[0].nd),0,0); } -#line 8781 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8780 "mrbgems/mruby-compiler/core/y.tab.c" break; case 356: /* f_margs: f_arg ',' "*" f_norm_arg */ @@ -8785,7 +8784,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list3((yyvsp[-3].nd), new_arg(p, (yyvsp[0].id)), 0); } -#line 8789 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8788 "mrbgems/mruby-compiler/core/y.tab.c" break; case 357: /* f_margs: f_arg ',' "*" f_norm_arg ',' f_arg */ @@ -8793,7 +8792,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list3((yyvsp[-5].nd), new_arg(p, (yyvsp[-2].id)), (yyvsp[0].nd)); } -#line 8797 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8796 "mrbgems/mruby-compiler/core/y.tab.c" break; case 358: /* f_margs: f_arg ',' "*" */ @@ -8802,7 +8801,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); local_add_f(p, intern_op(mul)); (yyval.nd) = list3((yyvsp[-2].nd), nint(-1), 0); } -#line 8806 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8805 "mrbgems/mruby-compiler/core/y.tab.c" break; case 359: /* f_margs: f_arg ',' "*" ',' f_arg */ @@ -8810,7 +8809,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list3((yyvsp[-4].nd), nint(-1), (yyvsp[0].nd)); } -#line 8814 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8813 "mrbgems/mruby-compiler/core/y.tab.c" break; case 360: /* f_margs: "*" f_norm_arg */ @@ -8818,7 +8817,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list3(0, new_arg(p, (yyvsp[0].id)), 0); } -#line 8822 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8821 "mrbgems/mruby-compiler/core/y.tab.c" break; case 361: /* f_margs: "*" f_norm_arg ',' f_arg */ @@ -8826,7 +8825,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list3(0, new_arg(p, (yyvsp[-2].id)), (yyvsp[0].nd)); } -#line 8830 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8829 "mrbgems/mruby-compiler/core/y.tab.c" break; case 362: /* f_margs: "*" */ @@ -8835,7 +8834,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); local_add_f(p, intern_op(mul)); (yyval.nd) = list3(0, nint(-1), 0); } -#line 8839 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8838 "mrbgems/mruby-compiler/core/y.tab.c" break; case 363: /* $@24: %empty */ @@ -8843,7 +8842,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { local_add_f(p, intern_op(mul)); } -#line 8847 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8846 "mrbgems/mruby-compiler/core/y.tab.c" break; case 364: /* f_margs: "*" ',' $@24 f_arg */ @@ -8851,7 +8850,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list3(0, nint(-1), (yyvsp[0].nd)); } -#line 8855 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8854 "mrbgems/mruby-compiler/core/y.tab.c" break; case 365: /* block_args_tail: f_block_kwarg ',' f_kwrest opt_f_block_arg */ @@ -8859,7 +8858,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args_tail(p, (yyvsp[-3].nd), (yyvsp[-1].nd), (yyvsp[0].id)); } -#line 8863 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8862 "mrbgems/mruby-compiler/core/y.tab.c" break; case 366: /* block_args_tail: f_block_kwarg opt_f_block_arg */ @@ -8867,7 +8866,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args_tail(p, (yyvsp[-1].nd), 0, (yyvsp[0].id)); } -#line 8871 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8870 "mrbgems/mruby-compiler/core/y.tab.c" break; case 367: /* block_args_tail: f_kwrest opt_f_block_arg */ @@ -8875,7 +8874,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args_tail(p, 0, (yyvsp[-1].nd), (yyvsp[0].id)); } -#line 8879 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8878 "mrbgems/mruby-compiler/core/y.tab.c" break; case 368: /* block_args_tail: f_block_arg */ @@ -8883,7 +8882,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args_tail(p, 0, 0, (yyvsp[0].id)); } -#line 8887 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8886 "mrbgems/mruby-compiler/core/y.tab.c" break; case 369: /* opt_block_args_tail: ',' block_args_tail */ @@ -8891,7 +8890,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = (yyvsp[0].nd); } -#line 8895 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8894 "mrbgems/mruby-compiler/core/y.tab.c" break; case 370: /* opt_block_args_tail: %empty */ @@ -8899,7 +8898,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args_tail(p, 0, 0, 0); } -#line 8903 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8902 "mrbgems/mruby-compiler/core/y.tab.c" break; case 371: /* block_param: f_arg ',' f_block_optarg ',' f_rest_arg opt_block_args_tail */ @@ -8907,7 +8906,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args(p, (yyvsp[-5].nd), (yyvsp[-3].nd), (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 8911 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8910 "mrbgems/mruby-compiler/core/y.tab.c" break; case 372: /* block_param: f_arg ',' f_block_optarg ',' f_rest_arg ',' f_arg opt_block_args_tail */ @@ -8915,7 +8914,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args(p, (yyvsp[-7].nd), (yyvsp[-5].nd), (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 8919 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8918 "mrbgems/mruby-compiler/core/y.tab.c" break; case 373: /* block_param: f_arg ',' f_block_optarg opt_block_args_tail */ @@ -8923,7 +8922,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args(p, (yyvsp[-3].nd), (yyvsp[-1].nd), 0, 0, (yyvsp[0].nd)); } -#line 8927 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8926 "mrbgems/mruby-compiler/core/y.tab.c" break; case 374: /* block_param: f_arg ',' f_block_optarg ',' f_arg opt_block_args_tail */ @@ -8931,7 +8930,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args(p, (yyvsp[-5].nd), (yyvsp[-3].nd), 0, (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 8935 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8934 "mrbgems/mruby-compiler/core/y.tab.c" break; case 375: /* block_param: f_arg ',' f_rest_arg opt_block_args_tail */ @@ -8939,7 +8938,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args(p, (yyvsp[-3].nd), 0, (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 8943 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8942 "mrbgems/mruby-compiler/core/y.tab.c" break; case 376: /* block_param: f_arg ',' opt_block_args_tail */ @@ -8947,7 +8946,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args(p, (yyvsp[-2].nd), 0, 0, 0, (yyvsp[0].nd)); } -#line 8951 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8950 "mrbgems/mruby-compiler/core/y.tab.c" break; case 377: /* block_param: f_arg ',' f_rest_arg ',' f_arg opt_block_args_tail */ @@ -8955,7 +8954,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args(p, (yyvsp[-5].nd), 0, (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 8959 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8958 "mrbgems/mruby-compiler/core/y.tab.c" break; case 378: /* block_param: f_arg opt_block_args_tail */ @@ -8963,7 +8962,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args(p, (yyvsp[-1].nd), 0, 0, 0, (yyvsp[0].nd)); } -#line 8967 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8966 "mrbgems/mruby-compiler/core/y.tab.c" break; case 379: /* block_param: f_block_optarg ',' f_rest_arg opt_block_args_tail */ @@ -8971,7 +8970,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args(p, 0, (yyvsp[-3].nd), (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 8975 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8974 "mrbgems/mruby-compiler/core/y.tab.c" break; case 380: /* block_param: f_block_optarg ',' f_rest_arg ',' f_arg opt_block_args_tail */ @@ -8979,7 +8978,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args(p, 0, (yyvsp[-5].nd), (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 8983 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8982 "mrbgems/mruby-compiler/core/y.tab.c" break; case 381: /* block_param: f_block_optarg opt_block_args_tail */ @@ -8987,7 +8986,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args(p, 0, (yyvsp[-1].nd), 0, 0, (yyvsp[0].nd)); } -#line 8991 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8990 "mrbgems/mruby-compiler/core/y.tab.c" break; case 382: /* block_param: f_block_optarg ',' f_arg opt_block_args_tail */ @@ -8995,7 +8994,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args(p, 0, (yyvsp[-3].nd), 0, (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 8999 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8998 "mrbgems/mruby-compiler/core/y.tab.c" break; case 383: /* block_param: f_rest_arg opt_block_args_tail */ @@ -9003,7 +9002,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args(p, 0, 0, (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 9007 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9006 "mrbgems/mruby-compiler/core/y.tab.c" break; case 384: /* block_param: f_rest_arg ',' f_arg opt_block_args_tail */ @@ -9011,7 +9010,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args(p, 0, 0, (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 9015 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9014 "mrbgems/mruby-compiler/core/y.tab.c" break; case 385: /* block_param: block_args_tail */ @@ -9019,7 +9018,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args(p, 0, 0, 0, 0, (yyvsp[0].nd)); } -#line 9023 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9022 "mrbgems/mruby-compiler/core/y.tab.c" break; case 386: /* opt_block_param: none */ @@ -9028,7 +9027,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); local_add_blk(p, 0); (yyval.nd) = 0; } -#line 9032 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9031 "mrbgems/mruby-compiler/core/y.tab.c" break; case 387: /* opt_block_param: block_param_def */ @@ -9037,13 +9036,13 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->cmd_start = TRUE; (yyval.nd) = (yyvsp[0].nd); } -#line 9041 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9040 "mrbgems/mruby-compiler/core/y.tab.c" break; case 388: /* $@25: %empty */ #line 3116 "mrbgems/mruby-compiler/core/parse.y" {local_add_blk(p, 0);} -#line 9047 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9046 "mrbgems/mruby-compiler/core/y.tab.c" break; case 389: /* block_param_def: '|' $@25 opt_bv_decl '|' */ @@ -9051,7 +9050,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = 0; } -#line 9055 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9054 "mrbgems/mruby-compiler/core/y.tab.c" break; case 390: /* block_param_def: "||" */ @@ -9060,7 +9059,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); local_add_blk(p, 0); (yyval.nd) = 0; } -#line 9064 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9063 "mrbgems/mruby-compiler/core/y.tab.c" break; case 391: /* block_param_def: '|' block_param opt_bv_decl '|' */ @@ -9068,7 +9067,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = (yyvsp[-2].nd); } -#line 9072 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9071 "mrbgems/mruby-compiler/core/y.tab.c" break; case 392: /* opt_bv_decl: opt_nl */ @@ -9076,7 +9075,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = 0; } -#line 9080 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9079 "mrbgems/mruby-compiler/core/y.tab.c" break; case 393: /* opt_bv_decl: opt_nl ';' bv_decls opt_nl */ @@ -9084,7 +9083,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = 0; } -#line 9088 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9087 "mrbgems/mruby-compiler/core/y.tab.c" break; case 396: /* bvar: "local variable or method" */ @@ -9093,7 +9092,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); local_add_f(p, (yyvsp[0].id)); new_bv(p, (yyvsp[0].id)); } -#line 9097 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9096 "mrbgems/mruby-compiler/core/y.tab.c" break; case 398: /* f_larglist: '(' f_args opt_bv_decl ')' */ @@ -9101,7 +9100,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = (yyvsp[-2].nd); } -#line 9105 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9104 "mrbgems/mruby-compiler/core/y.tab.c" break; case 399: /* f_larglist: f_args */ @@ -9109,7 +9108,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = (yyvsp[0].nd); } -#line 9113 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9112 "mrbgems/mruby-compiler/core/y.tab.c" break; case 400: /* lambda_body: tLAMBEG compstmt '}' */ @@ -9117,38 +9116,40 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = (yyvsp[-1].nd); } -#line 9121 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9120 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 401: /* lambda_body: keyword_do_LAMBDA bodystmt keyword_end */ + case 401: /* lambda_body: "'do' for lambda" bodystmt "'end'" */ #line 3169 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 9129 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9128 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 402: /* $@26: %empty */ + case 402: /* @26: %empty */ #line 3175 "mrbgems/mruby-compiler/core/parse.y" { local_nest(p); nvars_nest(p); + (yyval.num) = p->lineno; } #line 9138 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 403: /* do_block: keyword_do_block $@26 opt_block_param bodystmt keyword_end */ -#line 3182 "mrbgems/mruby-compiler/core/parse.y" + case 403: /* do_block: "'do' for block" @26 opt_block_param bodystmt "'end'" */ +#line 3183 "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 9148 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9149 "mrbgems/mruby-compiler/core/y.tab.c" break; case 404: /* block_call: command do_block */ -#line 3190 "mrbgems/mruby-compiler/core/parse.y" +#line 3192 "mrbgems/mruby-compiler/core/parse.y" { if (typen((yyvsp[-1].nd)->car) == NODE_YIELD) { yyerror(p, "block given to yield"); @@ -9158,159 +9159,159 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } (yyval.nd) = (yyvsp[-1].nd); } -#line 9162 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9163 "mrbgems/mruby-compiler/core/y.tab.c" break; case 405: /* block_call: block_call call_op2 operation2 opt_paren_args */ -#line 3200 "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 9170 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9171 "mrbgems/mruby-compiler/core/y.tab.c" break; case 406: /* block_call: block_call call_op2 operation2 opt_paren_args brace_block */ -#line 3204 "mrbgems/mruby-compiler/core/parse.y" +#line 3206 "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 9179 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9180 "mrbgems/mruby-compiler/core/y.tab.c" break; case 407: /* block_call: block_call call_op2 operation2 command_args do_block */ -#line 3209 "mrbgems/mruby-compiler/core/parse.y" +#line 3211 "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 9188 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9189 "mrbgems/mruby-compiler/core/y.tab.c" break; case 408: /* method_call: operation paren_args */ -#line 3216 "mrbgems/mruby-compiler/core/parse.y" +#line 3218 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_fcall(p, (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 9196 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9197 "mrbgems/mruby-compiler/core/y.tab.c" break; case 409: /* method_call: primary_value call_op operation2 opt_paren_args */ -#line 3220 "mrbgems/mruby-compiler/core/parse.y" +#line 3222 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), (yyvsp[-2].num)); } -#line 9204 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9205 "mrbgems/mruby-compiler/core/y.tab.c" break; case 410: /* method_call: primary_value "::" operation2 paren_args */ -#line 3224 "mrbgems/mruby-compiler/core/parse.y" +#line 3226 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), tCOLON2); } -#line 9212 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9213 "mrbgems/mruby-compiler/core/y.tab.c" break; case 411: /* method_call: primary_value "::" operation3 */ -#line 3228 "mrbgems/mruby-compiler/core/parse.y" +#line 3230 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, tCOLON2); } -#line 9220 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9221 "mrbgems/mruby-compiler/core/y.tab.c" break; case 412: /* method_call: primary_value call_op paren_args */ -#line 3232 "mrbgems/mruby-compiler/core/parse.y" +#line 3234 "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 9228 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9229 "mrbgems/mruby-compiler/core/y.tab.c" break; case 413: /* method_call: primary_value "::" paren_args */ -#line 3236 "mrbgems/mruby-compiler/core/parse.y" +#line 3238 "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 9236 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9237 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 414: /* method_call: keyword_super paren_args */ -#line 3240 "mrbgems/mruby-compiler/core/parse.y" + case 414: /* method_call: "'super'" paren_args */ +#line 3242 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_super(p, (yyvsp[0].nd)); } -#line 9244 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9245 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 415: /* method_call: keyword_super */ -#line 3244 "mrbgems/mruby-compiler/core/parse.y" + case 415: /* method_call: "'super'" */ +#line 3246 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_zsuper(p); } -#line 9252 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9253 "mrbgems/mruby-compiler/core/y.tab.c" break; case 416: /* method_call: primary_value '[' opt_call_args ']' */ -#line 3248 "mrbgems/mruby-compiler/core/parse.y" +#line 3250 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), intern_op(aref), (yyvsp[-1].nd), '.'); } -#line 9260 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9261 "mrbgems/mruby-compiler/core/y.tab.c" break; case 417: /* @27: %empty */ -#line 3254 "mrbgems/mruby-compiler/core/parse.y" +#line 3256 "mrbgems/mruby-compiler/core/parse.y" { local_nest(p); nvars_nest(p); (yyval.num) = p->lineno; } -#line 9270 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9271 "mrbgems/mruby-compiler/core/y.tab.c" break; case 418: /* brace_block: '{' @27 opt_block_param compstmt '}' */ -#line 3261 "mrbgems/mruby-compiler/core/parse.y" +#line 3263 "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 9281 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9282 "mrbgems/mruby-compiler/core/y.tab.c" break; case 419: /* @28: %empty */ -#line 3268 "mrbgems/mruby-compiler/core/parse.y" +#line 3270 "mrbgems/mruby-compiler/core/parse.y" { local_nest(p); nvars_nest(p); (yyval.num) = p->lineno; } -#line 9291 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9292 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 420: /* brace_block: keyword_do @28 opt_block_param bodystmt keyword_end */ -#line 3275 "mrbgems/mruby-compiler/core/parse.y" + case 420: /* brace_block: "'do'" @28 opt_block_param bodystmt "'end'" */ +#line 3277 "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 9302 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9303 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 421: /* case_body: keyword_when args then compstmt cases */ -#line 3286 "mrbgems/mruby-compiler/core/parse.y" + case 421: /* case_body: "'when'" args then compstmt cases */ +#line 3288 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = cons(cons((yyvsp[-3].nd), (yyvsp[-1].nd)), (yyvsp[0].nd)); } -#line 9310 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9311 "mrbgems/mruby-compiler/core/y.tab.c" break; case 422: /* cases: opt_else */ -#line 3292 "mrbgems/mruby-compiler/core/parse.y" +#line 3294 "mrbgems/mruby-compiler/core/parse.y" { if ((yyvsp[0].nd)) { (yyval.nd) = cons(cons(0, (yyvsp[0].nd)), 0); @@ -9319,60 +9320,60 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = 0; } } -#line 9323 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9324 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 424: /* opt_rescue: keyword_rescue exc_list exc_var then compstmt opt_rescue */ -#line 3306 "mrbgems/mruby-compiler/core/parse.y" + case 424: /* opt_rescue: "'rescue'" exc_list exc_var then compstmt opt_rescue */ +#line 3308 "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 9332 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9333 "mrbgems/mruby-compiler/core/y.tab.c" break; case 426: /* exc_list: arg */ -#line 3314 "mrbgems/mruby-compiler/core/parse.y" +#line 3316 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 9340 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9341 "mrbgems/mruby-compiler/core/y.tab.c" break; case 429: /* exc_var: "=>" lhs */ -#line 3322 "mrbgems/mruby-compiler/core/parse.y" +#line 3324 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 9348 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9349 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 431: /* opt_ensure: keyword_ensure compstmt */ -#line 3329 "mrbgems/mruby-compiler/core/parse.y" + case 431: /* opt_ensure: "'ensure'" compstmt */ +#line 3331 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 9356 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9357 "mrbgems/mruby-compiler/core/y.tab.c" break; case 438: /* string: string string_fragment */ -#line 3343 "mrbgems/mruby-compiler/core/parse.y" +#line 3345 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = concat_string(p, (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 9364 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9365 "mrbgems/mruby-compiler/core/y.tab.c" break; case 441: /* string_fragment: "string literal" tSTRING */ -#line 3351 "mrbgems/mruby-compiler/core/parse.y" +#line 3353 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 9372 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9373 "mrbgems/mruby-compiler/core/y.tab.c" break; case 442: /* string_fragment: "string literal" string_rep tSTRING */ -#line 3355 "mrbgems/mruby-compiler/core/parse.y" +#line 3357 "mrbgems/mruby-compiler/core/parse.y" { node *n = (yyvsp[-1].nd); if (intn((yyvsp[0].nd)->cdr->cdr) > 0) { @@ -9383,68 +9384,68 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } (yyval.nd) = new_dstr(p, n); } -#line 9387 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9388 "mrbgems/mruby-compiler/core/y.tab.c" break; case 444: /* string_rep: string_rep string_interp */ -#line 3369 "mrbgems/mruby-compiler/core/parse.y" +#line 3371 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = append((yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 9395 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9396 "mrbgems/mruby-compiler/core/y.tab.c" break; case 445: /* string_interp: tSTRING_MID */ -#line 3375 "mrbgems/mruby-compiler/core/parse.y" +#line 3377 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 9403 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9404 "mrbgems/mruby-compiler/core/y.tab.c" break; case 446: /* @29: %empty */ -#line 3379 "mrbgems/mruby-compiler/core/parse.y" +#line 3381 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push_strterm(p); } -#line 9411 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9412 "mrbgems/mruby-compiler/core/y.tab.c" break; case 447: /* string_interp: tSTRING_PART @29 compstmt '}' */ -#line 3384 "mrbgems/mruby-compiler/core/parse.y" +#line 3386 "mrbgems/mruby-compiler/core/parse.y" { pop_strterm(p,(yyvsp[-2].nd)); (yyval.nd) = list2((yyvsp[-3].nd), (yyvsp[-1].nd)); } -#line 9420 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9421 "mrbgems/mruby-compiler/core/y.tab.c" break; case 448: /* string_interp: tLITERAL_DELIM */ -#line 3389 "mrbgems/mruby-compiler/core/parse.y" +#line 3391 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1(new_literal_delim(p)); } -#line 9428 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9429 "mrbgems/mruby-compiler/core/y.tab.c" break; case 449: /* string_interp: tHD_LITERAL_DELIM heredoc_bodies */ -#line 3393 "mrbgems/mruby-compiler/core/parse.y" +#line 3395 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1(new_literal_delim(p)); } -#line 9436 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9437 "mrbgems/mruby-compiler/core/y.tab.c" break; case 450: /* xstring: tXSTRING_BEG tXSTRING */ -#line 3399 "mrbgems/mruby-compiler/core/parse.y" +#line 3401 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 9444 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9445 "mrbgems/mruby-compiler/core/y.tab.c" break; case 451: /* xstring: tXSTRING_BEG string_rep tXSTRING */ -#line 3403 "mrbgems/mruby-compiler/core/parse.y" +#line 3405 "mrbgems/mruby-compiler/core/parse.y" { node *n = (yyvsp[-1].nd); if (intn((yyvsp[0].nd)->cdr->cdr) > 0) { @@ -9455,81 +9456,81 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } (yyval.nd) = new_dxstr(p, n); } -#line 9459 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9460 "mrbgems/mruby-compiler/core/y.tab.c" break; case 452: /* regexp: tREGEXP_BEG tREGEXP */ -#line 3416 "mrbgems/mruby-compiler/core/parse.y" +#line 3418 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 9467 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9468 "mrbgems/mruby-compiler/core/y.tab.c" break; case 453: /* regexp: tREGEXP_BEG string_rep tREGEXP */ -#line 3420 "mrbgems/mruby-compiler/core/parse.y" +#line 3422 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_dregx(p, (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 9475 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9476 "mrbgems/mruby-compiler/core/y.tab.c" break; case 457: /* heredoc_body: tHEREDOC_END */ -#line 3433 "mrbgems/mruby-compiler/core/parse.y" +#line 3435 "mrbgems/mruby-compiler/core/parse.y" { parser_heredoc_info *info = parsing_heredoc_info(p); info->doc = push(info->doc, new_str(p, "", 0)); heredoc_end(p); } -#line 9485 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9486 "mrbgems/mruby-compiler/core/y.tab.c" break; case 458: /* heredoc_body: heredoc_string_rep tHEREDOC_END */ -#line 3439 "mrbgems/mruby-compiler/core/parse.y" +#line 3441 "mrbgems/mruby-compiler/core/parse.y" { heredoc_end(p); } -#line 9493 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9494 "mrbgems/mruby-compiler/core/y.tab.c" break; case 461: /* heredoc_string_interp: tHD_STRING_MID */ -#line 3449 "mrbgems/mruby-compiler/core/parse.y" +#line 3451 "mrbgems/mruby-compiler/core/parse.y" { parser_heredoc_info *info = parsing_heredoc_info(p); info->doc = push(info->doc, (yyvsp[0].nd)); heredoc_treat_nextline(p); } -#line 9503 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9504 "mrbgems/mruby-compiler/core/y.tab.c" break; case 462: /* @30: %empty */ -#line 3455 "mrbgems/mruby-compiler/core/parse.y" +#line 3457 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push_strterm(p); } -#line 9511 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9512 "mrbgems/mruby-compiler/core/y.tab.c" break; case 463: /* heredoc_string_interp: tHD_STRING_PART @30 compstmt '}' */ -#line 3460 "mrbgems/mruby-compiler/core/parse.y" +#line 3462 "mrbgems/mruby-compiler/core/parse.y" { pop_strterm(p, (yyvsp[-2].nd)); parser_heredoc_info *info = parsing_heredoc_info(p); info->doc = push(push(info->doc, (yyvsp[-3].nd)), (yyvsp[-1].nd)); } -#line 9521 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9522 "mrbgems/mruby-compiler/core/y.tab.c" break; case 464: /* words: tWORDS_BEG tSTRING */ -#line 3468 "mrbgems/mruby-compiler/core/parse.y" +#line 3470 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_words(p, list1((yyvsp[0].nd))); } -#line 9529 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9530 "mrbgems/mruby-compiler/core/y.tab.c" break; case 465: /* words: tWORDS_BEG string_rep tSTRING */ -#line 3472 "mrbgems/mruby-compiler/core/parse.y" +#line 3474 "mrbgems/mruby-compiler/core/parse.y" { node *n = (yyvsp[-1].nd); if (intn((yyvsp[0].nd)->cdr->cdr) > 0) { @@ -9540,20 +9541,20 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } (yyval.nd) = new_words(p, n); } -#line 9544 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9545 "mrbgems/mruby-compiler/core/y.tab.c" break; case 466: /* symbol: basic_symbol */ -#line 3486 "mrbgems/mruby-compiler/core/parse.y" +#line 3488 "mrbgems/mruby-compiler/core/parse.y" { p->lstate = EXPR_ENDARG; (yyval.nd) = new_sym(p, (yyvsp[0].id)); } -#line 9553 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9554 "mrbgems/mruby-compiler/core/y.tab.c" break; case 467: /* symbol: "symbol" "string literal" string_rep tSTRING */ -#line 3491 "mrbgems/mruby-compiler/core/parse.y" +#line 3493 "mrbgems/mruby-compiler/core/parse.y" { node *n = (yyvsp[-1].nd); p->lstate = EXPR_ENDARG; @@ -9565,43 +9566,43 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } (yyval.nd) = new_dsym(p, new_dstr(p, n)); } -#line 9569 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9570 "mrbgems/mruby-compiler/core/y.tab.c" break; case 468: /* basic_symbol: "symbol" sym */ -#line 3505 "mrbgems/mruby-compiler/core/parse.y" +#line 3507 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = (yyvsp[0].id); } -#line 9577 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9578 "mrbgems/mruby-compiler/core/y.tab.c" break; case 473: /* sym: tSTRING */ -#line 3515 "mrbgems/mruby-compiler/core/parse.y" +#line 3517 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = new_strsym(p, (yyvsp[0].nd)); } -#line 9585 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9586 "mrbgems/mruby-compiler/core/y.tab.c" break; case 474: /* sym: "string literal" tSTRING */ -#line 3519 "mrbgems/mruby-compiler/core/parse.y" +#line 3521 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = new_strsym(p, (yyvsp[0].nd)); } -#line 9593 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9594 "mrbgems/mruby-compiler/core/y.tab.c" break; case 475: /* symbols: tSYMBOLS_BEG tSTRING */ -#line 3525 "mrbgems/mruby-compiler/core/parse.y" +#line 3527 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_symbols(p, list1((yyvsp[0].nd))); } -#line 9601 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9602 "mrbgems/mruby-compiler/core/y.tab.c" break; case 476: /* symbols: tSYMBOLS_BEG string_rep tSTRING */ -#line 3529 "mrbgems/mruby-compiler/core/parse.y" +#line 3531 "mrbgems/mruby-compiler/core/parse.y" { node *n = (yyvsp[-1].nd); if (intn((yyvsp[0].nd)->cdr->cdr) > 0) { @@ -9609,123 +9610,123 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } (yyval.nd) = new_symbols(p, n); } -#line 9613 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9614 "mrbgems/mruby-compiler/core/y.tab.c" break; case 479: /* numeric: tUMINUS_NUM "integer literal" */ -#line 3541 "mrbgems/mruby-compiler/core/parse.y" +#line 3543 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_negate(p, (yyvsp[0].nd)); } -#line 9621 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9622 "mrbgems/mruby-compiler/core/y.tab.c" break; case 480: /* numeric: tUMINUS_NUM "float literal" */ -#line 3545 "mrbgems/mruby-compiler/core/parse.y" +#line 3547 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_negate(p, (yyvsp[0].nd)); } -#line 9629 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9630 "mrbgems/mruby-compiler/core/y.tab.c" break; case 481: /* variable: "local variable or method" */ -#line 3551 "mrbgems/mruby-compiler/core/parse.y" +#line 3553 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_lvar(p, (yyvsp[0].id)); } -#line 9637 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9638 "mrbgems/mruby-compiler/core/y.tab.c" break; case 482: /* variable: "instance variable" */ -#line 3555 "mrbgems/mruby-compiler/core/parse.y" +#line 3557 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_ivar(p, (yyvsp[0].id)); } -#line 9645 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9646 "mrbgems/mruby-compiler/core/y.tab.c" break; case 483: /* variable: "global variable" */ -#line 3559 "mrbgems/mruby-compiler/core/parse.y" +#line 3561 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_gvar(p, (yyvsp[0].id)); } -#line 9653 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9654 "mrbgems/mruby-compiler/core/y.tab.c" break; case 484: /* variable: "class variable" */ -#line 3563 "mrbgems/mruby-compiler/core/parse.y" +#line 3565 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_cvar(p, (yyvsp[0].id)); } -#line 9661 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9662 "mrbgems/mruby-compiler/core/y.tab.c" break; case 485: /* variable: "constant" */ -#line 3567 "mrbgems/mruby-compiler/core/parse.y" +#line 3569 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_const(p, (yyvsp[0].id)); } -#line 9669 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9670 "mrbgems/mruby-compiler/core/y.tab.c" break; case 486: /* var_lhs: variable */ -#line 3573 "mrbgems/mruby-compiler/core/parse.y" +#line 3575 "mrbgems/mruby-compiler/core/parse.y" { assignable(p, (yyvsp[0].nd)); } -#line 9677 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9678 "mrbgems/mruby-compiler/core/y.tab.c" break; case 487: /* var_lhs: "numbered parameter" */ -#line 3577 "mrbgems/mruby-compiler/core/parse.y" +#line 3579 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "can't assign to numbered parameter"); } -#line 9685 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9686 "mrbgems/mruby-compiler/core/y.tab.c" break; case 488: /* var_ref: variable */ -#line 3583 "mrbgems/mruby-compiler/core/parse.y" +#line 3585 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = var_reference(p, (yyvsp[0].nd)); } -#line 9693 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9694 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 489: /* var_ref: keyword_nil */ -#line 3587 "mrbgems/mruby-compiler/core/parse.y" + case 489: /* var_ref: "'nil'" */ +#line 3589 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_nil(p); } -#line 9701 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9702 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 490: /* var_ref: keyword_self */ -#line 3591 "mrbgems/mruby-compiler/core/parse.y" + case 490: /* var_ref: "'self'" */ +#line 3593 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_self(p); } -#line 9709 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9710 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 491: /* var_ref: keyword_true */ -#line 3595 "mrbgems/mruby-compiler/core/parse.y" + case 491: /* var_ref: "'true'" */ +#line 3597 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_true(p); } -#line 9717 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9718 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 492: /* var_ref: keyword_false */ -#line 3599 "mrbgems/mruby-compiler/core/parse.y" + case 492: /* var_ref: "'false'" */ +#line 3601 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_false(p); } -#line 9725 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9726 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 493: /* var_ref: keyword__FILE__ */ -#line 3603 "mrbgems/mruby-compiler/core/parse.y" + case 493: /* var_ref: "'__FILE__'" */ +#line 3605 "mrbgems/mruby-compiler/core/parse.y" { const char *fn = mrb_sym_name_len(p->mrb, p->filename_sym, NULL); if (!fn) { @@ -9733,607 +9734,607 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } (yyval.nd) = new_str(p, fn, strlen(fn)); } -#line 9737 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9738 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 494: /* var_ref: keyword__LINE__ */ -#line 3611 "mrbgems/mruby-compiler/core/parse.y" + case 494: /* var_ref: "'__LINE__'" */ +#line 3613 "mrbgems/mruby-compiler/core/parse.y" { char buf[16]; dump_int(p->lineno, buf); (yyval.nd) = new_int(p, buf, 10, 0); } -#line 9748 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9749 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 495: /* var_ref: keyword__ENCODING__ */ -#line 3618 "mrbgems/mruby-compiler/core/parse.y" + case 495: /* var_ref: "'__ENCODING__'" */ +#line 3620 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_fcall(p, MRB_SYM_2(p->mrb, __ENCODING__), 0); } -#line 9756 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9757 "mrbgems/mruby-compiler/core/y.tab.c" break; case 498: /* superclass: %empty */ -#line 3628 "mrbgems/mruby-compiler/core/parse.y" +#line 3630 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = 0; } -#line 9764 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9765 "mrbgems/mruby-compiler/core/y.tab.c" break; case 499: /* $@31: %empty */ -#line 3632 "mrbgems/mruby-compiler/core/parse.y" +#line 3634 "mrbgems/mruby-compiler/core/parse.y" { p->lstate = EXPR_BEG; p->cmd_start = TRUE; } -#line 9773 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9774 "mrbgems/mruby-compiler/core/y.tab.c" break; case 500: /* superclass: '<' $@31 expr_value term */ -#line 3637 "mrbgems/mruby-compiler/core/parse.y" +#line 3639 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 9781 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9782 "mrbgems/mruby-compiler/core/y.tab.c" break; case 503: /* f_arglist_paren: '(' f_args rparen */ -#line 3653 "mrbgems/mruby-compiler/core/parse.y" +#line 3655 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); p->lstate = EXPR_BEG; p->cmd_start = TRUE; } -#line 9791 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9792 "mrbgems/mruby-compiler/core/y.tab.c" break; case 504: /* f_arglist_paren: '(' f_arg ',' tBDOT3 rparen */ -#line 3659 "mrbgems/mruby-compiler/core/parse.y" +#line 3661 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_dots(p, (yyvsp[-3].nd)); } -#line 9799 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9800 "mrbgems/mruby-compiler/core/y.tab.c" break; case 505: /* f_arglist_paren: '(' tBDOT3 rparen */ -#line 3663 "mrbgems/mruby-compiler/core/parse.y" +#line 3665 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_dots(p, 0); } -#line 9807 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9808 "mrbgems/mruby-compiler/core/y.tab.c" break; case 507: /* f_arglist: f_args term */ -#line 3670 "mrbgems/mruby-compiler/core/parse.y" +#line 3672 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 9815 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9816 "mrbgems/mruby-compiler/core/y.tab.c" break; case 508: /* f_arglist: f_arg ',' tBDOT3 term */ -#line 3674 "mrbgems/mruby-compiler/core/parse.y" +#line 3676 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_dots(p, (yyvsp[-3].nd)); } -#line 9823 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9824 "mrbgems/mruby-compiler/core/y.tab.c" break; case 509: /* f_arglist: "..." term */ -#line 3678 "mrbgems/mruby-compiler/core/parse.y" +#line 3680 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_dots(p, 0); } -#line 9831 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9832 "mrbgems/mruby-compiler/core/y.tab.c" break; case 510: /* f_label: "local variable or method" "label" */ -#line 3684 "mrbgems/mruby-compiler/core/parse.y" +#line 3686 "mrbgems/mruby-compiler/core/parse.y" { local_nest(p); } -#line 9839 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9840 "mrbgems/mruby-compiler/core/y.tab.c" break; case 511: /* f_label: "numbered parameter" "label" */ -#line 3688 "mrbgems/mruby-compiler/core/parse.y" +#line 3690 "mrbgems/mruby-compiler/core/parse.y" { local_nest(p); } -#line 9847 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9848 "mrbgems/mruby-compiler/core/y.tab.c" break; case 512: /* f_kw: f_label arg */ -#line 3694 "mrbgems/mruby-compiler/core/parse.y" +#line 3696 "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 9857 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9858 "mrbgems/mruby-compiler/core/y.tab.c" break; case 513: /* f_kw: f_label */ -#line 3700 "mrbgems/mruby-compiler/core/parse.y" +#line 3702 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_kw_arg(p, (yyvsp[0].id), 0); local_unnest(p); } -#line 9866 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9867 "mrbgems/mruby-compiler/core/y.tab.c" break; case 514: /* f_block_kw: f_label primary_value */ -#line 3707 "mrbgems/mruby-compiler/core/parse.y" +#line 3709 "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 9876 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9877 "mrbgems/mruby-compiler/core/y.tab.c" break; case 515: /* f_block_kw: f_label */ -#line 3713 "mrbgems/mruby-compiler/core/parse.y" +#line 3715 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_kw_arg(p, (yyvsp[0].id), 0); local_unnest(p); } -#line 9885 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9886 "mrbgems/mruby-compiler/core/y.tab.c" break; case 516: /* f_block_kwarg: f_block_kw */ -#line 3720 "mrbgems/mruby-compiler/core/parse.y" +#line 3722 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 9893 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9894 "mrbgems/mruby-compiler/core/y.tab.c" break; case 517: /* f_block_kwarg: f_block_kwarg ',' f_block_kw */ -#line 3724 "mrbgems/mruby-compiler/core/parse.y" +#line 3726 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 9901 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9902 "mrbgems/mruby-compiler/core/y.tab.c" break; case 518: /* f_kwarg: f_kw */ -#line 3730 "mrbgems/mruby-compiler/core/parse.y" +#line 3732 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 9909 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9910 "mrbgems/mruby-compiler/core/y.tab.c" break; case 519: /* f_kwarg: f_kwarg ',' f_kw */ -#line 3734 "mrbgems/mruby-compiler/core/parse.y" +#line 3736 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 9917 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9918 "mrbgems/mruby-compiler/core/y.tab.c" break; case 522: /* f_kwrest: kwrest_mark "local variable or method" */ -#line 3744 "mrbgems/mruby-compiler/core/parse.y" +#line 3746 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_kw_rest_args(p, (yyvsp[0].id)); } -#line 9925 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9926 "mrbgems/mruby-compiler/core/y.tab.c" break; case 523: /* f_kwrest: kwrest_mark */ -#line 3748 "mrbgems/mruby-compiler/core/parse.y" +#line 3750 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_kw_rest_args(p, 0); } -#line 9933 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9934 "mrbgems/mruby-compiler/core/y.tab.c" break; case 524: /* args_tail: f_kwarg ',' f_kwrest opt_f_block_arg */ -#line 3754 "mrbgems/mruby-compiler/core/parse.y" +#line 3756 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, (yyvsp[-3].nd), (yyvsp[-1].nd), (yyvsp[0].id)); } -#line 9941 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9942 "mrbgems/mruby-compiler/core/y.tab.c" break; case 525: /* args_tail: f_kwarg opt_f_block_arg */ -#line 3758 "mrbgems/mruby-compiler/core/parse.y" +#line 3760 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, (yyvsp[-1].nd), 0, (yyvsp[0].id)); } -#line 9949 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9950 "mrbgems/mruby-compiler/core/y.tab.c" break; case 526: /* args_tail: f_kwrest opt_f_block_arg */ -#line 3762 "mrbgems/mruby-compiler/core/parse.y" +#line 3764 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, 0, (yyvsp[-1].nd), (yyvsp[0].id)); } -#line 9957 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9958 "mrbgems/mruby-compiler/core/y.tab.c" break; case 527: /* args_tail: f_block_arg */ -#line 3766 "mrbgems/mruby-compiler/core/parse.y" +#line 3768 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, 0, 0, (yyvsp[0].id)); } -#line 9965 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9966 "mrbgems/mruby-compiler/core/y.tab.c" break; case 528: /* opt_args_tail: ',' args_tail */ -#line 3772 "mrbgems/mruby-compiler/core/parse.y" +#line 3774 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 9973 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9974 "mrbgems/mruby-compiler/core/y.tab.c" break; case 529: /* opt_args_tail: %empty */ -#line 3776 "mrbgems/mruby-compiler/core/parse.y" +#line 3778 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, 0, 0, 0); } -#line 9981 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9982 "mrbgems/mruby-compiler/core/y.tab.c" break; case 530: /* f_args: f_arg ',' f_optarg ',' f_rest_arg opt_args_tail */ -#line 3782 "mrbgems/mruby-compiler/core/parse.y" +#line 3784 "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 9989 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9990 "mrbgems/mruby-compiler/core/y.tab.c" break; case 531: /* f_args: f_arg ',' f_optarg ',' f_rest_arg ',' f_arg opt_args_tail */ -#line 3786 "mrbgems/mruby-compiler/core/parse.y" +#line 3788 "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 9997 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9998 "mrbgems/mruby-compiler/core/y.tab.c" break; case 532: /* f_args: f_arg ',' f_optarg opt_args_tail */ -#line 3790 "mrbgems/mruby-compiler/core/parse.y" +#line 3792 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-3].nd), (yyvsp[-1].nd), 0, 0, (yyvsp[0].nd)); } -#line 10005 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10006 "mrbgems/mruby-compiler/core/y.tab.c" break; case 533: /* f_args: f_arg ',' f_optarg ',' f_arg opt_args_tail */ -#line 3794 "mrbgems/mruby-compiler/core/parse.y" +#line 3796 "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 10013 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10014 "mrbgems/mruby-compiler/core/y.tab.c" break; case 534: /* f_args: f_arg ',' f_rest_arg opt_args_tail */ -#line 3798 "mrbgems/mruby-compiler/core/parse.y" +#line 3800 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-3].nd), 0, (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 10021 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10022 "mrbgems/mruby-compiler/core/y.tab.c" break; case 535: /* f_args: f_arg ',' f_rest_arg ',' f_arg opt_args_tail */ -#line 3802 "mrbgems/mruby-compiler/core/parse.y" +#line 3804 "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 10029 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10030 "mrbgems/mruby-compiler/core/y.tab.c" break; case 536: /* f_args: f_arg opt_args_tail */ -#line 3806 "mrbgems/mruby-compiler/core/parse.y" +#line 3808 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-1].nd), 0, 0, 0, (yyvsp[0].nd)); } -#line 10037 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10038 "mrbgems/mruby-compiler/core/y.tab.c" break; case 537: /* f_args: f_optarg ',' f_rest_arg opt_args_tail */ -#line 3810 "mrbgems/mruby-compiler/core/parse.y" +#line 3812 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, (yyvsp[-3].nd), (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 10045 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10046 "mrbgems/mruby-compiler/core/y.tab.c" break; case 538: /* f_args: f_optarg ',' f_rest_arg ',' f_arg opt_args_tail */ -#line 3814 "mrbgems/mruby-compiler/core/parse.y" +#line 3816 "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 10053 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10054 "mrbgems/mruby-compiler/core/y.tab.c" break; case 539: /* f_args: f_optarg opt_args_tail */ -#line 3818 "mrbgems/mruby-compiler/core/parse.y" +#line 3820 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, (yyvsp[-1].nd), 0, 0, (yyvsp[0].nd)); } -#line 10061 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10062 "mrbgems/mruby-compiler/core/y.tab.c" break; case 540: /* f_args: f_optarg ',' f_arg opt_args_tail */ -#line 3822 "mrbgems/mruby-compiler/core/parse.y" +#line 3824 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, (yyvsp[-3].nd), 0, (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 10069 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10070 "mrbgems/mruby-compiler/core/y.tab.c" break; case 541: /* f_args: f_rest_arg opt_args_tail */ -#line 3826 "mrbgems/mruby-compiler/core/parse.y" +#line 3828 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, 0, (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 10077 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10078 "mrbgems/mruby-compiler/core/y.tab.c" break; case 542: /* f_args: f_rest_arg ',' f_arg opt_args_tail */ -#line 3830 "mrbgems/mruby-compiler/core/parse.y" +#line 3832 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, 0, (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 10085 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10086 "mrbgems/mruby-compiler/core/y.tab.c" break; case 543: /* f_args: args_tail */ -#line 3834 "mrbgems/mruby-compiler/core/parse.y" +#line 3836 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, 0, 0, 0, (yyvsp[0].nd)); } -#line 10093 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10094 "mrbgems/mruby-compiler/core/y.tab.c" break; case 544: /* f_args: %empty */ -#line 3838 "mrbgems/mruby-compiler/core/parse.y" +#line 3840 "mrbgems/mruby-compiler/core/parse.y" { local_add_f(p, 0); (yyval.nd) = new_args(p, 0, 0, 0, 0, 0); } -#line 10102 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10103 "mrbgems/mruby-compiler/core/y.tab.c" break; case 545: /* f_bad_arg: "constant" */ -#line 3845 "mrbgems/mruby-compiler/core/parse.y" +#line 3847 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "formal argument cannot be a constant"); (yyval.nd) = 0; } -#line 10111 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10112 "mrbgems/mruby-compiler/core/y.tab.c" break; case 546: /* f_bad_arg: "instance variable" */ -#line 3850 "mrbgems/mruby-compiler/core/parse.y" +#line 3852 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "formal argument cannot be an instance variable"); (yyval.nd) = 0; } -#line 10120 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10121 "mrbgems/mruby-compiler/core/y.tab.c" break; case 547: /* f_bad_arg: "global variable" */ -#line 3855 "mrbgems/mruby-compiler/core/parse.y" +#line 3857 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "formal argument cannot be a global variable"); (yyval.nd) = 0; } -#line 10129 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10130 "mrbgems/mruby-compiler/core/y.tab.c" break; case 548: /* f_bad_arg: "class variable" */ -#line 3860 "mrbgems/mruby-compiler/core/parse.y" +#line 3862 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "formal argument cannot be a class variable"); (yyval.nd) = 0; } -#line 10138 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10139 "mrbgems/mruby-compiler/core/y.tab.c" break; case 549: /* f_bad_arg: "numbered parameter" */ -#line 3865 "mrbgems/mruby-compiler/core/parse.y" +#line 3867 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "formal argument cannot be a numbered parameter"); (yyval.nd) = 0; } -#line 10147 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10148 "mrbgems/mruby-compiler/core/y.tab.c" break; case 550: /* f_norm_arg: f_bad_arg */ -#line 3872 "mrbgems/mruby-compiler/core/parse.y" +#line 3874 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = 0; } -#line 10155 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10156 "mrbgems/mruby-compiler/core/y.tab.c" break; case 551: /* f_norm_arg: "local variable or method" */ -#line 3876 "mrbgems/mruby-compiler/core/parse.y" +#line 3878 "mrbgems/mruby-compiler/core/parse.y" { local_add_f(p, (yyvsp[0].id)); (yyval.id) = (yyvsp[0].id); } -#line 10164 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10165 "mrbgems/mruby-compiler/core/y.tab.c" break; case 552: /* f_arg_item: f_norm_arg */ -#line 3883 "mrbgems/mruby-compiler/core/parse.y" +#line 3885 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_arg(p, (yyvsp[0].id)); } -#line 10172 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10173 "mrbgems/mruby-compiler/core/y.tab.c" break; case 553: /* @32: %empty */ -#line 3887 "mrbgems/mruby-compiler/core/parse.y" +#line 3889 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = local_switch(p); } -#line 10180 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10181 "mrbgems/mruby-compiler/core/y.tab.c" break; case 554: /* f_arg_item: tLPAREN @32 f_margs rparen */ -#line 3891 "mrbgems/mruby-compiler/core/parse.y" +#line 3893 "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 10190 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10191 "mrbgems/mruby-compiler/core/y.tab.c" break; case 555: /* f_arg: f_arg_item */ -#line 3899 "mrbgems/mruby-compiler/core/parse.y" +#line 3901 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 10198 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10199 "mrbgems/mruby-compiler/core/y.tab.c" break; case 556: /* f_arg: f_arg ',' f_arg_item */ -#line 3903 "mrbgems/mruby-compiler/core/parse.y" +#line 3905 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 10206 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10207 "mrbgems/mruby-compiler/core/y.tab.c" break; case 557: /* f_opt_asgn: "local variable or method" '=' */ -#line 3909 "mrbgems/mruby-compiler/core/parse.y" +#line 3911 "mrbgems/mruby-compiler/core/parse.y" { local_add_f(p, (yyvsp[-1].id)); local_nest(p); (yyval.id) = (yyvsp[-1].id); } -#line 10216 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10217 "mrbgems/mruby-compiler/core/y.tab.c" break; case 558: /* f_opt: f_opt_asgn arg */ -#line 3917 "mrbgems/mruby-compiler/core/parse.y" +#line 3919 "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 10226 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10227 "mrbgems/mruby-compiler/core/y.tab.c" break; case 559: /* f_block_opt: f_opt_asgn primary_value */ -#line 3925 "mrbgems/mruby-compiler/core/parse.y" +#line 3927 "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 10236 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10237 "mrbgems/mruby-compiler/core/y.tab.c" break; case 560: /* f_block_optarg: f_block_opt */ -#line 3933 "mrbgems/mruby-compiler/core/parse.y" +#line 3935 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 10244 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10245 "mrbgems/mruby-compiler/core/y.tab.c" break; case 561: /* f_block_optarg: f_block_optarg ',' f_block_opt */ -#line 3937 "mrbgems/mruby-compiler/core/parse.y" +#line 3939 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 10252 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10253 "mrbgems/mruby-compiler/core/y.tab.c" break; case 562: /* f_optarg: f_opt */ -#line 3943 "mrbgems/mruby-compiler/core/parse.y" +#line 3945 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 10260 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10261 "mrbgems/mruby-compiler/core/y.tab.c" break; case 563: /* f_optarg: f_optarg ',' f_opt */ -#line 3947 "mrbgems/mruby-compiler/core/parse.y" +#line 3949 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 10268 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10269 "mrbgems/mruby-compiler/core/y.tab.c" break; case 566: /* f_rest_arg: restarg_mark "local variable or method" */ -#line 3957 "mrbgems/mruby-compiler/core/parse.y" +#line 3959 "mrbgems/mruby-compiler/core/parse.y" { local_add_f(p, (yyvsp[0].id)); (yyval.id) = (yyvsp[0].id); } -#line 10277 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10278 "mrbgems/mruby-compiler/core/y.tab.c" break; case 567: /* f_rest_arg: restarg_mark */ -#line 3962 "mrbgems/mruby-compiler/core/parse.y" +#line 3964 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(mul); local_add_f(p, (yyval.id)); } -#line 10286 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10287 "mrbgems/mruby-compiler/core/y.tab.c" break; case 570: /* f_block_arg: blkarg_mark "local variable or method" */ -#line 3973 "mrbgems/mruby-compiler/core/parse.y" +#line 3975 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = (yyvsp[0].id); } -#line 10294 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10295 "mrbgems/mruby-compiler/core/y.tab.c" break; case 571: /* f_block_arg: blkarg_mark */ -#line 3977 "mrbgems/mruby-compiler/core/parse.y" +#line 3979 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(and); } -#line 10302 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10303 "mrbgems/mruby-compiler/core/y.tab.c" break; case 572: /* opt_f_block_arg: ',' f_block_arg */ -#line 3983 "mrbgems/mruby-compiler/core/parse.y" +#line 3985 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = (yyvsp[0].id); } -#line 10310 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10311 "mrbgems/mruby-compiler/core/y.tab.c" break; case 573: /* opt_f_block_arg: none */ -#line 3987 "mrbgems/mruby-compiler/core/parse.y" +#line 3989 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = 0; } -#line 10318 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10319 "mrbgems/mruby-compiler/core/y.tab.c" break; case 574: /* singleton: var_ref */ -#line 3993 "mrbgems/mruby-compiler/core/parse.y" +#line 3995 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); if (!(yyval.nd)) (yyval.nd) = new_nil(p); } -#line 10327 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10328 "mrbgems/mruby-compiler/core/y.tab.c" break; case 575: /* $@33: %empty */ -#line 3997 "mrbgems/mruby-compiler/core/parse.y" +#line 3999 "mrbgems/mruby-compiler/core/parse.y" {p->lstate = EXPR_BEG;} -#line 10333 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10334 "mrbgems/mruby-compiler/core/y.tab.c" break; case 576: /* singleton: '(' $@33 expr rparen */ -#line 3998 "mrbgems/mruby-compiler/core/parse.y" +#line 4000 "mrbgems/mruby-compiler/core/parse.y" { if ((yyvsp[-1].nd) == 0) { yyerror(p, "can't define singleton method for ()."); @@ -10356,81 +10357,81 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } (yyval.nd) = (yyvsp[-1].nd); } -#line 10360 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10361 "mrbgems/mruby-compiler/core/y.tab.c" break; case 578: /* assoc_list: assocs trailer */ -#line 4024 "mrbgems/mruby-compiler/core/parse.y" +#line 4026 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 10368 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10369 "mrbgems/mruby-compiler/core/y.tab.c" break; case 579: /* assocs: assoc */ -#line 4030 "mrbgems/mruby-compiler/core/parse.y" +#line 4032 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 10377 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10378 "mrbgems/mruby-compiler/core/y.tab.c" break; case 580: /* assocs: assocs comma assoc */ -#line 4035 "mrbgems/mruby-compiler/core/parse.y" +#line 4037 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 10385 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10386 "mrbgems/mruby-compiler/core/y.tab.c" break; case 581: /* assoc: arg "=>" arg */ -#line 4041 "mrbgems/mruby-compiler/core/parse.y" +#line 4043 "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 10395 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10396 "mrbgems/mruby-compiler/core/y.tab.c" break; case 582: /* assoc: "local variable or method" "label" arg */ -#line 4047 "mrbgems/mruby-compiler/core/parse.y" +#line 4049 "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 10404 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10405 "mrbgems/mruby-compiler/core/y.tab.c" break; case 583: /* assoc: "local variable or method" "label" */ -#line 4052 "mrbgems/mruby-compiler/core/parse.y" +#line 4054 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = cons(new_sym(p, (yyvsp[-1].id)), label_reference(p, (yyvsp[-1].id))); } -#line 10412 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10413 "mrbgems/mruby-compiler/core/y.tab.c" break; case 584: /* assoc: "numbered parameter" "label" */ -#line 4056 "mrbgems/mruby-compiler/core/parse.y" +#line 4058 "mrbgems/mruby-compiler/core/parse.y" { mrb_sym sym = intern_numparam((yyvsp[-1].num)); (yyval.nd) = cons(new_sym(p, sym), label_reference(p, sym)); } -#line 10421 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10422 "mrbgems/mruby-compiler/core/y.tab.c" break; case 585: /* assoc: "numbered parameter" "label" arg */ -#line 4061 "mrbgems/mruby-compiler/core/parse.y" +#line 4063 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = cons(new_sym(p, intern_numparam((yyvsp[-2].num))), (yyvsp[0].nd)); } -#line 10430 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10431 "mrbgems/mruby-compiler/core/y.tab.c" break; case 586: /* assoc: string_fragment "label" arg */ -#line 4066 "mrbgems/mruby-compiler/core/parse.y" +#line 4068 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); if (typen((yyvsp[-2].nd)->car) == NODE_DSTR) { @@ -10440,75 +10441,75 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = cons(new_sym(p, new_strsym(p, (yyvsp[-2].nd))), (yyvsp[0].nd)); } } -#line 10444 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10445 "mrbgems/mruby-compiler/core/y.tab.c" break; case 587: /* assoc: "**" arg */ -#line 4076 "mrbgems/mruby-compiler/core/parse.y" +#line 4078 "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 10453 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10454 "mrbgems/mruby-compiler/core/y.tab.c" break; case 588: /* assoc: "**" */ -#line 4081 "mrbgems/mruby-compiler/core/parse.y" +#line 4083 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = cons(new_kw_rest_args(p, 0), new_lvar(p, intern_op(pow))); } -#line 10461 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10462 "mrbgems/mruby-compiler/core/y.tab.c" break; case 601: /* call_op: '.' */ -#line 4107 "mrbgems/mruby-compiler/core/parse.y" +#line 4109 "mrbgems/mruby-compiler/core/parse.y" { (yyval.num) = '.'; } -#line 10469 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10470 "mrbgems/mruby-compiler/core/y.tab.c" break; case 602: /* call_op: "&." */ -#line 4111 "mrbgems/mruby-compiler/core/parse.y" +#line 4113 "mrbgems/mruby-compiler/core/parse.y" { (yyval.num) = 0; } -#line 10477 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10478 "mrbgems/mruby-compiler/core/y.tab.c" break; case 604: /* call_op2: "::" */ -#line 4118 "mrbgems/mruby-compiler/core/parse.y" +#line 4120 "mrbgems/mruby-compiler/core/parse.y" { (yyval.num) = tCOLON2; } -#line 10485 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10486 "mrbgems/mruby-compiler/core/y.tab.c" break; case 613: /* term: ';' */ -#line 4139 "mrbgems/mruby-compiler/core/parse.y" +#line 4141 "mrbgems/mruby-compiler/core/parse.y" {yyerrok;} -#line 10491 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10492 "mrbgems/mruby-compiler/core/y.tab.c" break; case 615: /* nl: '\n' */ -#line 4144 "mrbgems/mruby-compiler/core/parse.y" +#line 4146 "mrbgems/mruby-compiler/core/parse.y" { p->lineno += (yyvsp[0].num); p->column = 0; } -#line 10500 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10501 "mrbgems/mruby-compiler/core/y.tab.c" break; case 619: /* none: %empty */ -#line 4156 "mrbgems/mruby-compiler/core/parse.y" +#line 4158 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = 0; } -#line 10508 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10509 "mrbgems/mruby-compiler/core/y.tab.c" break; -#line 10512 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10513 "mrbgems/mruby-compiler/core/y.tab.c" default: break; } @@ -10732,7 +10733,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); return yyresult; } -#line 4160 "mrbgems/mruby-compiler/core/parse.y" +#line 4162 "mrbgems/mruby-compiler/core/parse.y" #define pylval (*((YYSTYPE*)(p->ylval))) @@ -11402,7 +11403,8 @@ heredoc_remove_indent(parser_state *p, parser_heredoc_info *hinfo) newstr[newlen] = '\0'; pair->car = (node*)newstr; pair->cdr = (node*)newlen; - } else { + } + else { spaces = (size_t)nspaces->car; heredoc_count_indent(hinfo, str, len, spaces, &offset); pair->car = (node*)(str + offset); @@ -11477,7 +11479,8 @@ parse_string(parser_state *p) if (sizeof(s1)+sizeof(s2)+strlen(hinfo->term)+1 >= sizeof(buf)) { yyerror(p, "can't find heredoc delimiter anywhere before EOF"); - } else { + } + else { strcpy(buf, s1); strcat(buf, hinfo->term); strcat(buf, s2); @@ -13313,8 +13316,9 @@ mrbc_filename(mrb_state *mrb, mrbc_context *c, const char *s) { if (s) { size_t len = strlen(s); - char *p = (char*)mrb_malloc(mrb, len + 1); + char *p = (char*)mrb_malloc_simple(mrb, len + 1); + if (p == NULL) return NULL; memcpy(p, s, len + 1); if (c->filename) { mrb_free(mrb, c->filename); diff --git a/mruby/mrbgems/mruby-complex/src/complex.c b/mruby/mrbgems/mruby-complex/src/complex.c index ad88a67e..f0e5829d 100644 --- a/mruby/mrbgems/mruby-complex/src/complex.c +++ b/mruby/mrbgems/mruby-complex/src/complex.c @@ -284,12 +284,15 @@ add_pair(struct float_pair *s, struct float_pair const *a, { if (b->s == 0.0F) { *s = *a; - } else if (a->s == 0.0F) { + } + else if (a->s == 0.0F) { *s = *b; - } else if (a->x >= b->x) { + } + else if (a->x >= b->x) { s->s = a->s + F(ldexp)(b->s, b->x - a->x); s->x = a->x; - } else { + } + else { s->s = F(ldexp)(a->s, a->x - b->x) + b->s; s->x = b->x; } @@ -392,7 +395,7 @@ void mrb_mruby_complex_gem_init(mrb_state *mrb) struct RClass *comp; comp = mrb_define_class_id(mrb, MRB_SYM(Complex), mrb_class_get_id(mrb, MRB_SYM(Numeric))); - MRB_SET_INSTANCE_TT(comp, MRB_TT_COMPLEX); + MRB_SET_INSTANCE_TT(comp, MRB_TT_UNDEF); mrb_undef_class_method(mrb, comp, "new"); mrb_define_class_method(mrb, comp, "rectangular", complex_s_rect, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1)); diff --git a/mruby/mrbgems/mruby-data/src/data.c b/mruby/mrbgems/mruby-data/src/data.c index 91bc55a0..dd077619 100644 --- a/mruby/mrbgems/mruby-data/src/data.c +++ b/mruby/mrbgems/mruby-data/src/data.c @@ -94,15 +94,60 @@ mrb_data_members(mrb_state *mrb, mrb_value obj) } static mrb_value -mrb_data_ref(mrb_state *mrb, mrb_value obj) +data_ref(mrb_state *mrb, mrb_value obj, mrb_int i) { - mrb_int i = mrb_integer(mrb_proc_cfunc_env_get(mrb, 0)); + mrb_int len = RDATA_LEN(obj); mrb_value *ptr = RDATA_PTR(obj); - if (!ptr) return mrb_nil_value(); + if (!ptr || len <= i) + return mrb_nil_value(); return ptr[i]; } +static mrb_value +mrb_data_ref(mrb_state *mrb, mrb_value obj) +{ + mrb_int argc = mrb_get_argc(mrb); + if (argc != 0) { + mrb_argnum_error(mrb, argc, 0, 0); + } + mrb_int i = mrb_integer(mrb_proc_cfunc_env_get(mrb, 0)); + return data_ref(mrb, obj, i); +} + +static mrb_value +data_ref_0(mrb_state *mrb, mrb_value obj) +{ + return data_ref(mrb, obj, 0); +} + +static mrb_value +data_ref_1(mrb_state *mrb, mrb_value obj) +{ + return data_ref(mrb, obj, 1); +} + +static mrb_value +data_ref_2(mrb_state *mrb, mrb_value obj) +{ + return data_ref(mrb, obj, 2); +} + +static mrb_value +data_ref_3(mrb_state *mrb, mrb_value obj) +{ + return data_ref(mrb, obj, 3); +} + +#define DATA_DIRECT_REF_MAX 4 + +static mrb_func_t aref[DATA_DIRECT_REF_MAX] = { + data_ref_0, + data_ref_1, + data_ref_2, + data_ref_3, +}; + static void make_data_define_accessors(mrb_state *mrb, mrb_value members, struct RClass *c) { @@ -112,12 +157,18 @@ make_data_define_accessors(mrb_state *mrb, mrb_value members, struct RClass *c) for (mrb_int i=0; i0) mrb_str_cat_lit(mrb, ret, ", "); mrb_str_cat(mrb, ret, name, len); mrb_str_cat_lit(mrb, ret, "="); - mrb_str_cat_str(mrb, ret, mrb_inspect(mrb, vals[i])); + mrb_str_cat_str(mrb, ret, mrb_inspect(mrb, RARRAY_PTR(self)[i])); mrb_gc_arena_restore(mrb, ai); } mrb_str_cat_lit(mrb, ret, ">"); @@ -440,7 +492,7 @@ mrb_mruby_data_gem_init(mrb_state* mrb) { struct RClass *d; d = mrb_define_class(mrb, "Data", mrb->object_class); - MRB_SET_INSTANCE_TT(d, MRB_TT_STRUCT); + MRB_SET_INSTANCE_TT(d, MRB_TT_UNDEF); mrb_undef_class_method(mrb, d, "new"); mrb_define_class_method(mrb, d, "define", mrb_data_s_def, MRB_ARGS_ANY()); diff --git a/mruby/mrbgems/mruby-dir/README.md b/mruby/mrbgems/mruby-dir/README.md index 2be9d03c..7cd9fcc3 100644 --- a/mruby/mrbgems/mruby-dir/README.md +++ b/mruby/mrbgems/mruby-dir/README.md @@ -1,6 +1,6 @@ # mruby-dir -Dir class for mruby. Supported methods are: +Dir class for mruby. Supported methods are: `.chdir` `.delete` diff --git a/mruby/mrbgems/mruby-dir/mrbgem.rake b/mruby/mrbgems/mruby-dir/mrbgem.rake index 6951c49d..ed05e14d 100644 --- a/mruby/mrbgems/mruby-dir/mrbgem.rake +++ b/mruby/mrbgems/mruby-dir/mrbgem.rake @@ -1,4 +1,4 @@ MRuby::Gem::Specification.new('mruby-dir') do |spec| spec.license = 'MIT and MIT-like license' - spec.authors = [ 'Internet Initiative Japan Inc.', 'Kevlin Henney'] + spec.authors = ['Internet Initiative Japan Inc.', 'Kevlin Henney'] end diff --git a/mruby/mrbgems/mruby-dir/src/Win/dirent.c b/mruby/mrbgems/mruby-dir/src/Win/dirent.c index 1b43a992..086aaf97 100644 --- a/mruby/mrbgems/mruby-dir/src/Win/dirent.c +++ b/mruby/mrbgems/mruby-dir/src/Win/dirent.c @@ -39,38 +39,31 @@ DIR *opendir(const char *name) { DIR *dir = 0; - if(name && name[0]) - { + if (name && name[0]) { size_t base_length = strlen(name); const char *all = /* search pattern must end with suitable wildcard */ strchr("/\\", name[base_length - 1]) ? "*" : "/*"; - if((dir = (DIR *) malloc(sizeof *dir)) != 0 && - (dir->name = (char *) malloc(base_length + strlen(all) + 1)) != 0) - { + if ((dir = (DIR *) malloc(sizeof *dir)) != 0 && + (dir->name = (char *) malloc(base_length + strlen(all) + 1)) != 0) { strcat(strcpy(dir->name, name), all); - if((dir->handle = - (handle_type) _findfirst(dir->name, &dir->info)) != -1) - { + if ((dir->handle = (handle_type) _findfirst(dir->name, &dir->info)) != -1) { dir->result.d_name = 0; } - else /* rollback */ - { + else { /* rollback */ free(dir->name); free(dir); dir = 0; } } - else /* rollback */ - { + else { /* rollback */ free(dir); dir = 0; errno = ENOMEM; } } - else - { + else { errno = EINVAL; } @@ -81,9 +74,8 @@ int closedir(DIR *dir) { int result = -1; - if(dir) - { - if(dir->handle != -1) + if (dir) { + if (dir->handle != -1) { result = _findclose(dir->handle); } @@ -92,8 +84,7 @@ int closedir(DIR *dir) free(dir); } - if(result == -1) /* map all errors to EBADF */ - { + if (result == -1) { /* map all errors to EBADF */ errno = EBADF; } @@ -104,16 +95,13 @@ struct dirent *readdir(DIR *dir) { struct dirent *result = 0; - if(dir && dir->handle != -1) - { - if(!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1) - { + if (dir && dir->handle != -1) { + if (!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1) { result = &dir->result; result->d_name = dir->info.name; } } - else - { + else { errno = EBADF; } @@ -122,14 +110,12 @@ struct dirent *readdir(DIR *dir) void rewinddir(DIR *dir) { - if(dir && dir->handle != -1) - { + if (dir && dir->handle != -1) { _findclose(dir->handle); dir->handle = (handle_type) _findfirst(dir->name, &dir->info); dir->result.d_name = 0; } - else - { + else { errno = EBADF; } } diff --git a/mruby/mrbgems/mruby-dir/src/dir.c b/mruby/mrbgems/mruby-dir/src/dir.c index 455c17bd..52d100f2 100644 --- a/mruby/mrbgems/mruby-dir/src/dir.c +++ b/mruby/mrbgems/mruby-dir/src/dir.c @@ -34,6 +34,7 @@ #include #include #include +#include #define E_IO_ERROR mrb_exc_get_id(mrb, MRB_SYM(IOError)) @@ -128,10 +129,16 @@ static mrb_value mrb_dir_getwd(mrb_state *mrb, mrb_value klass) { mrb_value path; + mrb_int size = 64; - path = mrb_str_buf_new(mrb, MAXPATHLEN); - if (getcwd(RSTRING_PTR(path), MAXPATHLEN) == NULL) { - mrb_sys_fail(mrb, "getcwd(2)"); + path = mrb_str_buf_new(mrb, size); + while (getcwd(RSTRING_PTR(path), size) == NULL) { + int e = errno; + if (e != ERANGE) { + mrb_sys_fail(mrb, "getcwd(2)"); + } + size *= 2; + mrb_str_resize(mrb, path, size); } mrb_str_resize(mrb, path, strlen(RSTRING_PTR(path))); return path; @@ -166,7 +173,7 @@ mrb_dir_chdir(mrb_state *mrb, mrb_value klass) static mrb_value mrb_dir_chroot(mrb_state *mrb, mrb_value self) { -#if defined(_WIN32) || defined(_WIN64) || defined(__ANDROID__) +#if defined(_WIN32) || defined(_WIN64) || defined(__ANDROID__) || defined(__MSDOS__) mrb_raise(mrb, E_NOTIMP_ERROR, "chroot() unreliable on your system"); return mrb_fixnum_value(0); #else @@ -312,7 +319,7 @@ mrb_mruby_dir_gem_init(mrb_state *mrb) mrb_define_method(mrb, d, "seek", mrb_dir_seek, MRB_ARGS_REQ(1)); mrb_define_method(mrb, d, "tell", mrb_dir_tell, MRB_ARGS_NONE()); - mrb_define_class(mrb, "IOError", mrb->eStandardError_class); + mrb_define_class(mrb, "IOError", E_STANDARD_ERROR); } void diff --git a/mruby/mrbgems/mruby-enumerator/mrblib/enumerator.rb b/mruby/mrbgems/mruby-enumerator/mrblib/enumerator.rb index 65cddbda..4cc18efd 100644 --- a/mruby/mrbgems/mruby-enumerator/mrblib/enumerator.rb +++ b/mruby/mrbgems/mruby-enumerator/mrblib/enumerator.rb @@ -574,7 +574,7 @@ def << *args # # Examples of usage: # - # Enumerator.produce(1, &:succ) # => enumerator of 1, 2, 3, 4, .... + # Enumerator.produce(1, &:succ) # => enumerator of 1, 2, 3, 4, ... # # Enumerator.produce { rand(10) } # => infinite random number sequence # diff --git a/mruby/mrbgems/mruby-errno/src/errno.c b/mruby/mrbgems/mruby-errno/src/errno.c index 97132b4b..b2059f46 100644 --- a/mruby/mrbgems/mruby-errno/src/errno.c +++ b/mruby/mrbgems/mruby-errno/src/errno.c @@ -265,7 +265,8 @@ mrb_sce_errno(mrb_state *mrb, mrb_value 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 { + } + else { sym = MRB_SYM(errno); return mrb_attr_get(mrb, self, sym); } @@ -296,11 +297,9 @@ mrb_sce_sys_fail(mrb_state *mrb, mrb_value cls) void mrb_mruby_errno_gem_init(mrb_state *mrb) { - struct RClass *e, *eno, *sce, *ste; - - ste = mrb->eStandardError_class; + struct RClass *e, *eno, *sce; - sce = mrb_define_class(mrb, "SystemCallError", ste); + sce = mrb_define_class(mrb, "SystemCallError", E_STANDARD_ERROR); 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)); diff --git a/mruby/mrbgems/mruby-eval/mrbgem.rake b/mruby/mrbgems/mruby-eval/mrbgem.rake index cb8835b3..d2986fd3 100644 --- a/mruby/mrbgems/mruby-eval/mrbgem.rake +++ b/mruby/mrbgems/mruby-eval/mrbgem.rake @@ -4,4 +4,7 @@ MRuby::Gem::Specification.new('mruby-eval') do |spec| spec.summary = 'standard Kernel#eval method' add_dependency 'mruby-compiler', :core => 'mruby-compiler' + add_dependency 'mruby-binding', :core => 'mruby-binding' + spec.add_test_dependency('mruby-metaprog', :core => 'mruby-metaprog') + spec.add_test_dependency('mruby-method', :core => 'mruby-method') end diff --git a/mruby/mrbgems/mruby-eval/src/eval.c b/mruby/mrbgems/mruby-eval/src/eval.c index ff65b0fa..5b843216 100644 --- a/mruby/mrbgems/mruby-eval/src/eval.c +++ b/mruby/mrbgems/mruby-eval/src/eval.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -9,6 +10,15 @@ #include #include +/* provided by mruby-binding */ +mrb_bool mrb_binding_p(mrb_state *mrb, mrb_value binding); +const struct RProc * mrb_binding_extract_proc(mrb_state *mrb, mrb_value binding); +struct REnv * mrb_binding_extract_env(mrb_state *mrb, mrb_value binding); + +/* provided by mruby-compiler */ +typedef mrb_bool mrb_parser_foreach_top_variable_func(mrb_state *mrb, mrb_sym sym, void *user); +void mrb_parser_foreach_top_variable(mrb_state *mrb, struct mrb_parser_state *p, mrb_parser_foreach_top_variable_func *func, void *user); + static struct RProc* create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value binding, const char *file, mrb_int line) { @@ -22,22 +32,16 @@ create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value bi struct mrb_context *c = mrb->c; if (!mrb_nil_p(binding)) { - mrb_value scope_obj; - if (!mrb_class_defined_id(mrb, MRB_SYM(Binding)) - || !mrb_obj_is_kind_of(mrb, binding, mrb_class_get_id(mrb, MRB_SYM(Binding)))) { + if (!mrb_binding_p(mrb, binding)) { mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %C (expected binding)", - mrb_obj_class(mrb, binding)); + mrb_obj_class(mrb, binding)); } - scope_obj = mrb_iv_get(mrb, binding, MRB_SYM(proc)); - mrb_check_type(mrb, scope_obj, MRB_TT_PROC); - scope = mrb_proc_ptr(scope_obj); + scope = mrb_binding_extract_proc(mrb, binding); if (MRB_PROC_CFUNC_P(scope)) { e = NULL; } else { - mrb_value env = mrb_iv_get(mrb, binding, MRB_SYM(env)); - mrb_check_type(mrb, env, MRB_TT_ENV); - e = (struct REnv *)mrb_obj_ptr(env); + e = mrb_binding_extract_env(mrb, binding); mrb_assert(e != NULL); } } @@ -146,6 +150,108 @@ exec_irep(mrb_state *mrb, mrb_value self, struct RProc *proc) return mrb_exec_irep(mrb, self, proc); } +static void +binding_eval_error_check(mrb_state *mrb, struct mrb_parser_state *p, const char *file) +{ + if (!p) { + mrb_raise(mrb, E_RUNTIME_ERROR, "Failed to create parser state (out of memory)"); + } + + if (0 < p->nerr) { + mrb_value str; + + if (file) { + str = mrb_format(mrb, "file %s line %d: %s", + file, + p->error_buffer[0].lineno, + p->error_buffer[0].message); + } + else { + str = mrb_format(mrb, "line %d: %s", + p->error_buffer[0].lineno, + p->error_buffer[0].message); + } + mrb_exc_raise(mrb, mrb_exc_new_str(mrb, E_SYNTAX_ERROR, str)); + } +} + +#define LV_BUFFERS 8 + +struct expand_lvspace { + mrb_irep *irep; + struct REnv *env; + int numvar; + mrb_sym syms[LV_BUFFERS]; +}; + +static mrb_bool +expand_lvspace(mrb_state *mrb, mrb_sym sym, void *user) +{ + struct expand_lvspace *p = (struct expand_lvspace*)user; + mrb_int symlen; + const char *symname = mrb_sym_name_len(mrb, sym, &symlen); + + if (symname && symlen > 0) { + if (symname[0] != '&' && symname[0] != '*') { + p->syms[p->numvar++] = sym; + if (p->numvar >= LV_BUFFERS) { + mrb_proc_merge_lvar(mrb, p->irep, p->env, p->numvar, p->syms, NULL); + p->numvar = 0; + } + } + } + + return TRUE; +} + +struct binding_eval_prepare_body { + mrb_value binding; + const char *file; + mrbc_context *mrbc; + struct mrb_parser_state *pstate; +}; + +static mrb_value +binding_eval_prepare_body(mrb_state *mrb, void *opaque) +{ + struct binding_eval_prepare_body *p = (struct binding_eval_prepare_body*)opaque; + + const struct RProc *proc = mrb_binding_extract_proc(mrb, p->binding); + mrb_assert(!MRB_PROC_CFUNC_P(proc)); + p->mrbc->upper = proc; + binding_eval_error_check(mrb, p->pstate, p->file); + + struct expand_lvspace args = { + (mrb_irep*)proc->body.irep, + mrb_binding_extract_env(mrb, p->binding), + 0, + { 0 } + }; + mrb_parser_foreach_top_variable(mrb, p->pstate, expand_lvspace, &args); + if (args.numvar > 0) { + mrb_proc_merge_lvar(mrb, args.irep, args.env, args.numvar, args.syms, NULL); + } + + return mrb_nil_value(); +} + +static void +binding_eval_prepare(mrb_state *mrb, mrb_value binding, const char *expr, mrb_int exprlen, const char *file) +{ + struct binding_eval_prepare_body d = { binding }; + + d.mrbc = mrbc_context_new(mrb); + d.file = mrbc_filename(mrb, d.mrbc, file ? file : "(eval)"); + d.mrbc->capture_errors = TRUE; + d.pstate = mrb_parse_nstring(mrb, expr, exprlen, d.mrbc); + + mrb_bool error; + mrb_value ret = mrb_protect_error(mrb, binding_eval_prepare_body, &d, &error); + if (d.pstate) mrb_parser_free(d.pstate); + if (d.mrbc) mrbc_context_free(mrb, d.mrbc); + if (error) mrb_exc_raise(mrb, ret); +} + static mrb_value f_eval(mrb_state *mrb, mrb_value self) { @@ -158,6 +264,9 @@ f_eval(mrb_state *mrb, mrb_value self) mrb_get_args(mrb, "s|ozi", &s, &len, &binding, &file, &line); + if (!mrb_nil_p(binding)) { + binding_eval_prepare(mrb, binding, s, len, file); + } proc = create_proc_from_string(mrb, s, len, binding, file, line); if (!mrb_nil_p(binding)) { self = mrb_iv_get(mrb, binding, MRB_SYM(recv)); @@ -214,6 +323,22 @@ f_class_eval(mrb_state *mrb, mrb_value self) } } +static mrb_value +mrb_binding_eval(mrb_state *mrb, mrb_value binding) +{ + mrb_callinfo *ci = mrb->c->ci; + int argc = ci->n; + mrb_value *argv = ci->stack + 1; + + if (argc < 15) { + argv[0] = mrb_ary_new_from_values(mrb, argc, argv); + argv[1] = argv[argc]; /* copy block */ + ci->n = 15; + } + mrb_ary_splice(mrb, argv[0], 1, 0, binding); /* insert binding as 2nd argument */ + return f_eval(mrb, binding); +} + void mrb_mruby_eval_gem_init(mrb_state* mrb) { @@ -221,6 +346,9 @@ mrb_mruby_eval_gem_init(mrb_state* mrb) mrb_define_method_id(mrb, mrb_class_get_id(mrb, MRB_SYM(BasicObject)), MRB_SYM(instance_eval), f_instance_eval, MRB_ARGS_OPT(3)|MRB_ARGS_BLOCK()); mrb_define_method_id(mrb, mrb_class_get_id(mrb, MRB_SYM(Module)), MRB_SYM(module_eval), f_class_eval, MRB_ARGS_OPT(3)|MRB_ARGS_BLOCK()); mrb_define_method_id(mrb, mrb_class_get_id(mrb, MRB_SYM(Module)), MRB_SYM(class_eval), f_class_eval, MRB_ARGS_OPT(3)|MRB_ARGS_BLOCK()); + + struct RClass *binding = mrb_class_get_id(mrb, MRB_SYM(Binding)); + mrb_define_method(mrb, binding, "eval", mrb_binding_eval, MRB_ARGS_ANY()); } void diff --git a/mruby/mrbgems/mruby-eval/test/binding.rb b/mruby/mrbgems/mruby-eval/test/binding.rb new file mode 100644 index 00000000..1266690e --- /dev/null +++ b/mruby/mrbgems/mruby-eval/test/binding.rb @@ -0,0 +1,64 @@ +assert("Binding#eval") do + b = nil + 1.times { x, y, z = 1, 2, 3; [x,y,z]; b = binding } + assert_equal([1, 2, 3], b.eval("[x, y, z]")) + here = self + assert_equal(here, b.eval("self")) +end + +assert("Binding#local_variables") do + block = Proc.new do |a| + b = 1 + binding + end + bind = block.call(0) + assert_equal [:a, :b, :bind, :block], bind.local_variables.sort + bind.eval("x = 2") + assert_equal [:a, :b, :bind, :block, :x], bind.local_variables.sort +end + +assert("Binding#local_variable_set") do + bind = binding + 1.times { + assert_equal(9, bind.local_variable_set(:x, 9)) + assert_equal(9, bind.eval("x")) + assert_equal([:bind, :x], bind.eval("local_variables.sort")) + } +end + +assert("Binding#local_variable_get") do + bind = binding + x = 1 + 1.times { + y = 2 + assert_equal(1, bind.local_variable_get(:x)) + x = 10 + assert_equal(10, bind.local_variable_get(:x)) + assert_raise(NameError) { bind.local_variable_get(:y) } + bind.eval("z = 3") + assert_equal(3, bind.local_variable_get(:z)) + bind.eval("y = 5") + assert_equal(5, bind.local_variable_get(:y)) + assert_equal(2, y) + } +end + +assert "Binding#eval with Binding.new via UnboundMethod" do + assert_raise(NoMethodError) { Class.instance_method(:new).bind_call(Binding) } +end + +assert "Binding#eval with Binding.new via Method" do + # The following test is OK if SIGSEGV does not occur + cx = Class.new(Binding) + cx.define_singleton_method(:allocate, &Object.method(:allocate)) + Class.instance_method(:new).bind_call(cx).eval("") + + assert_true true +end + +assert "access local variables into procs" do + bx = binding + block = bx.eval("a = 1; proc { a }") + bx.eval("a = 2") + assert_equal 2, block.call +end diff --git a/mruby/mrbgems/mruby-exit/src/mruby-exit.c b/mruby/mrbgems/mruby-exit/src/mruby-exit.c index 658d188e..24311f12 100644 --- a/mruby/mrbgems/mruby-exit/src/mruby-exit.c +++ b/mruby/mrbgems/mruby-exit/src/mruby-exit.c @@ -72,7 +72,7 @@ f_exit_bang(mrb_state *mrb, mrb_value self) void mrb_mruby_exit_gem_init(mrb_state* mrb) { - mrb_define_class_id(mrb, MRB_SYM(SystemExit), mrb->eException_class); + mrb_define_class_id(mrb, MRB_SYM(SystemExit), E_EXCEPTION); mrb_define_method_id(mrb, mrb->kernel_module, MRB_SYM(exit), f_exit, MRB_ARGS_OPT(1)); mrb_define_method_id(mrb, mrb->kernel_module, MRB_SYM_B(exit), f_exit_bang, MRB_ARGS_OPT(1)); } diff --git a/mruby/mrbgems/mruby-fiber/src/fiber.c b/mruby/mrbgems/mruby-fiber/src/fiber.c index 75ffa906..05baac96 100644 --- a/mruby/mrbgems/mruby-fiber/src/fiber.c +++ b/mruby/mrbgems/mruby-fiber/src/fiber.c @@ -93,7 +93,7 @@ fiber_init(mrb_state *mrb, mrb_value self) if (p->body.irep->nregs > slen) { slen += p->body.irep->nregs; } - c->stbase = (mrb_value *)mrb_malloc(mrb, slen*sizeof(mrb_value)); + c->stbase = (mrb_value*)mrb_malloc(mrb, slen*sizeof(mrb_value)); c->stend = c->stbase + slen; { @@ -110,7 +110,7 @@ fiber_init(mrb_state *mrb, mrb_value self) c->stbase[0] = mrb->c->ci->stack[0]; /* initialize callinfo stack */ - c->cibase = (mrb_callinfo *)mrb_calloc(mrb, FIBER_CI_INIT_SIZE, sizeof(mrb_callinfo)); + c->cibase = (mrb_callinfo*)mrb_calloc(mrb, FIBER_CI_INIT_SIZE, sizeof(mrb_callinfo)); c->ciend = c->cibase + FIBER_CI_INIT_SIZE; c->ci = c->cibase; @@ -257,7 +257,14 @@ fiber_switch(mrb_state *mrb, mrb_value self, mrb_int len, const mrb_value *a, mr } } c->cibase->n = (uint8_t)len; - value = c->stbase[0] = MRB_PROC_ENV(c->cibase->proc)->stack[0]; + struct REnv *env = MRB_PROC_ENV(c->cibase->proc); + if (env && env->stack) { + value = env->stack[0]; + } + else { + value = mrb_top_self(mrb); + } + c->stbase[0] = value; } else { value = fiber_result(mrb, a, len); @@ -300,13 +307,9 @@ fiber_resume(mrb_state *mrb, mrb_value self) { const mrb_value *a; mrb_int len; - mrb_bool vmexec = FALSE; mrb_get_args(mrb, "*!", &a, &len); - if (mrb->c->ci->cci > 0) { - vmexec = TRUE; - } - return fiber_switch(mrb, self, len, a, TRUE, vmexec); + return fiber_switch(mrb, self, len, a, TRUE, FALSE); } MRB_API mrb_value @@ -470,7 +473,7 @@ mrb_mruby_fiber_gem_init(mrb_state* mrb) mrb_define_class_method(mrb, c, "yield", fiber_yield, MRB_ARGS_ANY()); mrb_define_class_method(mrb, c, "current", fiber_current, MRB_ARGS_NONE()); - mrb_define_class(mrb, "FiberError", mrb->eStandardError_class); + mrb_define_class(mrb, "FiberError", E_STANDARD_ERROR); } void diff --git a/mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb b/mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb index 5a8b5377..11537093 100644 --- a/mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb +++ b/mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb @@ -113,16 +113,7 @@ def merge!(*others, &block) # def compact! - keys = self.keys - nk = keys.select{|k| - self[k] != nil - } - return nil if (keys.size == nk.size) - h = {} - nk.each {|k| - h[k] = self[k] - } - self.replace(h) + self.__compact end ## @@ -136,12 +127,8 @@ def compact! # h #=> { a: 1, b: false, c: nil } # def compact - h = {} - self.keys.select{|k| - self[k] != nil - }.each {|k| - h[k] = self[k] - } + h=self.dup + h.__compact h end diff --git a/mruby/mrbgems/mruby-hash-ext/test/hash.rb b/mruby/mrbgems/mruby-hash-ext/test/hash.rb index a705af65..60a2123e 100644 --- a/mruby/mrbgems/mruby-hash-ext/test/hash.rb +++ b/mruby/mrbgems/mruby-hash-ext/test/hash.rb @@ -89,8 +89,8 @@ assert('Hash#compact!') do h = { "cat" => "feline", "dog" => nil, "cow" => false } - h.compact! - assert_equal({ "cat" => "feline", "cow" => false }, h) + assert_equal({ "cat" => "feline", "cow" => false }, h.compact!) + assert_nil(h.compact!) end assert('Hash#fetch') do diff --git a/mruby/mrbgems/mruby-io/README.md b/mruby/mrbgems/mruby-io/README.md index 525785fa..21138ace 100644 --- a/mruby/mrbgems/mruby-io/README.md +++ b/mruby/mrbgems/mruby-io/README.md @@ -158,14 +158,14 @@ Add the line below to your build configuration. | File.writable? | | FileTest | | File.writable_real? | | FileTest | | File.zero? | o | FileTest | -| File#atime | | | +| File#atime | o | | | File#chmod | | | | File#chown | | | -| File#ctime | | | +| File#ctime | o | | | File#flock | o | | | File#lstat | | | -| File#mtime | | | -| File#path, File#to_path | o | | +| File#mtime | o | | +| File#path | o | | | File#size | | | | File#truncate | | | diff --git a/mruby/mrbgems/mruby-io/mrblib/file.rb b/mruby/mrbgems/mruby-io/mrblib/file.rb index 9398acef..719f4e62 100644 --- a/mruby/mrbgems/mruby-io/mrblib/file.rb +++ b/mruby/mrbgems/mruby-io/mrblib/file.rb @@ -11,11 +11,25 @@ def initialize(fd_or_path, mode = "r", perm = 0666) end end + def atime + t = self._atime + t && Time.at(t) + end + + def ctime + t = self._ctime + t && Time.at(t) + end + def mtime t = self._mtime t && Time.at(t) end + def inspect + "<#{self.class}:#{@path}>" + end + def self.join(*names) return "" if names.empty? @@ -199,8 +213,6 @@ def self.extname(filename) def self.path(filename) if filename.kind_of?(String) filename - elsif filename.respond_to?(:to_path) - filename.to_path else raise TypeError, "no implicit conversion of #{filename.class} into String" end diff --git a/mruby/mrbgems/mruby-io/src/file.c b/mruby/mrbgems/mruby-io/src/file.c index e0957ffa..2bfef303 100644 --- a/mruby/mrbgems/mruby-io/src/file.c +++ b/mruby/mrbgems/mruby-io/src/file.c @@ -38,7 +38,9 @@ #define GETCWD getcwd #define CHMOD(a, b) chmod(a,b) #include +#ifndef __DJGPP__ #include +#endif #include #include #endif @@ -105,7 +107,8 @@ mrb_file_s_umask(mrb_state *mrb, mrb_value klass) if (mrb_get_args(mrb, "|i", &mask) == 0) { omask = umask(0); umask(omask); - } else { + } + else { omask = umask(mask); } return mrb_fixnum_value(omask); @@ -179,7 +182,8 @@ mrb_file_dirname(mrb_state *mrb, mrb_value klass) ridx = strlen(buffer); if (ridx == 0) { strncpy(buffer, ".", 2); /* null terminated */ - } else if (ridx > 1) { + } + else if (ridx > 1) { ridx--; while (ridx > 0 && (buffer[ridx] == '/' || buffer[ridx] == '\\')) { buffer[ridx] = '\0'; /* remove last char */ @@ -275,6 +279,7 @@ mrb_file__getwd(mrb_state *mrb, mrb_value klass) mrb_value path; char buf[MAXPATHLEN], *utf8; + mrb->c->ci->mid = 0; if (GETCWD(buf, MAXPATHLEN) == NULL) { mrb_sys_fail(mrb, "getcwd(2)"); } @@ -344,6 +349,7 @@ mrb_file__gethome(mrb_state *mrb, mrb_value klass) char *home; mrb_value path; + mrb->c->ci->mid = 0; #ifndef _WIN32 mrb_value username; @@ -356,7 +362,8 @@ mrb_file__gethome(mrb_state *mrb, mrb_value klass) if (!mrb_file_is_absolute_path(home)) { mrb_raise(mrb, E_ARGUMENT_ERROR, "non-absolute home"); } - } else { + } + else { const char *cuser = RSTRING_CSTR(mrb, username); struct passwd *pwd = getpwnam(cuser); if (pwd == NULL) { @@ -381,7 +388,8 @@ mrb_file__gethome(mrb_state *mrb, mrb_value klass) if (!mrb_file_is_absolute_path(home)) { mrb_raise(mrb, E_ARGUMENT_ERROR, "non-absolute home"); } - } else { + } + else { return mrb_nil_value(); } home = mrb_locale_from_utf8(home, -1); @@ -391,14 +399,60 @@ mrb_file__gethome(mrb_state *mrb, mrb_value klass) #endif } +#define TIME_OVERFLOW_P(a) (sizeof(time_t) >= sizeof(mrb_int) && ((a) > MRB_INT_MAX || (a) < MRB_INT_MIN)) +#define TIME_T_UINT (~(time_t)0 > 0) +#if defined(MRB_USE_BITINT) +#define TIME_BIGTIME(mrb, a) \ + return (TIME_T_UINT ? mrb_bint_new_uint64((mrb), (uint64_t)(a)) \ + : mrb_bint_new_int64(mrb, (int64_t)(a))) +#elif !defined(MRB_NO_FLOAT) +#define TIME_BIGTIME(mrb,a) return mrb_float_value((mrb), (mrb_float)(a)) +#else +#define TIME_BIGTIME(mrb, a) mrb_raise(mrb, E_IO_ERROR, #a " overflow") +#endif + +static mrb_value +mrb_file_atime(mrb_state *mrb, mrb_value self) +{ + int fd = mrb_io_fileno(mrb, self); + mrb_stat st; + + mrb->c->ci->mid = 0; + if (mrb_fstat(fd, &st) == -1) + mrb_sys_fail(mrb, "atime"); + if (TIME_OVERFLOW_P(st.st_atime)) { + TIME_BIGTIME(mrb, st.st_atime); + } + return mrb_int_value(mrb, (mrb_int)st.st_atime); +} + +static mrb_value +mrb_file_ctime(mrb_state *mrb, mrb_value self) +{ + int fd = mrb_io_fileno(mrb, self); + mrb_stat st; + + mrb->c->ci->mid = 0; + if (mrb_fstat(fd, &st) == -1) + mrb_sys_fail(mrb, "ctime"); + if (TIME_OVERFLOW_P(st.st_ctime)) { + TIME_BIGTIME(mrb, st. st_ctime); + } + return mrb_int_value(mrb, (mrb_int)st.st_ctime); +} + static mrb_value mrb_file_mtime(mrb_state *mrb, mrb_value self) { int fd = mrb_io_fileno(mrb, self); mrb_stat st; + mrb->c->ci->mid = 0; if (mrb_fstat(fd, &st) == -1) - return mrb_false_value(); + mrb_sys_fail(mrb, "mtime"); + if (TIME_OVERFLOW_P(st.st_mtime)) { + TIME_BIGTIME(mrb, st. st_mtime); + } return mrb_int_value(mrb, (mrb_int)st.st_mtime); } @@ -567,10 +621,10 @@ mrb_file_s_readlink(mrb_state *mrb, mrb_value klass) { mrb_get_args(mrb, "z", &path); tmp = mrb_locale_from_utf8(path, -1); - buf = (char *)mrb_malloc(mrb, bufsize); + buf = (char*)mrb_malloc(mrb, bufsize); while ((rc = readlink(tmp, buf, bufsize)) == (ssize_t)bufsize && rc != -1) { bufsize *= 2; - buf = (char *)mrb_realloc(mrb, buf, bufsize); + buf = (char*)mrb_realloc(mrb, buf, bufsize); } mrb_locale_free(tmp); if (rc == -1) { @@ -610,6 +664,8 @@ mrb_init_file(mrb_state *mrb) mrb_define_class_method(mrb, file, "_gethome", mrb_file__gethome, MRB_ARGS_OPT(1)); mrb_define_method(mrb, file, "flock", mrb_file_flock, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, file, "_atime", mrb_file_atime, MRB_ARGS_NONE()); + mrb_define_method(mrb, file, "_ctime", mrb_file_ctime, MRB_ARGS_NONE()); mrb_define_method(mrb, file, "_mtime", mrb_file_mtime, MRB_ARGS_NONE()); mrb_define_method(mrb, file, "size", mrb_file_size, MRB_ARGS_NONE()); mrb_define_method(mrb, file, "truncate", mrb_file_truncate, MRB_ARGS_REQ(1)); diff --git a/mruby/mrbgems/mruby-io/src/file_test.c b/mruby/mrbgems/mruby-io/src/file_test.c index f1762369..1d7aa564 100644 --- a/mruby/mrbgems/mruby-io/src/file_test.c +++ b/mruby/mrbgems/mruby-io/src/file_test.c @@ -20,7 +20,9 @@ #include #include #include +#ifndef __DJGPP__ #include +#endif #include #include #endif @@ -38,7 +40,7 @@ mrb_stat0(mrb_state *mrb, mrb_value obj, struct stat *st, int do_lstat) { if (mrb_obj_is_kind_of(mrb, obj, mrb_class_get(mrb, "IO"))) { struct mrb_io *fptr; - fptr = (struct mrb_io *)mrb_data_get_ptr(mrb, obj, &mrb_io_type); + fptr = (struct mrb_io*)mrb_data_get_ptr(mrb, obj, &mrb_io_type); if (fptr && fptr->fd >= 0) { return fstat(fptr->fd, st); @@ -52,7 +54,8 @@ mrb_stat0(mrb_state *mrb, mrb_value obj, struct stat *st, int do_lstat) int ret; if (do_lstat) { ret = LSTAT(path, st); - } else { + } + else { ret = stat(path, st); } mrb_locale_free(path); diff --git a/mruby/mrbgems/mruby-io/src/io.c b/mruby/mrbgems/mruby-io/src/io.c index ebe19930..560acde6 100644 --- a/mruby/mrbgems/mruby-io/src/io.c +++ b/mruby/mrbgems/mruby-io/src/io.c @@ -46,7 +46,11 @@ #include typedef size_t fsize_t; typedef time_t ftime_t; +#ifdef __DJGPP__ + typedef long fsuseconds_t; +#else typedef suseconds_t fsuseconds_t; +#endif typedef mode_t fmode_t; typedef ssize_t fssize_t; #endif @@ -94,7 +98,7 @@ io_get_open_fptr(mrb_state *mrb, mrb_value io) # define MRB_NO_IO_POPEN 1 #endif -#ifndef MRB_NO_IO_POEPN +#ifndef MRB_NO_IO_POPEN static void io_set_process_status(mrb_state *mrb, pid_t pid, int status) { @@ -110,7 +114,8 @@ io_set_process_status(mrb_state *mrb, pid_t pid, int status) } if (c_status != NULL) { v = mrb_funcall_id(mrb, mrb_obj_value(c_status), MRB_SYM(new), 2, mrb_fixnum_value(pid), mrb_fixnum_value(status)); - } else { + } + else { v = mrb_fixnum_value(WEXITSTATUS(status)); } mrb_gv_set(mrb, mrb_intern_lit(mrb, "$?"), v); @@ -559,10 +564,12 @@ io_s_popen(mrb_state *mrb, mrb_value klass) fd = pr[0]; close(pw[0]); write_fd = pw[1]; - } else if (OPEN_RDONLY_P(flags)) { + } + else if (OPEN_RDONLY_P(flags)) { close(pr[1]); fd = pr[0]; - } else { + } + else { close(pw[0]); fd = pw[1]; } @@ -629,10 +636,16 @@ io_init_copy(mrb_state *mrb, mrb_value copy) mrb_free(mrb, fptr_copy); } fptr_copy = (struct mrb_io*)io_alloc(mrb); + fptr_copy->pid = fptr_orig->pid; + fptr_copy->readable = fptr_orig->readable; + fptr_copy->writable = fptr_orig->writable; + fptr_copy->sync = fptr_orig->sync; + fptr_copy->is_socket = fptr_orig->is_socket; + + io_buf_init(mrb, fptr_copy); DATA_TYPE(copy) = &mrb_io_type; DATA_PTR(copy) = fptr_copy; - io_buf_init(mrb, fptr_copy); fptr_copy->fd = symdup(mrb, fptr_orig->fd, &failed); if (failed) { @@ -649,12 +662,6 @@ io_init_copy(mrb_state *mrb, mrb_value copy) io_fd_cloexec(mrb, fptr_copy->fd2); } - fptr_copy->pid = fptr_orig->pid; - fptr_copy->readable = fptr_orig->readable; - fptr_copy->writable = fptr_orig->writable; - fptr_copy->sync = fptr_orig->sync; - fptr_copy->is_socket = fptr_orig->is_socket; - return copy; } @@ -685,10 +692,8 @@ check_file_descriptor(mrb_state *mrb, mrb_int fd) } #endif /* _WIN32 */ - if (fstat(fdi, &sb) != 0) { - goto badfd; - } - + if (fstat(fdi, &sb) == 0) return; + if (errno == EBADF) goto badfd; return; badfd: @@ -705,6 +710,9 @@ io_init(mrb_state *mrb, mrb_value io) mode = opt = mrb_nil_value(); + if (mrb_block_given_p(mrb)) { + mrb_warn(mrb, "File.new() does not take block; use File.open() instead"); + } mrb_get_args(mrb, "i|oH", &fd, &mode, &opt); switch (fd) { case 0: /* STDIN_FILENO */ @@ -1278,7 +1286,8 @@ io_s_select(mrb_state *mrb, mrb_value klass) if (mrb_nil_p(timeout)) { tp = NULL; - } else { + } + else { timerec = time2timeval(mrb, timeout); tp = &timerec; } @@ -1304,7 +1313,8 @@ io_s_select(mrb_state *mrb, mrb_value klass) timerec.tv_sec = timerec.tv_usec = 0; tp = &timerec; } - } else { + } + else { rp = NULL; } @@ -1324,7 +1334,8 @@ io_s_select(mrb_state *mrb, mrb_value klass) max = fptr->fd2; } } - } else { + } + else { wp = NULL; } @@ -1344,7 +1355,8 @@ io_s_select(mrb_state *mrb, mrb_value klass) max = fptr->fd2; } } - } else { + } + else { ep = NULL; } @@ -1392,7 +1404,8 @@ io_s_select(mrb_state *mrb, mrb_value klass) fptr = io_get_open_fptr(mrb, RARRAY_PTR(write)[i]); if (FD_ISSET(fptr->fd, wp)) { mrb_ary_push(mrb, list, RARRAY_PTR(write)[i]); - } else if (fptr->fd2 >= 0 && FD_ISSET(fptr->fd2, wp)) { + } + else if (fptr->fd2 >= 0 && FD_ISSET(fptr->fd2, wp)) { mrb_ary_push(mrb, list, RARRAY_PTR(write)[i]); } } @@ -1404,7 +1417,8 @@ io_s_select(mrb_state *mrb, mrb_value klass) fptr = io_get_open_fptr(mrb, RARRAY_PTR(except)[i]); if (FD_ISSET(fptr->fd, ep)) { mrb_ary_push(mrb, list, RARRAY_PTR(except)[i]); - } else if (fptr->fd2 >= 0 && FD_ISSET(fptr->fd2, ep)) { + } + else if (fptr->fd2 >= 0 && FD_ISSET(fptr->fd2, ep)) { mrb_ary_push(mrb, list, RARRAY_PTR(except)[i]); } } @@ -1713,7 +1727,7 @@ io_find_index(struct mrb_io *fptr, const char *rs, mrb_int rslen) mrb_assert(rslen > 0); const char c = rs[0]; - const mrb_int limit = buf->len - rslen; + const mrb_int limit = buf->len - rslen + 1; const char *p = buf->mem+buf->start; for (mrb_int i=0; i 0) { mrb_str_cat_cstr(mrb, fname, tmpdir); if (*(RSTRING_END(fname)-1) != '/') mrb_str_cat_lit(mrb, fname, "/"); - } else { + } + else { mrb_str_cat_lit(mrb, fname, "/tmp/"); } #endif @@ -142,7 +143,7 @@ mrb_io_test_io_setup(mrb_state *mrb, mrb_value self) sun0.sun_family = AF_UNIX; strncpy(sun0.sun_path, fnames[IDX_SOCKET], sizeof(sun0.sun_path)-1); sun0.sun_path[sizeof(sun0.sun_path)-1] = 0; - if (bind(fds[IDX_SOCKET], (struct sockaddr *)&sun0, sizeof(sun0)) == -1) { + if (bind(fds[IDX_SOCKET], (struct sockaddr*)&sun0, sizeof(sun0)) == -1) { mrb_raisef(mrb, E_RUNTIME_ERROR, "can't bind AF_UNIX socket to %s: %d", sun0.sun_path, errno); diff --git a/mruby/mrbgems/mruby-math/src/math.c b/mruby/mrbgems/mruby-math/src/math.c index 1f6f88e8..75f0a220 100644 --- a/mruby/mrbgems/mruby-math/src/math.c +++ b/mruby/mrbgems/mruby-math/src/math.c @@ -174,6 +174,8 @@ log2(double x) #endif +#define get_float_arg(mrb) mrb_as_float((mrb), mrb_get_arg1(mrb)) + /* TRIGONOMETRIC FUNCTIONS */ @@ -188,11 +190,7 @@ log2(double x) static mrb_value math_sin(mrb_state *mrb, mrb_value obj) { - mrb_float x; - - mrb_get_args(mrb, "f", &x); - x = sin(x); - + mrb_float x = sin(get_float_arg(mrb)); return mrb_float_value(mrb, x); } @@ -206,11 +204,7 @@ math_sin(mrb_state *mrb, mrb_value obj) static mrb_value math_cos(mrb_state *mrb, mrb_value obj) { - mrb_float x; - - mrb_get_args(mrb, "f", &x); - x = cos(x); - + mrb_float x = cos(get_float_arg(mrb)); return mrb_float_value(mrb, x); } @@ -223,11 +217,7 @@ math_cos(mrb_state *mrb, mrb_value obj) static mrb_value math_tan(mrb_state *mrb, mrb_value obj) { - mrb_float x; - - mrb_get_args(mrb, "f", &x); - x = tan(x); - + mrb_float x = tan(get_float_arg(mrb)); return mrb_float_value(mrb, x); } @@ -245,9 +235,8 @@ math_tan(mrb_state *mrb, mrb_value obj) static mrb_value math_asin(mrb_state *mrb, mrb_value obj) { - mrb_float x; + mrb_float x = get_float_arg(mrb); - mrb_get_args(mrb, "f", &x); if (x < -1.0 || x > 1.0) { domain_error(mrb, "asin"); } @@ -265,9 +254,8 @@ math_asin(mrb_state *mrb, mrb_value obj) static mrb_value math_acos(mrb_state *mrb, mrb_value obj) { - mrb_float x; + mrb_float x = get_float_arg(mrb); - mrb_get_args(mrb, "f", &x); if (x < -1.0 || x > 1.0) { domain_error(mrb, "acos"); } @@ -285,11 +273,7 @@ math_acos(mrb_state *mrb, mrb_value obj) static mrb_value math_atan(mrb_state *mrb, mrb_value obj) { - mrb_float x; - - mrb_get_args(mrb, "f", &x); - x = atan(x); - + mrb_float x = atan(get_float_arg(mrb)); return mrb_float_value(mrb, x); } @@ -336,11 +320,7 @@ math_atan2(mrb_state *mrb, mrb_value obj) static mrb_value math_sinh(mrb_state *mrb, mrb_value obj) { - mrb_float x; - - mrb_get_args(mrb, "f", &x); - x = sinh(x); - + mrb_float x = sinh(get_float_arg(mrb)); return mrb_float_value(mrb, x); } @@ -353,11 +333,7 @@ math_sinh(mrb_state *mrb, mrb_value obj) static mrb_value math_cosh(mrb_state *mrb, mrb_value obj) { - mrb_float x; - - mrb_get_args(mrb, "f", &x); - x = cosh(x); - + mrb_float x = cosh(get_float_arg(mrb)); return mrb_float_value(mrb, x); } @@ -371,11 +347,7 @@ math_cosh(mrb_state *mrb, mrb_value obj) static mrb_value math_tanh(mrb_state *mrb, mrb_value obj) { - mrb_float x; - - mrb_get_args(mrb, "f", &x); - x = tanh(x); - + mrb_float x = tanh(get_float_arg(mrb)); return mrb_float_value(mrb, x); } @@ -393,12 +365,7 @@ math_tanh(mrb_state *mrb, mrb_value obj) static mrb_value math_asinh(mrb_state *mrb, mrb_value obj) { - mrb_float x; - - mrb_get_args(mrb, "f", &x); - - x = asinh(x); - + mrb_float x = asinh(get_float_arg(mrb)); return mrb_float_value(mrb, x); } @@ -411,9 +378,8 @@ math_asinh(mrb_state *mrb, mrb_value obj) static mrb_value math_acosh(mrb_state *mrb, mrb_value obj) { - mrb_float x; + mrb_float x = get_float_arg(mrb); - mrb_get_args(mrb, "f", &x); if (x < 1.0) { domain_error(mrb, "acosh"); } @@ -431,9 +397,8 @@ math_acosh(mrb_state *mrb, mrb_value obj) static mrb_value math_atanh(mrb_state *mrb, mrb_value obj) { - mrb_float x; + mrb_float x = get_float_arg(mrb); - mrb_get_args(mrb, "f", &x); if (x < -1.0 || x > 1.0) { domain_error(mrb, "atanh"); } @@ -460,11 +425,7 @@ math_atanh(mrb_state *mrb, mrb_value obj) static mrb_value math_exp(mrb_state *mrb, mrb_value obj) { - mrb_float x; - - mrb_get_args(mrb, "f", &x); - x = exp(x); - + mrb_float x = exp(get_float_arg(mrb)); return mrb_float_value(mrb, x); } @@ -518,9 +479,8 @@ math_log(mrb_state *mrb, mrb_value obj) static mrb_value math_log2(mrb_state *mrb, mrb_value obj) { - mrb_float x; + mrb_float x = get_float_arg(mrb); - mrb_get_args(mrb, "f", &x); if (x < 0.0) { domain_error(mrb, "log2"); } @@ -543,9 +503,8 @@ math_log2(mrb_state *mrb, mrb_value obj) static mrb_value math_log10(mrb_state *mrb, mrb_value obj) { - mrb_float x; + mrb_float x = get_float_arg(mrb); - mrb_get_args(mrb, "f", &x); if (x < 0.0) { domain_error(mrb, "log10"); } @@ -564,9 +523,8 @@ math_log10(mrb_state *mrb, mrb_value obj) static mrb_value math_sqrt(mrb_state *mrb, mrb_value obj) { - mrb_float x; + mrb_float x = get_float_arg(mrb); - mrb_get_args(mrb, "f", &x); if (x < 0.0) { domain_error(mrb, "sqrt"); } @@ -610,11 +568,7 @@ math_sqrt(mrb_state *mrb, mrb_value obj) static mrb_value math_cbrt(mrb_state *mrb, mrb_value obj) { - mrb_float x; - - mrb_get_args(mrb, "f", &x); - x = cbrt(x); - + mrb_float x = cbrt(get_float_arg(mrb)); return mrb_float_value(mrb, x); } @@ -633,10 +587,9 @@ math_cbrt(mrb_state *mrb, mrb_value obj) static mrb_value math_frexp(mrb_state *mrb, mrb_value obj) { - mrb_float x; + mrb_float x = get_float_arg(mrb); int exp; - mrb_get_args(mrb, "f", &x); x = frexp(x, &exp); return mrb_assoc_new(mrb, mrb_float_value(mrb, x), mrb_fixnum_value(exp)); @@ -692,11 +645,7 @@ math_hypot(mrb_state *mrb, mrb_value obj) static mrb_value math_erf(mrb_state *mrb, mrb_value obj) { - mrb_float x; - - mrb_get_args(mrb, "f", &x); - x = erf(x); - + mrb_float x = erf(get_float_arg(mrb)); return mrb_float_value(mrb, x); } @@ -710,11 +659,7 @@ math_erf(mrb_state *mrb, mrb_value obj) static mrb_value math_erfc(mrb_state *mrb, mrb_value obj) { - mrb_float x; - - mrb_get_args(mrb, "f", &x); - x = erfc(x); - + mrb_float x = erfc(get_float_arg(mrb)); return mrb_float_value(mrb, x); } @@ -725,7 +670,7 @@ mrb_mruby_math_gem_init(mrb_state* mrb) struct RClass *mrb_math; mrb_math = mrb_define_module(mrb, "Math"); - mrb_define_class_under_id(mrb, mrb_math, MRB_SYM(DomainError), mrb->eStandardError_class); + mrb_define_class_under_id(mrb, mrb_math, MRB_SYM(DomainError), E_STANDARD_ERROR); #ifdef M_PI mrb_define_const_id(mrb, mrb_math, MRB_SYM(PI), mrb_float_value(mrb, M_PI)); diff --git a/mruby/mrbgems/mruby-metaprog/src/metaprog.c b/mruby/mrbgems/mruby-metaprog/src/metaprog.c index 67da9cd9..3b93574c 100644 --- a/mruby/mrbgems/mruby-metaprog/src/metaprog.c +++ b/mruby/mrbgems/mruby-metaprog/src/metaprog.c @@ -22,8 +22,6 @@ typedef enum { NOEX_RESPONDS = 0x80 } mrb_method_flag_t; -mrb_value mrb_proc_local_variables(mrb_state *mrb, const struct RProc *proc); - static mrb_value mrb_f_nil(mrb_state *mrb, mrb_value cv) { @@ -296,7 +294,6 @@ mrb_obj_public_methods(mrb_state *mrb, mrb_value self) static mrb_value mrb_obj_singleton_methods(mrb_state *mrb, mrb_bool recur, mrb_value obj) { - khint_t i; mrb_value ary; struct RClass *klass; khash_t(st) *set = kh_init(st, mrb); @@ -316,7 +313,7 @@ mrb_obj_singleton_methods(mrb_state *mrb, mrb_bool recur, mrb_value obj) } ary = mrb_ary_new(mrb); - for (i=0;ibody.func != other_rproc->body.func) - return mrb_false_value(); + if (mrb_nil_p(orig_proc) && mrb_nil_p(other_proc) && + mrb_symbol(IV_GET(self, MRB_SYM(_name))) == mrb_symbol(IV_GET(other, MRB_SYM(_name)))) { + return mrb_true_value(); } - else { - if (MRB_PROC_CFUNC_P(other_rproc)) - return mrb_false_value(); - if (orig_rproc->body.irep != other_rproc->body.irep) - return mrb_false_value(); + if (mrb_nil_p(orig_proc) || mrb_nil_p(other_proc)) { + return mrb_false_value(); } - - return mrb_true_value(); + return mrb_bool_value(mrb_proc_eql(mrb, orig_proc, other_proc)); } #undef IV_GET @@ -429,8 +420,8 @@ method_to_s(mrb_state *mrb, mrb_value self) return str; } -static void -mrb_search_method_owner(mrb_state *mrb, struct RClass *c, mrb_value obj, mrb_sym name, struct RClass **owner, struct RProc **proc, mrb_bool unbound) +static mrb_bool +search_method_owner(mrb_state *mrb, struct RClass *c, mrb_value obj, mrb_sym name, struct RClass **owner, struct RProc **proc, mrb_bool unbound) { mrb_value ret; @@ -438,14 +429,14 @@ mrb_search_method_owner(mrb_state *mrb, struct RClass *c, mrb_value obj, mrb_sym *proc = method_search_vm(mrb, owner, name); if (!*proc) { if (unbound) { - goto name_error; + return FALSE; } if (!mrb_respond_to(mrb, obj, MRB_SYM_Q(respond_to_missing))) { - goto name_error; + return FALSE; } ret = mrb_funcall_id(mrb, obj, MRB_SYM_Q(respond_to_missing), 2, mrb_symbol_value(name), mrb_true_value()); if (!mrb_test(ret)) { - goto name_error; + return FALSE; } *owner = c; } @@ -453,54 +444,74 @@ mrb_search_method_owner(mrb_state *mrb, struct RClass *c, mrb_value obj, mrb_sym while ((*owner)->tt == MRB_TT_ICLASS) *owner = (*owner)->c; - return; + return TRUE; +} -name_error: - mrb_raisef(mrb, E_NAME_ERROR, "undefined method '%n' for class '%C'", name, c); +static mrb_noreturn void +singleton_method_error(mrb_state *mrb, mrb_sym name, mrb_value obj) +{ + mrb_raisef(mrb, E_NAME_ERROR, "undefined singleton method '%n' for '%!v'", name, obj); } static mrb_value -mrb_kernel_method(mrb_state *mrb, mrb_value self) +method_alloc(mrb_state *mrb, struct RClass *c, mrb_value obj, mrb_sym name, mrb_bool unbound, mrb_bool singleton) { struct RClass *owner; struct RProc *proc; struct RObject *me; - mrb_sym name; - mrb_get_args(mrb, "n", &name); - - mrb_search_method_owner(mrb, mrb_class(mrb, self), self, name, &owner, &proc, FALSE); - - me = method_object_alloc(mrb, mrb_class_get_id(mrb, MRB_SYM(Method))); + if (!search_method_owner(mrb, c, obj, name, &owner, &proc, unbound)) { + if (singleton) { + singleton_method_error(mrb, name, obj); + } + else { + mrb_raisef(mrb, E_NAME_ERROR, "undefined method '%n' for class '%C'", name, c); + } + } + if (singleton && owner != c) { + singleton_method_error(mrb, name, obj); + } + me = method_object_alloc(mrb, mrb_class_get_id(mrb, unbound ? MRB_SYM(UnboundMethod) : MRB_SYM(Method))); mrb_obj_iv_set(mrb, me, MRB_SYM(_owner), mrb_obj_value(owner)); - mrb_obj_iv_set(mrb, me, MRB_SYM(_recv), self); + mrb_obj_iv_set(mrb, me, MRB_SYM(_recv), unbound ? mrb_nil_value() : obj); mrb_obj_iv_set(mrb, me, MRB_SYM(_name), mrb_symbol_value(name)); mrb_obj_iv_set(mrb, me, MRB_SYM(_proc), proc ? mrb_obj_value(proc) : mrb_nil_value()); - mrb_obj_iv_set(mrb, me, MRB_SYM(_klass), mrb_obj_value(mrb_class(mrb, self))); + mrb_obj_iv_set(mrb, me, MRB_SYM(_klass), mrb_obj_value(c)); return mrb_obj_value(me); } static mrb_value -mrb_module_instance_method(mrb_state *mrb, mrb_value self) +mrb_kernel_method(mrb_state *mrb, mrb_value self) { - struct RClass *owner; - struct RProc *proc; - struct RObject *ume; mrb_sym name; mrb_get_args(mrb, "n", &name); + return method_alloc(mrb, mrb_class(mrb, self), self, name, FALSE, FALSE); +} - mrb_search_method_owner(mrb, mrb_class_ptr(self), self, name, &owner, &proc, TRUE); +static mrb_value +mrb_kernel_singleton_method(mrb_state *mrb, mrb_value self) +{ + struct RClass *c; + mrb_sym name; - ume = method_object_alloc(mrb, mrb_class_get_id(mrb, MRB_SYM(UnboundMethod))); - mrb_obj_iv_set(mrb, ume, MRB_SYM(_owner), mrb_obj_value(owner)); - mrb_obj_iv_set(mrb, ume, MRB_SYM(_recv), mrb_nil_value()); - mrb_obj_iv_set(mrb, ume, MRB_SYM(_name), mrb_symbol_value(name)); - mrb_obj_iv_set(mrb, ume, MRB_SYM(_proc), proc ? mrb_obj_value(proc) : mrb_nil_value()); - mrb_obj_iv_set(mrb, ume, MRB_SYM(_klass), self); + mrb_get_args(mrb, "n", &name); - return mrb_obj_value(ume); + c = mrb_class(mrb, self); + if (c->tt != MRB_TT_SCLASS) { + singleton_method_error(mrb, name, self); + } + return method_alloc(mrb, c, self, name, FALSE, TRUE); +} + +static mrb_value +mrb_module_instance_method(mrb_state *mrb, mrb_value self) +{ + mrb_sym name; + + mrb_get_args(mrb, "n", &name); + return method_alloc(mrb, mrb_class_ptr(self), self, name, TRUE, FALSE); } static mrb_value @@ -527,6 +538,7 @@ mrb_mruby_method_gem_init(mrb_state* mrb) struct RClass *unbound_method = mrb_define_class_id(mrb, MRB_SYM(UnboundMethod), mrb->object_class); struct RClass *method = mrb_define_class_id(mrb, MRB_SYM(Method), mrb->object_class); + MRB_SET_INSTANCE_TT(unbound_method, MRB_TT_UNDEF); mrb_undef_class_method(mrb, unbound_method, "new"); mrb_define_method(mrb, unbound_method, "bind", unbound_method_bind, MRB_ARGS_REQ(1)); mrb_define_method(mrb, unbound_method, "super_method", method_super_method, MRB_ARGS_NONE()); @@ -541,6 +553,7 @@ mrb_mruby_method_gem_init(mrb_state* mrb) mrb_define_method(mrb, unbound_method, "owner", method_owner, MRB_ARGS_NONE()); mrb_define_method(mrb, unbound_method, "name", method_name, MRB_ARGS_NONE()); + MRB_SET_INSTANCE_TT(method, MRB_TT_UNDEF); mrb_undef_class_method(mrb, method, "new"); mrb_define_method(mrb, method, "==", method_eql, MRB_ARGS_REQ(1)); mrb_define_method(mrb, method, "eql?", method_eql, MRB_ARGS_REQ(1)); @@ -558,6 +571,7 @@ mrb_mruby_method_gem_init(mrb_state* mrb) mrb_define_method(mrb, method, "name", method_name, MRB_ARGS_NONE()); mrb_define_method(mrb, mrb->kernel_module, "method", mrb_kernel_method, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, mrb->kernel_module, "singleton_method", mrb_kernel_singleton_method, MRB_ARGS_REQ(1)); mrb_define_method(mrb, mrb->module_class, "instance_method", mrb_module_instance_method, MRB_ARGS_REQ(1)); } diff --git a/mruby/mrbgems/mruby-numeric-ext/src/numeric_ext.c b/mruby/mrbgems/mruby-numeric-ext/src/numeric_ext.c index 5fa4e5fb..4833f05f 100644 --- a/mruby/mrbgems/mruby-numeric-ext/src/numeric_ext.c +++ b/mruby/mrbgems/mruby-numeric-ext/src/numeric_ext.c @@ -59,29 +59,36 @@ mrb_value mrb_int_pow(mrb_state *mrb, mrb_value x, mrb_value y); static mrb_value int_powm(mrb_state *mrb, mrb_value x) { - mrb_value m; - mrb_int e, exp, mod, result = 1; + mrb_value m, e; + mrb_int exp, mod, result = 1; if (mrb_get_argc(mrb) == 1) { return mrb_int_pow(mrb, x, mrb_get_arg1(mrb)); } - mrb_get_args(mrb, "io", &e, &m); - if (e < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "int.pow(n,m): n must be positive"); + mrb_get_args(mrb, "oo", &e, &m); + if (!mrb_integer_p(e) +#ifdef MRB_USE_BIGINT + && !mrb_bigint_p(e) +#endif + ) { + mrb_raise(mrb, E_TYPE_ERROR, "int.pow(n,m): 2nd argument not allowed unless 1st argument is an integer"); + } #ifdef MRB_USE_BIGINT if (mrb_bigint_p(x)) { return mrb_bint_powm(mrb, x, e, m); } - if (mrb_bigint_p(m)) { + if (mrb_bigint_p(e) || mrb_bigint_p(m)) { return mrb_bint_powm(mrb, mrb_bint_new_int(mrb, mrb_integer(x)), e, m); } #endif + exp = mrb_integer(e); + if (exp < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "int.pow(n,m): n must be positive"); 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 when 2nd argument specified"); if (mod == 0) mrb_int_zerodiv(mrb); if (mod == 1) return mrb_fixnum_value(0); mrb_int base = mrb_integer(x); - exp = e; for (;;) { mrb_int tmp; if (exp & 1) { @@ -211,30 +218,30 @@ flo_remainder(mrb_state *mrb, mrb_value self) void mrb_mruby_numeric_ext_gem_init(mrb_state* mrb) { - struct RClass *i = mrb->integer_class; + struct RClass *ic = mrb->integer_class; - mrb_define_alias(mrb, i, "modulo", "%"); - mrb_define_method(mrb, i, "remainder", int_remainder, MRB_ARGS_REQ(1)); + mrb_define_alias(mrb, ic, "modulo", "%"); + mrb_define_method(mrb, ic, "remainder", int_remainder, MRB_ARGS_REQ(1)); - mrb_define_method_id(mrb, i, MRB_SYM(pow), int_powm, MRB_ARGS_ARG(1,1)); - mrb_define_method_id(mrb, i, MRB_SYM(digits), int_digits, MRB_ARGS_OPT(1)); + mrb_define_method_id(mrb, ic, MRB_SYM(pow), int_powm, MRB_ARGS_ARG(1,1)); + mrb_define_method_id(mrb, ic, MRB_SYM(digits), int_digits, MRB_ARGS_OPT(1)); #ifndef MRB_NO_FLOAT - struct RClass *f = mrb->float_class; - - mrb_define_alias(mrb, f, "modulo", "%"); - mrb_define_method(mrb, f, "remainder", flo_remainder, MRB_ARGS_REQ(1)); - - mrb_define_const_id(mrb, mrb->float_class, MRB_SYM(RADIX), mrb_fixnum_value(MRB_FLT_RADIX)); - mrb_define_const_id(mrb, mrb->float_class, MRB_SYM(MANT_DIG), mrb_fixnum_value(MRB_FLT_MANT_DIG)); - mrb_define_const_id(mrb, mrb->float_class, MRB_SYM(EPSILON), mrb_float_value(mrb, MRB_FLT_EPSILON)); - mrb_define_const_id(mrb, mrb->float_class, MRB_SYM(DIG), mrb_fixnum_value(MRB_FLT_DIG)); - mrb_define_const_id(mrb, mrb->float_class, MRB_SYM(MIN_EXP), mrb_fixnum_value(MRB_FLT_MIN_EXP)); - mrb_define_const_id(mrb, mrb->float_class, MRB_SYM(MIN), mrb_float_value(mrb, MRB_FLT_MIN)); - mrb_define_const_id(mrb, mrb->float_class, MRB_SYM(MIN_10_EXP), mrb_fixnum_value(MRB_FLT_MIN_10_EXP)); - mrb_define_const_id(mrb, mrb->float_class, MRB_SYM(MAX_EXP), mrb_fixnum_value(MRB_FLT_MAX_EXP)); - mrb_define_const_id(mrb, mrb->float_class, MRB_SYM(MAX), mrb_float_value(mrb, MRB_FLT_MAX)); - mrb_define_const_id(mrb, mrb->float_class, MRB_SYM(MAX_10_EXP), mrb_fixnum_value(MRB_FLT_MAX_10_EXP)); + struct RClass *fc = mrb->float_class; + + mrb_define_alias(mrb, fc, "modulo", "%"); + mrb_define_method(mrb, fc, "remainder", flo_remainder, MRB_ARGS_REQ(1)); + + mrb_define_const_id(mrb, fc, MRB_SYM(RADIX), mrb_fixnum_value(MRB_FLT_RADIX)); + mrb_define_const_id(mrb, fc, MRB_SYM(MANT_DIG), mrb_fixnum_value(MRB_FLT_MANT_DIG)); + mrb_define_const_id(mrb, fc, MRB_SYM(EPSILON), mrb_float_value(mrb, MRB_FLT_EPSILON)); + mrb_define_const_id(mrb, fc, MRB_SYM(DIG), mrb_fixnum_value(MRB_FLT_DIG)); + mrb_define_const_id(mrb, fc, MRB_SYM(MIN_EXP), mrb_fixnum_value(MRB_FLT_MIN_EXP)); + mrb_define_const_id(mrb, fc, MRB_SYM(MIN), mrb_float_value(mrb, MRB_FLT_MIN)); + mrb_define_const_id(mrb, fc, MRB_SYM(MIN_10_EXP), mrb_fixnum_value(MRB_FLT_MIN_10_EXP)); + mrb_define_const_id(mrb, fc, MRB_SYM(MAX_EXP), mrb_fixnum_value(MRB_FLT_MAX_EXP)); + mrb_define_const_id(mrb, fc, MRB_SYM(MAX), mrb_float_value(mrb, MRB_FLT_MAX)); + mrb_define_const_id(mrb, fc, MRB_SYM(MAX_10_EXP), mrb_fixnum_value(MRB_FLT_MAX_10_EXP)); #endif /* MRB_NO_FLOAT */ } diff --git a/mruby/mrbgems/mruby-object-ext/src/object.c b/mruby/mrbgems/mruby-object-ext/src/object.c index 69f1763c..f0b50bf1 100644 --- a/mruby/mrbgems/mruby-object-ext/src/object.c +++ b/mruby/mrbgems/mruby-object-ext/src/object.c @@ -70,7 +70,7 @@ nil_to_i(mrb_state *mrb, mrb_value obj) * */ static mrb_value -mrb_f_itself(mrb_state *mrb, mrb_value self) +f_itself(mrb_state *mrb, mrb_value self) { return self; } @@ -94,7 +94,7 @@ mrb_f_itself(mrb_state *mrb, mrb_value self) */ static mrb_value -mrb_obj_instance_exec(mrb_state *mrb, mrb_value self) +obj_instance_exec(mrb_state *mrb, mrb_value self) { const mrb_value *argv; mrb_int argc; @@ -122,9 +122,9 @@ mrb_mruby_object_ext_gem_init(mrb_state* mrb) mrb_define_method(mrb, n, "to_h", nil_to_h, MRB_ARGS_NONE()); mrb_define_method(mrb, n, "to_i", nil_to_i, MRB_ARGS_NONE()); - mrb_define_method(mrb, mrb->kernel_module, "itself", mrb_f_itself, MRB_ARGS_NONE()); + mrb_define_method(mrb, mrb->kernel_module, "itself", f_itself, MRB_ARGS_NONE()); - mrb_define_method(mrb, mrb_class_get_id(mrb, MRB_SYM(BasicObject)), "instance_exec", mrb_obj_instance_exec, MRB_ARGS_ANY() | MRB_ARGS_BLOCK()); + mrb_define_method(mrb, mrb_class_get_id(mrb, MRB_SYM(BasicObject)), "instance_exec", obj_instance_exec, MRB_ARGS_ANY() | MRB_ARGS_BLOCK()); } void diff --git a/mruby/mrbgems/mruby-os-memsize/src/memsize.c b/mruby/mrbgems/mruby-os-memsize/src/memsize.c index b95515cc..10f77bee 100644 --- a/mruby/mrbgems/mruby-os-memsize/src/memsize.c +++ b/mruby/mrbgems/mruby-os-memsize/src/memsize.c @@ -16,13 +16,24 @@ static size_t os_memsize_of_irep(mrb_state* state, const struct mrb_irep *irep) { size_t size; - int i; size = (irep->slen * sizeof(mrb_sym)) + - (irep->plen * sizeof(mrb_code)) + - (irep->ilen * sizeof(mrb_code)); + (irep->plen * sizeof(mrb_pool_value)) + + (irep->ilen * sizeof(mrb_code)) + + (irep->rlen * sizeof(struct mrb_irep*)); - for(i = 0; i < irep->rlen; i++) { + for (int i = 0; i < irep->plen; i++) { + const mrb_pool_value *p = &irep->pool[i]; + if ((p->tt & IREP_TT_NFLAG) == 0) { /* string pool value */ + size += (p->tt>>2); + } + else if (p->tt == IREP_TT_BIGINT) { /* bigint pool value */ + size += p->u.str[0]; + } + } + + for (int i = 0; i < irep->rlen; i++) { + size += sizeof(struct mrb_irep); /* size of irep structure */ size += os_memsize_of_irep(state, irep->reps[i]); } return size; @@ -72,7 +83,7 @@ os_memsize_of_object(mrb_state* mrb, mrb_value obj) case MRB_TT_MODULE: case MRB_TT_SCLASS: case MRB_TT_ICLASS: - size += mrb_gc_mark_mt_size(mrb, mrb_class_ptr(obj)) * sizeof(mrb_method_t); + size += mrb_class_mt_memsize(mrb, mrb_class_ptr(obj)); /* fall through */ case MRB_TT_EXCEPTION: case MRB_TT_OBJECT: { @@ -95,14 +106,16 @@ os_memsize_of_object(mrb_state* mrb, mrb_value obj) /* Arrays that do not fit within an RArray perform a heap allocation * storing an array of pointers to the original objects*/ size += mrb_objspace_page_slot_size(); - if(len > MRB_ARY_EMBED_LEN_MAX) size += sizeof(mrb_value *) * len; + if (len > MRB_ARY_EMBED_LEN_MAX) + size += sizeof(mrb_value*) * len; break; } case MRB_TT_PROC: { struct RProc* proc = mrb_proc_ptr(obj); size += mrb_objspace_page_slot_size(); size += MRB_ENV_LEN(proc->e.env) * sizeof(mrb_value); - if(!MRB_PROC_CFUNC_P(proc)) size += os_memsize_of_irep(mrb, proc->body.irep); + if (!MRB_PROC_CFUNC_P(proc)) + size += os_memsize_of_irep(mrb, proc->body.irep); break; } case MRB_TT_RANGE: @@ -112,7 +125,7 @@ os_memsize_of_object(mrb_state* mrb, mrb_value obj) #endif break; case MRB_TT_FIBER: { - struct RFiber* f = (struct RFiber *)mrb_ptr(obj); + struct RFiber* f = (struct RFiber*)mrb_ptr(obj); ptrdiff_t stack_size = f->cxt->stend - f->cxt->stbase; ptrdiff_t ci_size = f->cxt->ciend - f->cxt->cibase; @@ -192,9 +205,7 @@ static mrb_value os_memsize_of(mrb_state *mrb, mrb_value self) { size_t total; - mrb_value obj; - - mrb_get_args(mrb, "o", &obj); + mrb_value obj = mrb_get_arg1(mrb); total = os_memsize_of_object(mrb, obj); return mrb_fixnum_value((mrb_int)total); @@ -208,7 +219,7 @@ struct os_memsize_of_all_cb_data { static int os_memsize_of_all_cb(mrb_state *mrb, struct RBasic *obj, void *d) { - struct os_memsize_of_all_cb_data *data = (struct os_memsize_of_all_cb_data *)d; + struct os_memsize_of_all_cb_data *data = (struct os_memsize_of_all_cb_data*)d; switch (obj->tt) { case MRB_TT_FREE: case MRB_TT_ENV: case MRB_TT_BREAK: case MRB_TT_ICLASS: diff --git a/mruby/mrbgems/mruby-pack/README.md b/mruby/mrbgems/mruby-pack/README.md index 712cf8e1..10a53809 100644 --- a/mruby/mrbgems/mruby-pack/README.md +++ b/mruby/mrbgems/mruby-pack/README.md @@ -16,6 +16,8 @@ There is no dependency on other mrbgems. - A : arbitrary binary string (space padded, count is width) - a : arbitrary binary string (null padded, count is width) +- B : bit string (descending) +- b : bit string (ascending) - C : 8-bit unsigned (unsigned char) - c : 8-bit signed (signed char) - D, d: 64-bit float, native format @@ -28,6 +30,8 @@ There is no dependency on other mrbgems. - h : hex string (low nibble first) - I : unsigned integer, native endian (`unsigned int` in C) - i : signed integer, native endian (`int` in C) +- J : unsigned integer, native endian (`uintptr_t` in C) +- j : signed integer, native endian (`intptr_t` in C) - L : 32-bit unsigned, native endian (`uint32_t`) - l : 32-bit signed, native endian (`int32_t`) - m : base64 encoded string (see RFC 2045, count is width) diff --git a/mruby/mrbgems/mruby-pack/src/pack.c b/mruby/mrbgems/mruby-pack/src/pack.c index b5ecdc64..26c2890b 100644 --- a/mruby/mrbgems/mruby-pack/src/pack.c +++ b/mruby/mrbgems/mruby-pack/src/pack.c @@ -35,17 +35,17 @@ enum pack_dir { //PACK_DIR_VAX, PACK_DIR_BER, /* w */ PACK_DIR_UTF8, /* U */ - //PACK_DIR_BER, PACK_DIR_DOUBLE, /* E */ PACK_DIR_FLOAT, /* f */ PACK_DIR_STR, /* A */ PACK_DIR_HEX, /* h */ + PACK_DIR_BSTR, /* b */ PACK_DIR_BASE64, /* m */ PACK_DIR_QENC, /* M */ PACK_DIR_NUL, /* x */ PACK_DIR_BACK, /* X */ PACK_DIR_ABS, /* @ */ - PACK_DIR_INVALID + PACK_DIR_NONE, /* - */ }; enum pack_type { @@ -123,9 +123,9 @@ static int unpack_char(mrb_state *mrb, const void *src, int srclen, mrb_value ary, unsigned int flags) { if (flags & PACK_FLAG_SIGNED) - mrb_ary_push(mrb, ary, mrb_fixnum_value(*(signed char *)src)); + mrb_ary_push(mrb, ary, mrb_fixnum_value(*(signed char*)src)); else - mrb_ary_push(mrb, ary, mrb_fixnum_value(*(unsigned char *)src)); + mrb_ary_push(mrb, ary, mrb_fixnum_value(*(unsigned char*)src)); return 1; } @@ -139,7 +139,8 @@ pack_short(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned in if (flags & PACK_FLAG_LITTLEENDIAN) { RSTRING_PTR(str)[sidx+0] = n % 256; RSTRING_PTR(str)[sidx+1] = n / 256; - } else { + } + else { RSTRING_PTR(str)[sidx+0] = n / 256; RSTRING_PTR(str)[sidx+1] = n % 256; } @@ -153,7 +154,8 @@ unpack_short(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary if (flags & PACK_FLAG_LITTLEENDIAN) { n = src[1] * 256 + src[0]; - } else { + } + else { n = src[0] * 256 + src[1]; } if ((flags & PACK_FLAG_SIGNED) && (n >= 0x8000)) { @@ -175,7 +177,8 @@ pack_long(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int RSTRING_PTR(str)[sidx+1] = (char)(n >> 8); RSTRING_PTR(str)[sidx+2] = (char)(n >> 16); RSTRING_PTR(str)[sidx+3] = (char)(n >> 24); - } else { + } + else { RSTRING_PTR(str)[sidx+0] = (char)(n >> 24); RSTRING_PTR(str)[sidx+1] = (char)(n >> 16); RSTRING_PTR(str)[sidx+2] = (char)(n >> 8); @@ -231,7 +234,8 @@ unpack_long(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, ul += (uint32_t)src[2] *256*256; ul += (uint32_t)src[1] *256; ul += (uint32_t)src[0]; - } else { + } + else { ul = (uint32_t)src[0] * 256*256*256; ul += (uint32_t)src[1] *256*256; ul += (uint32_t)src[2] *256; @@ -239,7 +243,8 @@ unpack_long(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, } if (flags & PACK_FLAG_SIGNED) { n = (int32_t)ul; - } else { + } + else { #ifndef MRB_INT64 if (UINT_OVERFLOW_P(ul)) { u32tostr(msg, sizeof(msg), ul); @@ -268,7 +273,8 @@ pack_quad(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int RSTRING_PTR(str)[sidx+5] = (char)(n >> 40); RSTRING_PTR(str)[sidx+6] = (char)(n >> 48); RSTRING_PTR(str)[sidx+7] = (char)(n >> 56); - } else { + } + else { RSTRING_PTR(str)[sidx+0] = (char)(n >> 56); RSTRING_PTR(str)[sidx+1] = (char)(n >> 48); RSTRING_PTR(str)[sidx+2] = (char)(n >> 40); @@ -345,7 +351,8 @@ unpack_quad(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, if (flags & PACK_FLAG_LITTLEENDIAN) { pos = 7; step = -1; - } else { + } + else { pos = 0; step = 1; } @@ -363,7 +370,8 @@ unpack_quad(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, } #endif n = (mrb_int)sll; - } else { + } + else { if (UINT_OVERFLOW_P(ull)) { u64tostr(msg, sizeof(msg), ull); mrb_raisef(mrb, E_RANGE_ERROR, "cannot unpack to Integer: %s", msg); @@ -425,7 +433,7 @@ pack_double(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned i { int i; double d; - uint8_t *buffer = (uint8_t *)&d; + uint8_t *buffer = (uint8_t*)&d; str = str_len_ensure(mrb, str, sidx + 8); d = mrb_float(o); @@ -438,7 +446,8 @@ pack_double(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned i RSTRING_PTR(str)[sidx + i] = buffer[8 - i - 1]; } } - } else { + } + else { if (littleendian) { for (i = 0; i < 8; i++) { RSTRING_PTR(str)[sidx + i] = buffer[8 - i - 1]; @@ -457,7 +466,7 @@ unpack_double(mrb_state *mrb, const unsigned char * src, int srclen, mrb_value a { int i; double d; - uint8_t *buffer = (uint8_t *)&d; + uint8_t *buffer = (uint8_t*)&d; if (flags & PACK_FLAG_LITTLEENDIAN) { if (littleendian) { @@ -468,7 +477,8 @@ unpack_double(mrb_state *mrb, const unsigned char * src, int srclen, mrb_value a buffer[8 - i - 1] = src[i]; } } - } else { + } + else { if (littleendian) { for (i = 0; i < 8; i++) { buffer[8 - i - 1] = src[i]; @@ -488,7 +498,7 @@ pack_float(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned in { int i; float f; - uint8_t *buffer = (uint8_t *)&f; + uint8_t *buffer = (uint8_t*)&f; str = str_len_ensure(mrb, str, sidx + 4); f = (float)mrb_float(o); @@ -501,7 +511,8 @@ pack_float(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned in RSTRING_PTR(str)[sidx + i] = buffer[4 - i - 1]; } } - } else { + } + else { if (littleendian) { for (i = 0; i < 4; i++) { RSTRING_PTR(str)[sidx + i] = buffer[4 - i - 1]; @@ -520,7 +531,7 @@ unpack_float(mrb_state *mrb, const unsigned char * src, int srclen, mrb_value ar { int i; float f; - uint8_t *buffer = (uint8_t *)&f; + uint8_t *buffer = (uint8_t*)&f; if (flags & PACK_FLAG_LITTLEENDIAN) { if (littleendian) { @@ -531,7 +542,8 @@ unpack_float(mrb_state *mrb, const unsigned char * src, int srclen, mrb_value ar buffer[4 - i - 1] = src[i]; } } - } else { + } + else { if (littleendian) { for (i = 0; i < 4; i++) { buffer[4 - i - 1] = src[i]; @@ -660,7 +672,7 @@ unpack_utf8(mrb_state *mrb, const unsigned char * src, int srclen, mrb_value ary if (srclen == 0) { return 1; } - uv = utf8_to_uv(mrb, (const char *)src, &lenp); + uv = utf8_to_uv(mrb, (const char*)src, &lenp); mrb_ary_push(mrb, ary, mrb_fixnum_value((mrb_int)uv)); return (int)lenp; } @@ -681,13 +693,16 @@ pack_str(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, int count, if (count == 0) { return 0; - } else if (count == -1) { + } + else if (count == -1) { copylen = slen; padlen = (flags & PACK_FLAG_Z) ? 1 : 0; - } else if (count < slen) { + } + else if (count < slen) { copylen = count; padlen = 0; - } else { + } + else { copylen = slen; padlen = count - slen; } @@ -719,14 +734,14 @@ unpack_str(mrb_state *mrb, const void *src, int slen, mrb_value ary, int count, const char *cp, *sptr; int copylen; - sptr = (const char *)src; + sptr = (const char*)src; if (count != -1 && count < slen) { slen = count; } copylen = slen; if (slen >= 0 && flags & PACK_FLAG_Z) { /* "Z" */ - if ((cp = (const char *)memchr(sptr, '\0', slen)) != NULL) { + if ((cp = (const char*)memchr(sptr, '\0', slen)) != NULL) { copylen = (int)(cp - sptr); if (count == -1) { slen = copylen + 1; @@ -760,14 +775,16 @@ pack_hex(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, int count, if (flags & PACK_FLAG_LSB) { ashift = 0; bshift = 4; - } else { + } + else { ashift = 4; bshift = 0; } if (count == -1) { count = slen; - } else if (slen > count) { + } + else if (slen > count) { slen = count; } @@ -807,12 +824,13 @@ unpack_hex(mrb_state *mrb, const void *src, int slen, mrb_value ary, int count, if (flags & PACK_FLAG_LSB) { ashift = 0; bshift = 4; - } else { + } + else { ashift = 4; bshift = 0; } - sptr = (const char *)src; + sptr = (const char*)src; if (count == -1) count = slen * 2; @@ -842,6 +860,92 @@ unpack_hex(mrb_state *mrb, const void *src, int slen, mrb_value ary, int count, return (int)(sptr - sptr0); } +static int +pack_bstr(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, int count, unsigned int flags) +{ + const char *sptr = RSTRING_PTR(src); + int slen = (int)RSTRING_LEN(src); + + if (count == -1) { + count = slen; + } + else if (slen > count) { + slen = count; + } + + dst = str_len_ensure(mrb, dst, didx + count); + char *dptr = RSTRING_PTR(dst) + didx; + char *dptr0 = dptr; + + unsigned int byte = 0; + for (int i=0; i++ < slen; sptr++) { + if (flags & PACK_FLAG_LSB) { + if (*sptr & 1) + byte |= 128; + if (i & 7) + byte >>= 1; + else { + char c = (char)(byte&0xff); + *dptr++ = c; + byte = 0; + } + } + else { + byte |= *sptr & 1; + if (i & 7) + byte <<= 1; + else { + char c = (char)(byte&0xff); + *dptr++ = c; + byte = 0; + } + } + } + if (slen & 7) { + if (flags & PACK_FLAG_LSB) { + byte >>= 7 - (slen & 7); + } + else { + byte <<= 7 - (slen & 7); + } + char c = (char)(byte&0xff); + *dptr++ = c; + } + return (int)(dptr - dptr0); +} + +static int +unpack_bstr(mrb_state *mrb, const void *src, int slen, mrb_value ary, int count, unsigned int flags) +{ + CHECK_UNPACK_LEN(mrb, slen, ary); + + const char *sptr0 = (const char*)src; + const char *sptr = sptr0; + if (count == -1) + count = slen * 8; + + mrb_value dst = mrb_str_new(mrb, NULL, count); + char *dptr = RSTRING_PTR(dst); + const char *dptr0 = dptr; + int bits = 0; + + for (int i=0; i>= 1; + else bits = (unsigned char)*sptr++; + *dptr++ = (bits & 1) ? '1' : '0'; + } + else { + if (i & 7) bits <<= 1; + else bits = (unsigned char)*sptr++; + *dptr++ = (bits & 128) ? '1' : '0'; + } + } + dst = mrb_str_resize(mrb, dst, (mrb_int)(dptr - dptr0)); + mrb_ary_push(mrb, ary, dst); + return (int)(sptr - sptr0); +} + static int pack_base64(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, int count) { @@ -858,7 +962,8 @@ pack_base64(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, int coun if (count != 0 && count < 3) { /* -1, 1 or 2 */ count = 45; - } else if (count >= 3) { + } + else if (count >= 3) { count -= count % 3; } @@ -892,7 +997,8 @@ pack_base64(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, int coun *dstptr++ = '='; *dstptr++ = '='; column += 3; - } else if (srclen == 2) { + } + else if (srclen == 2) { l = (unsigned char)*srcptr++ << 16; l += (unsigned char)*srcptr++ << 8; *dstptr++ = base64chars[(l >> 18) & 0x3f]; @@ -921,7 +1027,7 @@ unpack_base64(mrb_state *mrb, const void *src, int slen, mrb_value ary) const char *sptr, *sptr0; char *dptr, *dptr0; - sptr0 = sptr = (const char *)src; + sptr0 = sptr = (const char*)src; dlen = slen / 4 * 3; /* an estimated value - may be shorter */ dst = mrb_str_new(mrb, NULL, dlen); @@ -950,11 +1056,13 @@ unpack_base64(mrb_state *mrb, const void *src, int slen, mrb_value ary) *dptr++ = (l >> 16) & 0xff; *dptr++ = (l >> 8) & 0xff; *dptr++ = l & 0xff; - } else if (padding == 1) { + } + else if (padding == 1) { *dptr++ = (l >> 16) & 0xff; *dptr++ = (l >> 8) & 0xff; break; - } else { + } + else { *dptr++ = (l >> 16) & 0xff; break; } @@ -1095,8 +1203,8 @@ has_tmpl(const struct tmpl *tmpl) return (tmpl->idx < RSTRING_LEN(tmpl->str)); } -static void -read_tmpl(mrb_state *mrb, struct tmpl *tmpl, enum pack_dir *dirp, enum pack_type *typep, int *sizep, int *countp, unsigned int *flagsp) +static enum pack_dir +read_tmpl(mrb_state *mrb, struct tmpl *tmpl, enum pack_type *typep, int *sizep, int *countp, unsigned int *flagsp) { mrb_int t, tlen; int ch, size = 0; @@ -1109,8 +1217,10 @@ read_tmpl(mrb_state *mrb, struct tmpl *tmpl, enum pack_dir *dirp, enum pack_type tptr = RSTRING_PTR(tmpl->str); tlen = RSTRING_LEN(tmpl->str); + restart: + if (tmpl->idx >= tlen) return PACK_DIR_NONE; t = tptr[tmpl->idx++]; -alias: + alias: switch (t) { case 'A': dir = PACK_DIR_STR; @@ -1179,6 +1289,16 @@ read_tmpl(mrb_state *mrb, struct tmpl *tmpl, enum pack_dir *dirp, enum pack_type type = PACK_TYPE_STRING; flags |= PACK_FLAG_COUNT2 | PACK_FLAG_LSB; break; + case 'B': + dir = PACK_DIR_BSTR; + type = PACK_TYPE_STRING; + flags |= PACK_FLAG_COUNT2; + break; + case 'b': + dir = PACK_DIR_BSTR; + type = PACK_TYPE_STRING; + flags |= PACK_FLAG_COUNT2 | PACK_FLAG_LSB; + break; case 'I': switch (sizeof(int)) { case 2: t = 'S'; goto alias; @@ -1197,6 +1317,22 @@ read_tmpl(mrb_state *mrb, struct tmpl *tmpl, enum pack_dir *dirp, enum pack_type mrb_raisef(mrb, E_RUNTIME_ERROR, "mruby-pack does not support sizeof(int) == %d", (int)sizeof(int)); } break; + case 'J': + switch (sizeof(intptr_t)) { + case 4: t = 'L'; goto alias; + case 8: t = 'Q'; goto alias; + default: + mrb_raisef(mrb, E_RUNTIME_ERROR, "mruby-pack does not support sizeof(uintptr_t) == %d", (int)sizeof(uintptr_t)); + } + break; + case 'j': + switch (sizeof(intptr_t)) { + case 4: t = 'l'; goto alias; + case 8: t = 'q'; goto alias; + default: + mrb_raisef(mrb, E_RUNTIME_ERROR, "mruby-pack does not support sizeof(intptr_t) == %d", (int)sizeof(intptr_t)); + } + break; case 'L': dir = PACK_DIR_LONG; type = PACK_TYPE_INTEGER; @@ -1290,14 +1426,22 @@ read_tmpl(mrb_state *mrb, struct tmpl *tmpl, enum pack_dir *dirp, enum pack_type type = PACK_TYPE_STRING; flags |= PACK_FLAG_WIDTH | PACK_FLAG_COUNT2 | PACK_FLAG_Z; break; + case '#': + while (++tmpl->idx < tlen && tptr[tmpl->idx] != '\n') + ; + goto restart; + case 'p': case 'P': case '%': mrb_raisef(mrb, E_ARGUMENT_ERROR, "%c is not supported", (char)t); break; default: - dir = PACK_DIR_INVALID; - type = PACK_TYPE_NONE; - break; + if (!ISSPACE((char)t)) { + char c = (char)t; + mrb_value s = mrb_str_new(mrb, &c, 1); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "unknown unpack directive %!v", s); + } + goto restart; } /* read suffix [0-9*_!<>] */ @@ -1312,20 +1456,24 @@ read_tmpl(mrb_state *mrb, struct tmpl *tmpl, enum pack_dir *dirp, enum pack_type count = (int)n; tmpl->idx = (int)(e - tptr); continue; - } else if (ch == '*') { + } + else if (ch == '*') { if (type == PACK_TYPE_NONE) count = 0; else count = -1; - } else if (ch == '_' || ch == '!' || ch == '<' || ch == '>') { + } + else if (ch == '_' || ch == '!' || ch == '<' || ch == '>') { if (strchr("sSiIlLqQ", (int)t) == NULL) { mrb_raisef(mrb, E_ARGUMENT_ERROR, "'%c' allowed only after types sSiIlLqQ", ch); } if (ch == '_' || ch == '!') { flags |= PACK_FLAG_s; - } else if (ch == '<') { + } + else if (ch == '<') { flags |= PACK_FLAG_LT; - } else if (ch == '>') { + } + else if (ch == '>') { flags |= PACK_FLAG_GT; } } @@ -1339,11 +1487,11 @@ read_tmpl(mrb_state *mrb, struct tmpl *tmpl, enum pack_dir *dirp, enum pack_type flags |= PACK_FLAG_LITTLEENDIAN; } - *dirp = dir; *typep = type; *sizep = size; *countp = count; *flagsp = flags; + return dir; } static mrb_value @@ -1364,11 +1512,10 @@ mrb_pack_pack(mrb_state *mrb, mrb_value ary) aidx = 0; ridx = 0; while (has_tmpl(&tmpl)) { - read_tmpl(mrb, &tmpl, &dir, &type, &size, &count, &flags); + dir = read_tmpl(mrb, &tmpl, &type, &size, &count, &flags); - if (dir == PACK_DIR_INVALID) - continue; - else if (dir == PACK_DIR_NUL) { + if (dir == PACK_DIR_NONE) break; + if (dir == PACK_DIR_NUL) { grow: if (ridx > INT_MAX - count) goto overflow; ridx += pack_nul(mrb, result, ridx, count); @@ -1395,7 +1542,7 @@ mrb_pack_pack(mrb_state *mrb, mrb_value ary) if (count == 0 && !(flags & PACK_FLAG_WIDTH)) break; - o = mrb_ary_ref(mrb, ary, aidx); + o = RARRAY_PTR(ary)[aidx]; if (type == PACK_TYPE_INTEGER) { o = mrb_ensure_int_type(mrb, o); } @@ -1437,6 +1584,9 @@ mrb_pack_pack(mrb_state *mrb, mrb_value ary) case PACK_DIR_HEX: ridx += pack_hex(mrb, o, result, ridx, count, flags); break; + case PACK_DIR_BSTR: + ridx += pack_bstr(mrb, o, result, ridx, count, flags); + break; case PACK_DIR_STR: ridx += pack_str(mrb, o, result, ridx, count, flags); break; @@ -1493,11 +1643,10 @@ pack_unpack(mrb_state *mrb, mrb_value str, int single) result = mrb_ary_new(mrb); while (has_tmpl(&tmpl)) { - read_tmpl(mrb, &tmpl, &dir, &type, &size, &count, &flags); + dir = read_tmpl(mrb, &tmpl, &type, &size, &count, &flags); - if (dir == PACK_DIR_INVALID) - continue; - else if (dir == PACK_DIR_NUL) { + if (dir == PACK_DIR_NONE) break; + if (dir == PACK_DIR_NUL) { check_x(mrb, srclen-srcidx, count, 'x'); srcidx += count; continue; @@ -1514,11 +1663,14 @@ pack_unpack(mrb_state *mrb, mrb_value str, int single) } /* PACK_FLAG_COUNT2 directions */ - sptr = (const unsigned char *)RSTRING_PTR(str) + srcidx; + sptr = (const unsigned char*)RSTRING_PTR(str) + srcidx; switch (dir) { case PACK_DIR_HEX: srcidx += unpack_hex(mrb, sptr, srclen - srcidx, result, count, flags); continue; + case PACK_DIR_BSTR: + srcidx += unpack_bstr(mrb, sptr, srclen - srcidx, result, count, flags); + continue; case PACK_DIR_STR: srcidx += unpack_str(mrb, sptr, srclen - srcidx, result, count, flags); continue; diff --git a/mruby/mrbgems/mruby-pack/test/pack.rb b/mruby/mrbgems/mruby-pack/test/pack.rb index 4dd7f4a9..6045f788 100644 --- a/mruby/mrbgems/mruby-pack/test/pack.rb +++ b/mruby/mrbgems/mruby-pack/test/pack.rb @@ -38,6 +38,16 @@ def assert_pack tmpl, packed, unpacked assert_equal ["あ"], "=E3=81=82=\n".unpack("M") end +# pack & unpack 'B'/'b' +assert('pack("B/b")') do + assert_pack "b*", "\xFF\x00", ["1111111100000000"] + assert_pack "b*", "\x01\x02", ["1000000001000000"] + assert_pack "b3", "\x01", ["100"] + + assert_pack "B*", "\xFF\x00", ["1111111100000000"] + assert_pack "B*", "\x01\x02", ["0000000100000010"] +end + # pack & unpack 'H' assert('pack("H")') do assert_pack "H*", "01", ["3031"] diff --git a/mruby/mrbgems/mruby-print/mrblib/print.rb b/mruby/mrbgems/mruby-print/mrblib/print.rb index a8a23ea9..9047f5e8 100644 --- a/mruby/mrbgems/mruby-print/mrblib/print.rb +++ b/mruby/mrbgems/mruby-print/mrblib/print.rb @@ -6,32 +6,20 @@ module Kernel ## # Print human readable object description # - # ISO 15.3.1.2.9 - # ISO 15.3.1.3.34 + # ISO 15.3.1.2.9 Kernel.p + # ISO 15.3.1.3.34 Kernel#p def p(*args) i = 0 len = args.size while i < len - __printstr__ args[i].inspect - __printstr__ "\n" + print args[i].inspect, "\n" i += 1 end args.__svalue end - # 15.3.1.2.10 - # 15.3.1.3.35 - def print(*args) - i = 0 - len = args.size - while i < len - __printstr__ args[i].to_s - i += 1 - end - end - - # 15.3.1.2.11 - # 15.3.1.3.39 + # ISO 15.3.1.2.11 Kernel.puts + # ISO 15.3.1.3.39 Kernel#puts def puts(*args) i = 0 len = args.size @@ -41,15 +29,15 @@ def puts(*args) puts(*s) else s = s.to_s - __printstr__ s - __printstr__ "\n" if (s[-1] != "\n") + print s + print "\n" if (s[-1] != "\n") end i += 1 end - __printstr__ "\n" if len == 0 + print "\n" if len == 0 end def printf(*args) - __printstr__(sprintf(*args)) + print(sprintf(*args)) end end diff --git a/mruby/mrbgems/mruby-print/src/print.c b/mruby/mrbgems/mruby-print/src/print.c index f6d6d46f..94cab36e 100644 --- a/mruby/mrbgems/mruby-print/src/print.c +++ b/mruby/mrbgems/mruby-print/src/print.c @@ -13,13 +13,13 @@ # define isatty(x) _isatty(x) # define fileno(x) _fileno(x) #endif +#else +# include #endif -static mrb_value -mrb_printstr(mrb_state *mrb, mrb_value self) +static void +printstr(mrb_state *mrb, mrb_value s) { - mrb_value s = mrb_get_arg1(mrb); - if (mrb_string_p(s)) { const char *p = RSTRING_PTR(s); mrb_int len = RSTRING_LEN(s); @@ -35,21 +35,33 @@ mrb_printstr(mrb_state *mrb, mrb_value self) utf16, (DWORD)wlen, &written, NULL); } mrb_free(mrb, utf16); + return; } - else #endif - { - fwrite(p, (size_t)len, 1, stdout); - } - fflush(stdout); + fwrite(p, (size_t)len, 1, stdout); + } +} + +// ISO 15.3.1.2.10 Kernel.print +// ISO 15.3.1.3.35 Kernel#print +static mrb_value +mrb_print(mrb_state *mrb, mrb_value self) +{ + mrb_int argc = mrb_get_argc(mrb); + const mrb_value *argv = mrb_get_argv(mrb); + + for (mrb_int i=0; ikernel_module, "__printstr__", mrb_printstr, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, mrb->kernel_module, "print", mrb_print, MRB_ARGS_ANY()); /* 15.3.1.3.35 */ } void diff --git a/mruby/mrbgems/mruby-proc-binding/mrbgem.rake b/mruby/mrbgems/mruby-proc-binding/mrbgem.rake index 4aa88297..53e6faae 100644 --- a/mruby/mrbgems/mruby-proc-binding/mrbgem.rake +++ b/mruby/mrbgems/mruby-proc-binding/mrbgem.rake @@ -3,8 +3,8 @@ MRuby::Gem::Specification.new('mruby-proc-binding') do |spec| spec.author = 'mruby developers' spec.summary = 'Proc#binding method' - spec.add_dependency('mruby-binding-core', :core => 'mruby-binding-core') + spec.add_dependency('mruby-binding', :core => 'mruby-binding') spec.add_dependency('mruby-proc-ext', :core => 'mruby-proc-ext') - spec.add_test_dependency('mruby-binding', :core => 'mruby-binding') + spec.add_test_dependency('mruby-eval', :core => 'mruby-eval') spec.add_test_dependency('mruby-compiler', :core => 'mruby-compiler') end diff --git a/mruby/mrbgems/mruby-proc-binding/src/proc-binding.c b/mruby/mrbgems/mruby-proc-binding/src/proc-binding.c index d176034d..f513dafd 100644 --- a/mruby/mrbgems/mruby-proc-binding/src/proc-binding.c +++ b/mruby/mrbgems/mruby-proc-binding/src/proc-binding.c @@ -6,14 +6,12 @@ /* provided by mruby-proc-ext */ mrb_value mrb_proc_source_location(mrb_state *mrb, struct RProc *p); -/* provided by mruby-binding-core */ -mrb_value mrb_binding_alloc(mrb_state *mrb); -struct RProc *mrb_binding_wrap_lvspace(mrb_state *mrb, const struct RProc *proc, struct REnv **envp); +/* provided by mruby-binding */ +mrb_value mrb_binding_new(mrb_state *mrb, const struct RProc *proc, mrb_value recv, struct REnv *env); static mrb_value mrb_proc_binding(mrb_state *mrb, mrb_value procval) { - mrb_value binding = mrb_binding_alloc(mrb); const struct RProc *proc = mrb_proc_ptr(procval); struct REnv *env; @@ -30,10 +28,7 @@ mrb_proc_binding(mrb_state *mrb, mrb_value procval) receiver = MRB_ENV_LEN(env) > 0 ? env->stack[0] : mrb_nil_value(); } - proc = mrb_binding_wrap_lvspace(mrb, proc, &env); - mrb_iv_set(mrb, binding, MRB_SYM(proc), mrb_obj_value((void *)proc)); - mrb_iv_set(mrb, binding, MRB_SYM(recv), receiver); - mrb_iv_set(mrb, binding, MRB_SYM(env), mrb_obj_value(env)); + mrb_value binding = mrb_binding_new(mrb, proc, receiver, env); mrb_iv_set(mrb, binding, MRB_SYM(source_location), mrb_proc_source_location(mrb, mrb_proc_ptr(procval))); return binding; } diff --git a/mruby/mrbgems/mruby-proc-ext/src/proc.c b/mruby/mrbgems/mruby-proc-ext/src/proc.c index 4e90371c..8713e8bb 100644 --- a/mruby/mrbgems/mruby-proc-ext/src/proc.c +++ b/mruby/mrbgems/mruby-proc-ext/src/proc.c @@ -7,7 +7,7 @@ #include static mrb_value -mrb_proc_lambda_p(mrb_state *mrb, mrb_value self) +proc_lambda_p(mrb_state *mrb, mrb_value self) { struct RProc *p = mrb_proc_ptr(self); return mrb_bool_value(MRB_PROC_STRICT_P(p)); @@ -24,22 +24,21 @@ mrb_proc_source_location(mrb_state *mrb, struct RProc *p) int32_t line; const char *filename; - filename = mrb_debug_get_filename(mrb, irep, 0); - line = mrb_debug_get_line(mrb, irep, 0); - - return (!filename && line == -1)? mrb_nil_value() - : mrb_assoc_new(mrb, mrb_str_new_cstr(mrb, filename), mrb_fixnum_value(line)); + if (!mrb_debug_get_position(mrb, irep, 0, &line, &filename)) { + return mrb_nil_value(); + } + return mrb_assoc_new(mrb, mrb_str_new_cstr(mrb, filename), mrb_fixnum_value(line)); } } static mrb_value -mrb_proc_source_location_m(mrb_state *mrb, mrb_value self) +proc_source_location(mrb_state *mrb, mrb_value self) { return mrb_proc_source_location(mrb, mrb_proc_ptr(self)); } static mrb_value -mrb_proc_inspect(mrb_state *mrb, mrb_value self) +proc_inspect(mrb_state *mrb, mrb_value self) { struct RProc *p = mrb_proc_ptr(self); mrb_value str = mrb_str_new_lit(mrb, "#proc_class; - mrb_define_method(mrb, p, "lambda?", mrb_proc_lambda_p, MRB_ARGS_NONE()); - mrb_define_method(mrb, p, "source_location", mrb_proc_source_location_m, MRB_ARGS_NONE()); - mrb_define_method(mrb, p, "to_s", mrb_proc_inspect, MRB_ARGS_NONE()); - mrb_define_method(mrb, p, "inspect", mrb_proc_inspect, MRB_ARGS_NONE()); - mrb_define_method(mrb, p, "parameters", mrb_proc_parameters, MRB_ARGS_NONE()); - - mrb_define_class_method(mrb, mrb->kernel_module, "proc", mrb_kernel_proc, MRB_ARGS_NONE()|MRB_ARGS_BLOCK()); - mrb_define_method(mrb, mrb->kernel_module, "proc", mrb_kernel_proc, MRB_ARGS_NONE()|MRB_ARGS_BLOCK()); + mrb_define_method(mrb, p, "lambda?", proc_lambda_p, MRB_ARGS_NONE()); + mrb_define_method(mrb, p, "source_location", proc_source_location, MRB_ARGS_NONE()); + mrb_define_method(mrb, p, "to_s", proc_inspect, MRB_ARGS_NONE()); + mrb_define_method(mrb, p, "inspect", proc_inspect, MRB_ARGS_NONE()); + mrb_define_method(mrb, p, "parameters", mrb_proc_parameters, MRB_ARGS_NONE()); + + mrb_define_method(mrb, mrb->kernel_module, "proc", kernel_proc, MRB_ARGS_NONE()|MRB_ARGS_BLOCK()); } void diff --git a/mruby/mrbgems/mruby-proc-ext/test/proc.rb b/mruby/mrbgems/mruby-proc-ext/test/proc.rb index 7ac50840..13e7058f 100644 --- a/mruby/mrbgems/mruby-proc-ext/test/proc.rb +++ b/mruby/mrbgems/mruby-proc-ext/test/proc.rb @@ -7,8 +7,8 @@ def enable_debug_info? raise rescue => e @enable_debug_info = !e.backtrace.empty? - if(@enable_debug_info && e.backtrace[0].include?("(unknown)")) - @enable_debug_info = false + if @enable_debug_info && e.backtrace[0].include?("(unknown)") + @enable_debug_info = false end return @enable_debug_info end diff --git a/mruby/mrbgems/mruby-random/src/random.c b/mruby/mrbgems/mruby-random/src/random.c index d16ef332..c47702e9 100644 --- a/mruby/mrbgems/mruby-random/src/random.c +++ b/mruby/mrbgems/mruby-random/src/random.c @@ -222,8 +222,7 @@ random_m_bytes(mrb_state *mrb, mrb_value self) { rand_state *t = random_ptr(self); - mrb_int i; - mrb_get_args(mrb, "i", &i); + mrb_int i = mrb_as_int(mrb, mrb_get_arg1(mrb)); mrb_value bytes = mrb_str_new(mrb, NULL, i); uint8_t *p = (uint8_t*)RSTRING_PTR(bytes); diff --git a/mruby/mrbgems/mruby-range-ext/mrblib/range.rb b/mruby/mrbgems/mruby-range-ext/mrblib/range.rb index 8b670afe..e229c918 100644 --- a/mruby/mrbgems/mruby-range-ext/mrblib/range.rb +++ b/mruby/mrbgems/mruby-range-ext/mrblib/range.rb @@ -96,4 +96,12 @@ def min(&block) # delegate to Enumerable super() end + + # Compare two ranges and see if they overlap each other + # (1..5).overlap?(4..6) # => true + # (1..5).overlap?(7..9) # => false + def overlap?(other) + raise TypeError, "argument must be a range" unless other.kind_of?(Range) + other.begin == self.begin || self.cover?(other.begin) || other.cover?(self.begin) + end end diff --git a/mruby/mrbgems/mruby-range-ext/test/range.rb b/mruby/mrbgems/mruby-range-ext/test/range.rb index 4ae57566..d3771292 100644 --- a/mruby/mrbgems/mruby-range-ext/test/range.rb +++ b/mruby/mrbgems/mruby-range-ext/test/range.rb @@ -178,3 +178,37 @@ assert_equal nil, ((100..10).min { |x, y| x <=> y }) assert_equal nil, ((5...5).min { |x, y| x <=> y }) end + +assert('Range#overlap?') do + assert_false((0..2).overlap?(-2..-1)) + assert_false((0..2).overlap?(-2...0)) + assert_true((0..2).overlap?(-1..0)) + assert_true((0..2).overlap?(1..2)) + assert_true((0..2).overlap?(2..3)) + assert_false((0..2).overlap?(3...4)) + assert_false((0...2).overlap?(2..3)) + + assert_true((..0).overlap?(-1..0)) + assert_true((...0).overlap?(-1..0)) + assert_true((..0).overlap?(0..1)) + assert_true((..0).overlap?(..1)) + assert_false((..0).overlap?(1..2)) + assert_false((...0).overlap?(0..1)) + + assert_false((0..).overlap?(-2..-1)) + assert_false((0..).overlap?(...0)) + assert_true((0..).overlap?(..0)) + assert_true((0..).overlap?(0..1)) + assert_true((0..).overlap?(1..2)) + assert_true((0..).overlap?(-1..0)) + assert_true((0..).overlap?(1..)) + + assert_true((0..).overlap?(-1..0)) + assert_true((0..).overlap?(..0)) + assert_true((0..).overlap?(0..1)) + assert_true((0..).overlap?(1..2)) + assert_true((0..).overlap?(1..)) + + assert_raise(TypeError) { (0..).overlap?(1) } + assert_raise(TypeError) { (0..).overlap?(nil) } +end diff --git a/mruby/mrbgems/mruby-rational/src/rational.c b/mruby/mrbgems/mruby-rational/src/rational.c index 3b13fb57..2fadf5d6 100644 --- a/mruby/mrbgems/mruby-rational/src/rational.c +++ b/mruby/mrbgems/mruby-rational/src/rational.c @@ -202,8 +202,6 @@ float_decode_internal(mrb_state *mrb, mrb_float f, mrb_float *rf, int *n) *rf = f; } -void mrb_check_num_exact(mrb_state *mrb, mrb_float num); - static mrb_value rational_new_f(mrb_state *mrb, mrb_float f0) { @@ -487,7 +485,7 @@ rational_cmp(mrb_state *mrb, mrb_value x) } #endif default: - x = mrb_funcall_id(mrb, y, MRB_OPSYM(cmp), 1, x); + x = mrb_funcall_argv(mrb, y, MRB_OPSYM(cmp), 1, &x); if (mrb_integer_p(x)) { mrb_int z = mrb_integer(x); return mrb_fixnum_value(-z); @@ -544,7 +542,7 @@ mrb_rational_add(mrb_state *mrb, mrb_value x, mrb_value y) #endif default: - return mrb_funcall_id(mrb, y, MRB_OPSYM(add), 1, x); + return mrb_funcall_argv(mrb, y, MRB_OPSYM(add), 1, &x); } } @@ -642,7 +640,7 @@ mrb_rational_mul(mrb_state *mrb, mrb_value x, mrb_value y) #endif default: - return mrb_funcall_id(mrb, y, MRB_OPSYM(mul), 1, x); + return mrb_funcall_argv(mrb, y, MRB_OPSYM(mul), 1, &x); } } @@ -769,7 +767,7 @@ void mrb_mruby_rational_gem_init(mrb_state *mrb) struct RClass *rat; rat = mrb_define_class_id(mrb, MRB_SYM(Rational), mrb_class_get_id(mrb, MRB_SYM(Numeric))); - MRB_SET_INSTANCE_TT(rat, MRB_TT_RATIONAL); + MRB_SET_INSTANCE_TT(rat, MRB_TT_UNDEF); mrb_undef_class_method(mrb, rat, "new"); mrb_define_class_method(mrb, rat, "_new", rational_s_new, MRB_ARGS_REQ(2)); mrb_define_method(mrb, rat, "numerator", rational_numerator, MRB_ARGS_NONE()); diff --git a/mruby/mrbgems/mruby-set/mrblib/set.rb b/mruby/mrbgems/mruby-set/mrblib/set.rb index 0116e187..467290c7 100644 --- a/mruby/mrbgems/mruby-set/mrblib/set.rb +++ b/mruby/mrbgems/mruby-set/mrblib/set.rb @@ -306,17 +306,13 @@ def join(separator = nil) to_a.join(separator) end - def _inspect(recur_list) + def inspect return "#<#{self.class}: {}>" if empty? - return "#<#{self.class}: {...}>" if recur_list[self.object_id] - recur_list[self.object_id] = true - ary = map { |o| o._inspect(recur_list) } + return "#<#{self.class}: {...}>" if self.__inspect_recursive? + ary = map {|o| o.inspect } "#<#{self.class}: {#{ary.join(", ")}}>" end - def inspect - _inspect({}) - end alias to_s inspect def reset diff --git a/mruby/mrbgems/mruby-sleep/src/sleep.c b/mruby/mrbgems/mruby-sleep/src/sleep.c index d05bc194..4b30ceae 100644 --- a/mruby/mrbgems/mruby-sleep/src/sleep.c +++ b/mruby/mrbgems/mruby-sleep/src/sleep.c @@ -40,7 +40,7 @@ /* not implemented forever sleep (called without an argument)*/ static mrb_value -mrb_f_sleep(mrb_state *mrb, mrb_value self) +f_sleep(mrb_state *mrb, mrb_value self) { time_t beg = time(0); time_t end; @@ -60,7 +60,8 @@ mrb_f_sleep(mrb_state *mrb, mrb_value self) mrb_get_args(mrb, "i", &sec); if (sec >= 0) { sleep(sec); - } else { + } + else { mrb_raise(mrb, E_ARGUMENT_ERROR, "time interval must not be negative"); } #endif @@ -71,7 +72,7 @@ mrb_f_sleep(mrb_state *mrb, mrb_value self) /* mruby special; needed for mruby without float numbers */ static mrb_value -mrb_f_usleep(mrb_state *mrb, mrb_value self) +f_usleep(mrb_state *mrb, mrb_value self) { mrb_int usec; #ifdef _WIN32 @@ -94,7 +95,8 @@ mrb_f_usleep(mrb_state *mrb, mrb_value self) if (usec >= 0) { usleep(usec); - } else { + } + else { mrb_raise(mrb, E_ARGUMENT_ERROR, "time interval must not be negative"); } @@ -126,8 +128,8 @@ mrb_f_usleep(mrb_state *mrb, mrb_value self) void mrb_mruby_sleep_gem_init(mrb_state *mrb) { - mrb_define_method(mrb, mrb->kernel_module, "sleep", mrb_f_sleep, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, mrb->kernel_module, "usleep", mrb_f_usleep, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, mrb->kernel_module, "sleep", f_sleep, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, mrb->kernel_module, "usleep", f_usleep, MRB_ARGS_REQ(1)); } void diff --git a/mruby/mrbgems/mruby-socket/README.md b/mruby/mrbgems/mruby-socket/README.md index f88ae350..f7ff8ca3 100644 --- a/mruby/mrbgems/mruby-socket/README.md +++ b/mruby/mrbgems/mruby-socket/README.md @@ -20,8 +20,8 @@ Date: Tue, 21 May 2013 04:31:30 GMT ## Requirement -- [mruby-io](https://github.com/mruby/mruby/tree/master/mrbgems/mruby-io) mrbgem -- [iij/mruby-mtest](https://github.com/iij/mruby-mtest) mrgbem to run tests +- [mruby-io](../mruby-io) mrbgem +- [iij/mruby-mtest](https://github.com/iij/mruby-mtest) mrbgem to run tests - system must have RFC3493 basic socket interface - and some POSIX API... diff --git a/mruby/mrbgems/mruby-socket/mrbgem.rake b/mruby/mrbgems/mruby-socket/mrbgem.rake index dba00c64..c3684cd0 100644 --- a/mruby/mrbgems/mruby-socket/mrbgem.rake +++ b/mruby/mrbgems/mruby-socket/mrbgem.rake @@ -1,6 +1,6 @@ MRuby::Gem::Specification.new('mruby-socket') do |spec| spec.license = 'MIT' - spec.authors = ['Internet Initiative Japan', 'mruby developers'] + spec.authors = ['Internet Initiative Japan Inc.', 'mruby developers'] spec.summary = 'standard socket class' #spec.cc.defines << "HAVE_SA_LEN=0" @@ -12,6 +12,6 @@ MRuby::Gem::Specification.new('mruby-socket') do |spec| end spec.add_dependency('mruby-io', :core => 'mruby-io') - spec.add_dependency('mruby-pack', :core => 'mruby-pack') + spec.add_dependency('mruby-error', :core => 'mruby-error') # spec.add_dependency('mruby-mtest') end diff --git a/mruby/mrbgems/mruby-socket/mrblib/socket.rb b/mruby/mrbgems/mruby-socket/mrblib/socket.rb index 0e7bbdcc..6736df3d 100644 --- a/mruby/mrbgems/mruby-socket/mrblib/socket.rb +++ b/mruby/mrbgems/mruby-socket/mrblib/socket.rb @@ -19,7 +19,6 @@ def initialize(sockaddr, family=Socket::PF_UNSPEC, socktype=0, protocol=0) end @socktype = socktype @protocol = protocol - @canonname = nil end def self.foreach(nodename, service, family=nil, socktype=nil, protocol=nil, flags=0, &block) @@ -49,9 +48,7 @@ def afamily end #def bind - - attr_reader :canonname - + #def canonname #def connect #def connect_from #def connect_to @@ -70,10 +67,10 @@ def inspect else proto = '???' end - "#" else - "#" + proto = "SOCK_STREAM" end + "#" end def inspect_sockaddr @@ -570,52 +567,4 @@ def sysaccept end end -class Socket - include Constants -end - -class Socket - class Option - def initialize(family, level, optname, data) - @family = family - @level = level - @optname = optname - @data = data - end - - def self.bool(family, level, optname, bool) - self.new(family, level, optname, [(bool ? 1 : 0)].pack('i')) - end - - def self.int(family, level, optname, integer) - self.new(family, level, optname, [integer].pack('i')) - end - - #def self.linger(family, level, optname, integer) - #end - - attr_reader :data, :family, :level, :optname - - def bool - @data.unpack('i')[0] != 0 - end - - def inspect - "#" - end - - def int - @data.unpack('i')[0] - end - - def linger - raise NotImplementedError.new - end - - def unpack(template) - raise NotImplementedError.new - end - end -end - class SocketError < StandardError; end diff --git a/mruby/mrbgems/mruby-socket/src/socket.c b/mruby/mrbgems/mruby-socket/src/socket.c index a9ce33d2..73d89e6c 100644 --- a/mruby/mrbgems/mruby-socket/src/socket.c +++ b/mruby/mrbgems/mruby-socket/src/socket.c @@ -56,24 +56,22 @@ #ifdef _WIN32 static const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) { - if (af == AF_INET) - { + if (af == AF_INET) { struct sockaddr_in in = {0}; in.sin_family = AF_INET; memcpy(&in.sin_addr, src, sizeof(struct in_addr)); - getnameinfo((struct sockaddr *)&in, sizeof(struct - sockaddr_in), dst, cnt, NULL, 0, NI_NUMERICHOST); + getnameinfo((struct sockaddr*)&in, sizeof(struct sockaddr_in), + dst, cnt, NULL, 0, NI_NUMERICHOST); return dst; } - else if (af == AF_INET6) - { + else if (af == AF_INET6) { struct sockaddr_in6 in = {0}; in.sin6_family = AF_INET6; memcpy(&in.sin6_addr, src, sizeof(struct in_addr6)); - getnameinfo((struct sockaddr *)&in, sizeof(struct - sockaddr_in6), dst, cnt, NULL, 0, NI_NUMERICHOST); + getnameinfo((struct sockaddr*)&in, sizeof(struct sockaddr_in6), + dst, cnt, NULL, 0, NI_NUMERICHOST); return dst; } return NULL; @@ -86,16 +84,14 @@ static int inet_pton(int af, const char *src, void *dst) hints.ai_family = af; - if (getaddrinfo(src, NULL, &hints, &res) != 0) - { + if (getaddrinfo(src, NULL, &hints, &res) != 0) { printf("Couldn't resolve host %s\n", src); return -1; } ressave = res; - while (res) - { + while (res) { memcpy(dst, res->ai_addr, res->ai_addrlen); res = res->ai_next; } @@ -106,37 +102,57 @@ static int inet_pton(int af, const char *src, void *dst) #endif +struct gen_addrinfo_args { + struct RClass *klass; + struct addrinfo *addrinfo; +}; + +static mrb_value +gen_addrinfo(mrb_state *mrb, mrb_value args) +{ + mrb_value ary = mrb_ary_new(mrb); + int arena_idx = mrb_gc_arena_save(mrb); /* ary must be on arena! */ + struct gen_addrinfo_args *a = (struct gen_addrinfo_args*)mrb_cptr(args); + + for (struct addrinfo *res = a->addrinfo; res != NULL; res = res->ai_next) { + mrb_value sa = mrb_str_new(mrb, (char*)res->ai_addr, res->ai_addrlen); + mrb_value args[4] = {sa, mrb_fixnum_value(res->ai_family), mrb_fixnum_value(res->ai_socktype), mrb_fixnum_value(res->ai_protocol)}; + mrb_value ai = mrb_obj_new(mrb, a->klass, 4, args); + mrb_ary_push(mrb, ary, ai); + mrb_gc_arena_restore(mrb, arena_idx); + } + return ary; +} + +static mrb_value +free_addrinfo(mrb_state *mrb, mrb_value addrinfo) +{ + freeaddrinfo((struct addrinfo*)mrb_cptr(addrinfo)); + return mrb_nil_value(); +} + static mrb_value mrb_addrinfo_getaddrinfo(mrb_state *mrb, mrb_value klass) { - struct addrinfo hints = {0}, *res0, *res; - mrb_value ai, ary, family, lastai, nodename, protocol, sa, service, socktype; + struct addrinfo hints = {0}, *addr; + mrb_value family, protocol, service, socktype; mrb_int flags; - int arena_idx, error; - const char *hostname = NULL, *servname = NULL; - - ary = mrb_ary_new(mrb); - arena_idx = mrb_gc_arena_save(mrb); /* ary must be on arena! */ + const char *hostname, *servname = NULL; family = socktype = protocol = mrb_nil_value(); flags = 0; - mrb_get_args(mrb, "oo|oooi", &nodename, &service, &family, &socktype, &protocol, &flags); - - if (mrb_string_p(nodename)) { - hostname = RSTRING_CSTR(mrb, nodename); - } else if (mrb_nil_p(nodename)) { - hostname = NULL; - } else { - mrb_raise(mrb, E_TYPE_ERROR, "nodename must be String or nil"); - } + mrb_get_args(mrb, "z!o|oooi", &hostname, &service, &family, &socktype, &protocol, &flags); if (mrb_string_p(service)) { servname = RSTRING_CSTR(mrb, service); - } else if (mrb_integer_p(service)) { + } + else if (mrb_integer_p(service)) { servname = RSTRING_PTR(mrb_integer_to_str(mrb, service, 10)); - } else if (mrb_nil_p(service)) { + } + else if (mrb_nil_p(service)) { servname = NULL; - } else { + } + else { mrb_raise(mrb, E_TYPE_ERROR, "service must be String, Integer, or nil"); } @@ -154,29 +170,13 @@ mrb_addrinfo_getaddrinfo(mrb_state *mrb, mrb_value klass) hints.ai_protocol = (int)mrb_integer(protocol); } - lastai = mrb_cv_get(mrb, klass, MRB_SYM(_lastai)); - if (mrb_cptr_p(lastai)) { - freeaddrinfo((struct addrinfo*)mrb_cptr(lastai)); - mrb_cv_set(mrb, klass, MRB_SYM(_lastai), mrb_nil_value()); - } - - error = getaddrinfo(hostname, servname, &hints, &res0); + int error = getaddrinfo(hostname, servname, &hints, &addr); if (error) { mrb_raisef(mrb, E_SOCKET_ERROR, "getaddrinfo: %s", gai_strerror(error)); } - mrb_cv_set(mrb, klass, MRB_SYM(_lastai), mrb_cptr_value(mrb, res0)); - for (res = res0; res != NULL; res = res->ai_next) { - sa = mrb_str_new(mrb, (char*)res->ai_addr, res->ai_addrlen); - ai = mrb_funcall_id(mrb, klass, MRB_SYM(new), 4, sa, mrb_fixnum_value(res->ai_family), mrb_fixnum_value(res->ai_socktype), mrb_fixnum_value(res->ai_protocol)); - mrb_ary_push(mrb, ary, ai); - mrb_gc_arena_restore(mrb, arena_idx); - } - - freeaddrinfo(res0); - mrb_cv_set(mrb, klass, MRB_SYM(_lastai), mrb_nil_value()); - - return ary; + struct gen_addrinfo_args args = {mrb_class_ptr(klass), addr}; + return mrb_ensure(mrb, gen_addrinfo, mrb_cptr_value(mrb, &args), free_addrinfo, mrb_cptr_value(mrb, addr)); } static mrb_value @@ -195,7 +195,7 @@ mrb_addrinfo_getnameinfo(mrb_state *mrb, mrb_value self) if (!mrb_string_p(sastr)) { mrb_raise(mrb, E_SOCKET_ERROR, "invalid sockaddr"); } - error = getnameinfo((struct sockaddr *)RSTRING_PTR(sastr), (socklen_t)RSTRING_LEN(sastr), RSTRING_PTR(host), NI_MAXHOST, RSTRING_PTR(serv), NI_MAXSERV, (int)flags); + error = getnameinfo((struct sockaddr*)RSTRING_PTR(sastr), (socklen_t)RSTRING_LEN(sastr), RSTRING_PTR(host), NI_MAXHOST, RSTRING_PTR(serv), NI_MAXSERV, (int)flags); if (error) { mrb_raisef(mrb, E_SOCKET_ERROR, "getnameinfo: %s", gai_strerror(error)); } @@ -214,12 +214,13 @@ mrb_addrinfo_unix_path(mrb_state *mrb, mrb_value self) mrb_value sastr; sastr = mrb_iv_get(mrb, self, MRB_IVSYM(sockaddr)); - if (((struct sockaddr *)RSTRING_PTR(sastr))->sa_family != AF_UNIX) + if (!mrb_string_p(sastr) || ((struct sockaddr*)RSTRING_PTR(sastr))->sa_family != AF_UNIX) mrb_raise(mrb, E_SOCKET_ERROR, "need AF_UNIX address"); if (RSTRING_LEN(sastr) < (mrb_int)offsetof(struct sockaddr_un, sun_path) + 1) { return mrb_str_new(mrb, "", 0); - } else { - return mrb_str_new_cstr(mrb, ((struct sockaddr_un *)RSTRING_PTR(sastr))->sun_path); + } + else { + return mrb_str_new_cstr(mrb, ((struct sockaddr_un*)RSTRING_PTR(sastr))->sun_path); } } #endif @@ -234,11 +235,11 @@ sa2addrlist(mrb_state *mrb, const struct sockaddr *sa, socklen_t salen) switch (sa->sa_family) { case AF_INET: afstr = "AF_INET"; - port = ((struct sockaddr_in *)sa)->sin_port; + port = ((struct sockaddr_in*)sa)->sin_port; break; case AF_INET6: afstr = "AF_INET6"; - port = ((struct sockaddr_in6 *)sa)->sin6_port; + port = ((struct sockaddr_in6*)sa)->sin6_port; break; default: mrb_raise(mrb, E_ARGUMENT_ERROR, "bad af"); @@ -272,7 +273,7 @@ socket_family(int s) socklen_t salen; salen = sizeof(ss); - if (getsockname(s, (struct sockaddr *)&ss, &salen) == -1) + if (getsockname(s, (struct sockaddr*)&ss, &salen) == -1) return AF_UNSPEC; return ss.ss_family; } @@ -307,7 +308,7 @@ mrb_basicsocket_getpeername(mrb_state *mrb, mrb_value self) socklen_t salen; salen = sizeof(ss); - if (getpeername(socket_fd(mrb, self), (struct sockaddr *)&ss, &salen) != 0) + if (getpeername(socket_fd(mrb, self), (struct sockaddr*)&ss, &salen) != 0) mrb_sys_fail(mrb, "getpeername"); return mrb_str_new(mrb, (char*)&ss, salen); @@ -320,19 +321,180 @@ mrb_basicsocket_getsockname(mrb_state *mrb, mrb_value self) socklen_t salen; salen = sizeof(ss); - if (getsockname(socket_fd(mrb, self), (struct sockaddr *)&ss, &salen) != 0) + if (getsockname(socket_fd(mrb, self), (struct sockaddr*)&ss, &salen) != 0) mrb_sys_fail(mrb, "getsockname"); return mrb_str_new(mrb, (char*)&ss, salen); } +static struct RClass * +socket_option_class(mrb_state *mrb) +{ + return mrb_class_get_under_id(mrb, mrb_class_get_id(mrb, MRB_SYM(Socket)), MRB_SYM(Option)); +} + +static mrb_value +socket_option_init(mrb_state *mrb, mrb_value self) +{ + mrb_int family, level, optname; + mrb_value data; + + mrb_get_args(mrb, "iiio", &family, &level, &optname, &data); + mrb_iv_set(mrb, self, MRB_SYM(family), mrb_int_value(mrb, family)); + mrb_iv_set(mrb, self, MRB_SYM(level), mrb_int_value(mrb, level)); + mrb_iv_set(mrb, self, MRB_SYM(optname), mrb_int_value(mrb, optname)); + mrb_iv_set(mrb, self, MRB_SYM(data), data); + + return self; +} + +static mrb_value +socket_option_s_bool(mrb_state *mrb, mrb_value klass) +{ + mrb_value args[4]; + mrb_bool data; + int tmp; + + mrb_get_args(mrb, "ooob", &args[0], &args[1], &args[2], &data); + tmp = (int)data; + args[3] = mrb_str_new(mrb, (char*)&tmp, sizeof(int)); + return mrb_obj_new(mrb, mrb_class_ptr(klass), 4, args); +} + +static mrb_value +socket_option_s_int(mrb_state *mrb, mrb_value klass) +{ + mrb_value args[4]; + mrb_int data; + int tmp; + + mrb_get_args(mrb, "oooi", &args[0], &args[1], &args[2], &data); + tmp = (int)data; + args[3] = mrb_str_new(mrb, (char*)&tmp, sizeof(int)); + return mrb_obj_new(mrb, mrb_class_ptr(klass), 4, args); +} + +static mrb_value +socket_option_family(mrb_state *mrb, mrb_value self) +{ + return mrb_iv_get(mrb, self, MRB_SYM(family)); +} + +static mrb_value +socket_option_level(mrb_state *mrb, mrb_value self) +{ + return mrb_iv_get(mrb, self, MRB_SYM(level)); +} + +static mrb_value +socket_option_optname(mrb_state *mrb, mrb_value self) +{ + return mrb_iv_get(mrb, self, MRB_SYM(optname)); +} + +static mrb_value +socket_option_data(mrb_state *mrb, mrb_value self) +{ + return mrb_iv_get(mrb, self, MRB_SYM(data)); +} + +static int +option_int(mrb_state *mrb, mrb_value self) +{ + mrb_value data = mrb_obj_as_string(mrb, mrb_iv_get(mrb, self, MRB_SYM(data))); + int tmp; + + if (RSTRING_LEN(data) != sizeof(int)) { + mrb_raisef(mrb, E_TYPE_ERROR, "size differ; expected as sizeof(int)=%i but %i", (mrb_int)sizeof(int), RSTRING_LEN(data)); + } + memcpy((char*)&tmp, RSTRING_PTR(data), sizeof(int)); + return tmp; +} + +static mrb_value +socket_option_int(mrb_state *mrb, mrb_value self) +{ + int i = option_int(mrb, self); + return mrb_int_value(mrb, (mrb_int)i); +} + +static mrb_value +socket_option_bool(mrb_state *mrb, mrb_value self) +{ + int i = option_int(mrb, self); + return mrb_bool_value((mrb_bool)i); +} + +static mrb_value +socket_option_notimp(mrb_state *mrb, mrb_value self) +{ + mrb_notimplement(mrb); + return mrb_nil_value(); +} + +static mrb_value +socket_option_inspect(mrb_state *mrb, mrb_value self) +{ + mrb_value str = mrb_str_new_cstr(mrb, "#"); + + return str; +} + static mrb_value mrb_basicsocket_getsockopt(mrb_state *mrb, mrb_value self) { char opt[8]; int s; mrb_int family, level, optname; - mrb_value c, data; + mrb_value data; socklen_t optlen; mrb_get_args(mrb, "ii", &level, &optname); @@ -340,10 +502,10 @@ mrb_basicsocket_getsockopt(mrb_state *mrb, mrb_value self) optlen = sizeof(opt); if (getsockopt(s, (int)level, (int)optname, opt, &optlen) == -1) mrb_sys_fail(mrb, "getsockopt"); - c = mrb_const_get(mrb, mrb_obj_value(mrb_class_get_id(mrb, MRB_SYM(Socket))), MRB_SYM(Option)); family = socket_family(s); data = mrb_str_new(mrb, opt, optlen); - return mrb_funcall_id(mrb, c, MRB_SYM(new), 4, mrb_fixnum_value(family), mrb_fixnum_value(level), mrb_fixnum_value(optname), data); + mrb_value args[4] = {mrb_fixnum_value(family), mrb_fixnum_value(level), mrb_fixnum_value(optname), data}; + return mrb_obj_new(mrb, socket_option_class(mrb), 4, args); } static mrb_value @@ -374,7 +536,7 @@ mrb_basicsocket_recvfrom(mrb_state *mrb, mrb_value self) buf = mrb_str_new_capa(mrb, maxlen); socklen = sizeof(struct sockaddr_storage); sa = mrb_str_new_capa(mrb, socklen); - n = recvfrom(socket_fd(mrb, self), RSTRING_PTR(buf), (fsize_t)maxlen, (int)flags, (struct sockaddr *)RSTRING_PTR(sa), &socklen); + n = recvfrom(socket_fd(mrb, self), RSTRING_PTR(buf), (fsize_t)maxlen, (int)flags, (struct sockaddr*)RSTRING_PTR(sa), &socklen); if (n == -1) mrb_sys_fail(mrb, "recvfrom"); mrb_str_resize(mrb, buf, (mrb_int)n); @@ -396,7 +558,8 @@ mrb_basicsocket_send(mrb_state *mrb, mrb_value self) mrb_get_args(mrb, "Si|S", &mesg, &flags, &dest); if (mrb_nil_p(dest)) { n = send(socket_fd(mrb, self), RSTRING_PTR(mesg), (fsize_t)RSTRING_LEN(mesg), (int)flags); - } else { + } + else { n = sendto(socket_fd(mrb, self), RSTRING_PTR(mesg), (fsize_t)RSTRING_LEN(mesg), (int)flags, (const struct sockaddr*)RSTRING_PTR(dest), (fsize_t)RSTRING_LEN(dest)); } if (n == -1) @@ -442,34 +605,38 @@ mrb_basicsocket_setsockopt(mrb_state *mrb, mrb_value self) argc = mrb_get_args(mrb, "o|io", &so, &optname, &optval); if (argc == 3) { - if (!mrb_integer_p(so)) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "level is not an integer"); - } + mrb_ensure_int_type(mrb, so); level = mrb_integer(so); if (mrb_string_p(optval)) { /* that's good */ - } else if (mrb_true_p(optval) || mrb_false_p(optval)) { + } + else if (mrb_true_p(optval) || mrb_false_p(optval)) { mrb_int i = mrb_test(optval) ? 1 : 0; optval = mrb_str_new(mrb, (char*)&i, sizeof(i)); - } else if (mrb_integer_p(optval)) { + } + else if (mrb_integer_p(optval)) { if (optname == IP_MULTICAST_TTL || optname == IP_MULTICAST_LOOP) { char uc = (char)mrb_integer(optval); optval = mrb_str_new(mrb, &uc, sizeof(uc)); - } else { + } + else { mrb_int i = mrb_integer(optval); optval = mrb_str_new(mrb, (char*)&i, sizeof(i)); } - } else { + } + else { mrb_raise(mrb, E_ARGUMENT_ERROR, "optval should be true, false, an integer, or a string"); } - } else if (argc == 1) { - if (strcmp(mrb_obj_classname(mrb, so), "Socket::Option") != 0) + } + else if (argc == 1) { + if (!mrb_obj_is_instance_of(mrb, so, socket_option_class(mrb))) mrb_raise(mrb, E_ARGUMENT_ERROR, "not an instance of Socket::Option"); - 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); + level = mrb_as_int(mrb, mrb_iv_get(mrb, so, MRB_SYM(level))); + optname = mrb_as_int(mrb, mrb_iv_get(mrb, so, MRB_SYM(optname))); + optval = mrb_iv_get(mrb, so, MRB_SYM(data)); mrb_ensure_string_type(mrb, optval); - } else { + } + else { mrb_argnum_error(mrb, argc, 3, 3); } @@ -533,16 +700,19 @@ mrb_ipsocket_pton(mrb_state *mrb, mrb_value klass) if (af == AF_INET) { struct in_addr in; - if (inet_pton(AF_INET, buf, (void *)&in.s_addr) != 1) + if (inet_pton(AF_INET, buf, (void*)&in.s_addr) != 1) goto invalid; return mrb_str_new(mrb, (char*)&in.s_addr, 4); - } else if (af == AF_INET6) { + } + else if (af == AF_INET6) { struct in6_addr in6; - if (inet_pton(AF_INET6, buf, (void *)&in6.s6_addr) != 1) + if (inet_pton(AF_INET6, buf, (void*)&in6.s6_addr) != 1) goto invalid; return mrb_str_new(mrb, (char*)&in6.s6_addr, 16); - } else + } + else { mrb_raise(mrb, E_ARGUMENT_ERROR, "unsupported address family"); + } invalid: mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid address"); @@ -565,12 +735,12 @@ mrb_ipsocket_recvfrom(mrb_state *mrb, mrb_value self) buf = mrb_str_new_capa(mrb, maxlen); socklen = sizeof(ss); n = recvfrom(fd, RSTRING_PTR(buf), (fsize_t)maxlen, (int)flags, - (struct sockaddr *)&ss, &socklen); + (struct sockaddr*)&ss, &socklen); if (n == -1) { mrb_sys_fail(mrb, "recvfrom"); } mrb_str_resize(mrb, buf, (mrb_int)n); - a = sa2addrlist(mrb, (struct sockaddr *)&ss, socklen); + a = sa2addrlist(mrb, (struct sockaddr*)&ss, socklen); pair = mrb_ary_new_capa(mrb, 2); mrb_ary_push(mrb, pair, buf); mrb_ary_push(mrb, pair, a); @@ -620,7 +790,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, (mrb_int)socklen); - s1 = (int)accept(s0, (struct sockaddr *)RSTRING_PTR(sastr), &socklen); + s1 = (int)accept(s0, (struct sockaddr*)RSTRING_PTR(sastr), &socklen); if (s1 == -1) { mrb_sys_fail(mrb, "accept"); } @@ -639,7 +809,7 @@ mrb_socket_bind(mrb_state *mrb, mrb_value klass) mrb_int s; mrb_get_args(mrb, "iS", &s, &sastr); - if (bind((int)s, (struct sockaddr *)RSTRING_PTR(sastr), (socklen_t)RSTRING_LEN(sastr)) == -1) { + if (bind((int)s, (struct sockaddr*)RSTRING_PTR(sastr), (socklen_t)RSTRING_LEN(sastr)) == -1) { mrb_sys_fail(mrb, "bind"); } return mrb_nil_value(); @@ -652,7 +822,7 @@ mrb_socket_connect(mrb_state *mrb, mrb_value klass) mrb_int s; mrb_get_args(mrb, "iS", &s, &sastr); - if (connect((int)s, (struct sockaddr *)RSTRING_PTR(sastr), (socklen_t)RSTRING_LEN(sastr)) == -1) { + if (connect((int)s, (struct sockaddr*)RSTRING_PTR(sastr), (socklen_t)RSTRING_LEN(sastr)) == -1) { mrb_sys_fail(mrb, "connect"); } return mrb_nil_value(); @@ -680,7 +850,7 @@ mrb_socket_sockaddr_family(mrb_state *mrb, mrb_value klass) if ((size_t)RSTRING_LEN(str) < offsetof(struct sockaddr, sa_family) + sizeof(sa->sa_family)) { mrb_raise(mrb, E_SOCKET_ERROR, "invalid sockaddr (too short)"); } - sa = (const struct sockaddr *)RSTRING_PTR(str); + sa = (const struct sockaddr*)RSTRING_PTR(str); return mrb_fixnum_value(sa->sa_family); } @@ -699,7 +869,7 @@ mrb_socket_sockaddr_un(mrb_state *mrb, mrb_value klass) mrb_raisef(mrb, E_ARGUMENT_ERROR, "too long unix socket path (max: %d bytes)", (int)sizeof(sunp->sun_path) - 1); } s = mrb_str_new_capa(mrb, sizeof(struct sockaddr_un)); - sunp = (struct sockaddr_un *)RSTRING_PTR(s); + sunp = (struct sockaddr_un*)RSTRING_PTR(s); #if HAVE_SA_LEN sunp->sun_len = sizeof(struct sockaddr_un); #endif @@ -798,7 +968,8 @@ mrb_win32_basicsocket_sysread(mrb_state *mrb, mrb_value self) case 0: /* EOF */ if (maxlen == 0) { buf = mrb_str_new_cstr(mrb, ""); - } else { + } + else { mrb_raise(mrb, E_EOF_ERROR, "sysread failed: End of File"); } break; @@ -843,7 +1014,7 @@ void mrb_mruby_socket_gem_init(mrb_state* mrb) { struct RClass *io, *ai, *sock, *bsock, *ipsock, *tcpsock; - struct RClass *constants; + struct RClass *constants, *option; #ifdef _WIN32 WSADATA wsaData; @@ -854,7 +1025,6 @@ mrb_mruby_socket_gem_init(mrb_state* mrb) #endif ai = mrb_define_class(mrb, "Addrinfo", mrb->object_class); - mrb_mod_cv_set(mrb, ai, MRB_SYM(_lastai), mrb_nil_value()); mrb_define_class_method(mrb, ai, "getaddrinfo", mrb_addrinfo_getaddrinfo, MRB_ARGS_REQ(2)|MRB_ARGS_OPT(4)); mrb_define_method(mrb, ai, "getnameinfo", mrb_addrinfo_getnameinfo, MRB_ARGS_OPT(1)); #ifndef _WIN32 @@ -924,8 +1094,25 @@ mrb_mruby_socket_gem_init(mrb_state* mrb) mrb_define_method(mrb, bsock, "sysread", mrb_win32_basicsocket_sysread, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1)); mrb_define_method(mrb, bsock, "sysseek", mrb_win32_basicsocket_sysseek, MRB_ARGS_REQ(1)); mrb_define_method(mrb, bsock, "syswrite", mrb_win32_basicsocket_syswrite, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, bsock, "read", mrb_win32_basicsocket_sysread, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1)); + mrb_define_method(mrb, bsock, "write", mrb_win32_basicsocket_syswrite, MRB_ARGS_REQ(1)); #endif + option = mrb_define_class_under(mrb, sock, "Option", mrb->object_class); + mrb_define_class_method(mrb, option, "bool", socket_option_s_bool, MRB_ARGS_REQ(4)); + mrb_define_class_method(mrb, option, "int", socket_option_s_int, MRB_ARGS_REQ(4)); + mrb_define_method(mrb, option, "initialize", socket_option_init, MRB_ARGS_REQ(4)); + mrb_define_method(mrb, option, "inspect", socket_option_inspect, MRB_ARGS_REQ(0)); + mrb_define_method(mrb, option, "family", socket_option_family, MRB_ARGS_REQ(0)); + mrb_define_method(mrb, option, "level", socket_option_level, MRB_ARGS_REQ(0)); + mrb_define_method(mrb, option, "optname", socket_option_optname, MRB_ARGS_REQ(0)); + mrb_define_method(mrb, option, "data", socket_option_data, MRB_ARGS_REQ(0)); + mrb_define_method(mrb, option, "bool", socket_option_bool, MRB_ARGS_REQ(0)); + mrb_define_method(mrb, option, "int", socket_option_int, MRB_ARGS_REQ(0)); + + mrb_define_method(mrb, option, "linger", socket_option_notimp, MRB_ARGS_REQ(0)); + mrb_define_method(mrb, option, "unpack", socket_option_notimp, MRB_ARGS_REQ(1)); + constants = mrb_define_module_under(mrb, sock, "Constants"); #define define_const(SYM) \ @@ -934,16 +1121,13 @@ mrb_mruby_socket_gem_init(mrb_state* mrb) } while (0) #include "const.cstub" + + mrb_include_module(mrb, sock, constants); } void mrb_mruby_socket_gem_final(mrb_state* mrb) { - mrb_value ai; - ai = mrb_mod_cv_get(mrb, mrb_class_get_id(mrb, MRB_SYM(Addrinfo)), MRB_SYM(_lastai)); - if (mrb_cptr_p(ai)) { - freeaddrinfo((struct addrinfo*)mrb_cptr(ai)); - } #ifdef _WIN32 WSACleanup(); #endif diff --git a/mruby/mrbgems/mruby-sprintf/src/sprintf.c b/mruby/mrbgems/mruby-sprintf/src/sprintf.c index 71a3e90d..9f7fb59d 100644 --- a/mruby/mrbgems/mruby-sprintf/src/sprintf.c +++ b/mruby/mrbgems/mruby-sprintf/src/sprintf.c @@ -146,7 +146,8 @@ fmt_float(char *buf, size_t buf_size, char fmt, int flags, int width, int prec, memmove(&buf[width - len], buf, len); if (zero_pad) { memset(buf, '0', width - len); - } else { + } + else { memset(buf, ' ', width - len); } return width; @@ -604,7 +605,8 @@ mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fm mrb_sym id = 0; int flags = FNONE; - for (t = p; t < end && *t != '%'; t++) ; + for (t = p; t < end && *t != '%'; t++) + ; if (t + 1 == end) t++; PUSH(p, t - p); if (t >= end) @@ -761,7 +763,7 @@ mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fm tmp = mrb_str_new(mrb, buf, 1); } else { - tmp = mrb_funcall_id(mrb, val, MRB_SYM(chr), 0); + tmp = mrb_funcall_argv(mrb, val, MRB_SYM(chr), 0, NULL); mrb_check_type(mrb, tmp, MRB_TT_STRING); } #endif @@ -994,7 +996,8 @@ mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fm if ((flags & (FMINUS|FPREC)) != FMINUS) { char c = '0'; FILL(c, prec - len); - } else if (v < 0) { + } + else if (v < 0) { char c = sign_bits(base, p); FILL(c, prec - len); } diff --git a/mruby/mrbgems/mruby-string-ext/mrblib/string.rb b/mruby/mrbgems/mruby-string-ext/mrblib/string.rb index 87f8ab9a..9f940ca3 100644 --- a/mruby/mrbgems/mruby-string-ext/mrblib/string.rb +++ b/mruby/mrbgems/mruby-string-ext/mrblib/string.rb @@ -314,13 +314,14 @@ def each_char(&block) end def codepoints(&block) + cp = __codepoints() if block_given? - self.split('').each do|x| - block.call(x.ord) + cp.each do|x| + block.call(x) end self else - self.split('').map{|x| x.ord} + cp end end alias each_codepoint codepoints diff --git a/mruby/mrbgems/mruby-string-ext/src/string.c b/mruby/mrbgems/mruby-string-ext/src/string.c index 881409ad..4e2be81f 100644 --- a/mruby/mrbgems/mruby-string-ext/src/string.c +++ b/mruby/mrbgems/mruby-string-ext/src/string.c @@ -11,10 +11,10 @@ #define ENC_UTF8 "UTF-8" #define ENC_COMP_P(enc, enc_lit) \ - str_casecmp_p(RSTRING_PTR(enc), RSTRING_LEN(enc), enc_lit, sizeof(enc_lit"")-1) + casecmp_p(RSTRING_PTR(enc), RSTRING_LEN(enc), enc_lit, sizeof(enc_lit"")-1) static mrb_bool -str_casecmp_p(const char *s1, mrb_int len1, const char *s2, mrb_int len2) +casecmp_p(const char *s1, mrb_int len1, const char *s2, mrb_int len2) { const char *e1, *e2; @@ -96,7 +96,7 @@ int_chr_utf8(mrb_state *mrb, mrb_value num) * Note: case conversion is effective only in ASCII region. */ static mrb_value -mrb_str_swapcase_bang(mrb_state *mrb, mrb_value str) +str_swapcase_bang(mrb_state *mrb, mrb_value str) { char *p, *pend; int modify = 0; @@ -133,12 +133,12 @@ mrb_str_swapcase_bang(mrb_state *mrb, mrb_value str) * "cYbEr_PuNk11".swapcase #=> "CyBeR_pUnK11" */ static mrb_value -mrb_str_swapcase(mrb_state *mrb, mrb_value self) +str_swapcase(mrb_state *mrb, mrb_value self) { mrb_value str; str = mrb_str_dup(mrb, self); - mrb_str_swapcase_bang(mrb, str); + str_swapcase_bang(mrb, str); return str; } @@ -173,7 +173,7 @@ str_concat(mrb_state *mrb, mrb_value self, mrb_value str) * */ static mrb_value -mrb_str_concat_m(mrb_state *mrb, mrb_value self) +str_concat_m(mrb_state *mrb, mrb_value self) { if (mrb_get_argc(mrb) == 1) { str_concat(mrb, self, mrb_get_arg1(mrb)); @@ -204,7 +204,7 @@ mrb_str_concat_m(mrb_state *mrb, mrb_value self) * "h".start_with?("heaven", "hell") #=> false */ static mrb_value -mrb_str_start_with(mrb_state *mrb, mrb_value self) +str_start_with(mrb_state *mrb, mrb_value self) { const mrb_value *argv; mrb_int argc, i; @@ -234,7 +234,7 @@ mrb_str_start_with(mrb_state *mrb, mrb_value self) * Returns true if +str+ ends with one of the +suffixes+ given. */ static mrb_value -mrb_str_end_with(mrb_state *mrb, mrb_value self) +str_end_with(mrb_state *mrb, mrb_value self) { const mrb_value *argv; mrb_int argc, i; @@ -308,7 +308,7 @@ tr_parse_pattern(mrb_state *mrb, struct tr_pattern *ret, const mrb_value v_patte struct tr_pattern *pat1; mrb_int i = 0; - if(flag_reverse_enable && pattern_length >= 2 && pattern[0] == '^') { + if (flag_reverse_enable && pattern_length >= 2 && pattern[0] == '^') { flag_reverse = TRUE; i++; } @@ -580,7 +580,7 @@ str_tr(mrb_state *mrb, mrb_value str, mrb_value p1, mrb_value p2, mrb_bool squee * Note: conversion is effective only in ASCII region. */ static mrb_value -mrb_str_tr(mrb_state *mrb, mrb_value str) +str_tr_m(mrb_state *mrb, mrb_value str) { mrb_value dup; mrb_value p1, p2; @@ -599,7 +599,7 @@ mrb_str_tr(mrb_state *mrb, mrb_value str) * Returns str, or nil if no changes were made. */ static mrb_value -mrb_str_tr_bang(mrb_state *mrb, mrb_value str) +str_tr_bang(mrb_state *mrb, mrb_value str) { mrb_value p1, p2; @@ -622,7 +622,7 @@ mrb_str_tr_bang(mrb_state *mrb, mrb_value str) * "hello".tr_s('el', 'hx') #=> "hhxo" */ static mrb_value -mrb_str_tr_s(mrb_state *mrb, mrb_value str) +str_tr_s(mrb_state *mrb, mrb_value str) { mrb_value dup; mrb_value p1, p2; @@ -641,7 +641,7 @@ mrb_str_tr_s(mrb_state *mrb, mrb_value str) * str, or nil if no changes were made. */ static mrb_value -mrb_str_tr_s_bang(mrb_state *mrb, mrb_value str) +str_tr_s_bang(mrb_state *mrb, mrb_value str) { mrb_value p1, p2; @@ -716,7 +716,7 @@ str_squeeze(mrb_state *mrb, mrb_value str, mrb_value v_pat) * "putters shoot balls".squeeze("m-z") #=> "puters shot balls" */ static mrb_value -mrb_str_squeeze(mrb_state *mrb, mrb_value str) +str_squeeze_m(mrb_state *mrb, mrb_value str) { mrb_value pat = mrb_nil_value(); mrb_value dup; @@ -735,7 +735,7 @@ mrb_str_squeeze(mrb_state *mrb, mrb_value str) * changes were made. */ static mrb_value -mrb_str_squeeze_bang(mrb_state *mrb, mrb_value str) +str_squeeze_bang(mrb_state *mrb, mrb_value str) { mrb_value pat = mrb_nil_value(); @@ -779,7 +779,7 @@ str_delete(mrb_state *mrb, mrb_value str, mrb_value v_pat) } static mrb_value -mrb_str_delete(mrb_state *mrb, mrb_value str) +str_delete_m(mrb_state *mrb, mrb_value str) { mrb_value pat; mrb_value dup; @@ -791,7 +791,7 @@ mrb_str_delete(mrb_state *mrb, mrb_value str) } static mrb_value -mrb_str_delete_bang(mrb_state *mrb, mrb_value str) +str_delete_bang(mrb_state *mrb, mrb_value str) { mrb_value pat; @@ -814,7 +814,7 @@ mrb_str_delete_bang(mrb_state *mrb, mrb_value str) * the end of a sequence or the end of a other_str. */ static mrb_value -mrb_str_count(mrb_state *mrb, mrb_value str) +str_count(mrb_state *mrb, mrb_value str) { mrb_value v_pat = mrb_nil_value(); mrb_int i; @@ -838,13 +838,13 @@ mrb_str_count(mrb_state *mrb, mrb_value str) } static mrb_value -mrb_str_hex(mrb_state *mrb, mrb_value self) +str_hex(mrb_state *mrb, mrb_value self) { return mrb_str_to_integer(mrb, self, 16, FALSE); } static mrb_value -mrb_str_oct(mrb_state *mrb, mrb_value self) +str_oct(mrb_state *mrb, mrb_value self) { return mrb_str_to_integer(mrb, self, 8, FALSE); } @@ -859,7 +859,7 @@ mrb_str_oct(mrb_state *mrb, mrb_value self) * a.chr #=> "a" */ static mrb_value -mrb_str_chr(mrb_state *mrb, mrb_value self) +str_chr(mrb_state *mrb, mrb_value self) { return mrb_str_substr(mrb, self, 0, 1); } @@ -879,7 +879,7 @@ mrb_str_chr(mrb_state *mrb, mrb_value self) * 230.chr("UTF-8") #=> "\u00E6" */ static mrb_value -mrb_int_chr(mrb_state *mrb, mrb_value num) +int_chr(mrb_state *mrb, mrb_value num) { mrb_value enc; mrb_bool enc_given; @@ -912,7 +912,7 @@ mrb_int_chr(mrb_state *mrb, mrb_value num) * a.succ #=> "abd" */ static mrb_value -mrb_str_succ_bang(mrb_state *mrb, mrb_value self) +str_succ_bang(mrb_state *mrb, mrb_value self) { mrb_value result; unsigned char *p, *e, *b, *t; @@ -990,12 +990,12 @@ mrb_str_succ_bang(mrb_state *mrb, mrb_value self) } static mrb_value -mrb_str_succ(mrb_state *mrb, mrb_value self) +str_succ(mrb_state *mrb, mrb_value self) { mrb_value str; str = mrb_str_dup(mrb, self); - mrb_str_succ_bang(mrb, str); + str_succ_bang(mrb, str); return str; } @@ -1029,7 +1029,7 @@ utf8code(unsigned char* p, mrb_int limit) } static mrb_value -mrb_str_ord(mrb_state* mrb, mrb_value str) +str_ord(mrb_state* mrb, mrb_value str) { if (RSTRING_LEN(str) == 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "empty string"); @@ -1037,14 +1037,50 @@ mrb_str_ord(mrb_state* mrb, mrb_value str) if (c < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid UTF-8 byte sequence"); return mrb_fixnum_value(c); } + +static mrb_value +str_codepoints(mrb_state *mrb, mrb_value self) +{ + mrb_value result; + char *p = RSTRING_PTR(self); + mrb_int len = RSTRING_LEN(self); + char *e = p + len; + + mrb->c->ci->mid = 0; + result = mrb_ary_new(mrb); + while (p < e) { + mrb_int c = utf8code((unsigned char*)p, len); + mrb_ary_push(mrb, result, mrb_int_value(mrb, c)); + mrb_int ulen = mrb_utf8len(p, e); + len -= ulen; + p += ulen; + } + return result; +} #else static mrb_value -mrb_str_ord(mrb_state* mrb, mrb_value str) +str_ord(mrb_state* mrb, mrb_value str) { if (RSTRING_LEN(str) == 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "empty string"); return mrb_fixnum_value((unsigned char)RSTRING_PTR(str)[0]); } + +static mrb_value +str_codepoints(mrb_state *mrb, mrb_value self) +{ + mrb_value result; + char *p = RSTRING_PTR(self); + char *e = p + RSTRING_LEN(self); + + mrb->c->ci->mid = 0; + result = mrb_ary_new(mrb); + while (p < e) { + mrb_ary_push(mrb, result, mrb_int_value(mrb, (mrb_int)*p)); + p++; + } + return result; +} #endif /* @@ -1058,7 +1094,7 @@ mrb_str_ord(mrb_state* mrb, mrb_value str) * "hello".delete_prefix!("llo") #=> nil */ static mrb_value -mrb_str_del_prefix_bang(mrb_state *mrb, mrb_value self) +str_del_prefix_bang(mrb_state *mrb, mrb_value self) { mrb_int plen, slen; const char *ptr; @@ -1092,7 +1128,7 @@ mrb_str_del_prefix_bang(mrb_state *mrb, mrb_value self) * "hello".delete_prefix("llo") #=> "hello" */ static mrb_value -mrb_str_del_prefix(mrb_state *mrb, mrb_value self) +str_del_prefix(mrb_state *mrb, mrb_value self) { mrb_int plen, slen; const char *ptr; @@ -1116,7 +1152,7 @@ mrb_str_del_prefix(mrb_state *mrb, mrb_value self) * "hello".delete_suffix!("hel") #=> nil */ static mrb_value -mrb_str_del_suffix_bang(mrb_state *mrb, mrb_value self) +str_del_suffix_bang(mrb_state *mrb, mrb_value self) { mrb_int plen, slen; const char *ptr; @@ -1148,7 +1184,7 @@ mrb_str_del_suffix_bang(mrb_state *mrb, mrb_value self) * "hello".delete_suffix("llo") #=> "hello" */ static mrb_value -mrb_str_del_suffix(mrb_state *mrb, mrb_value self) +str_del_suffix(mrb_state *mrb, mrb_value self) { mrb_int plen, slen; const char *ptr; @@ -1175,18 +1211,21 @@ mrb_str_del_suffix(mrb_state *mrb, mrb_value self) * "abcdef".casecmp("ABCDEF") #=> 0 */ static mrb_value -mrb_str_casecmp(mrb_state *mrb, mrb_value self) +str_casecmp(mrb_state *mrb, mrb_value self) { - mrb_value str; + mrb_value str = mrb_get_arg1(mrb); - mrb_get_args(mrb, "o", &str); if (!mrb_string_p(str)) return mrb_nil_value(); struct RString *s1 = mrb_str_ptr(self); struct RString *s2 = mrb_str_ptr(str); - mrb_int len = lesser(RSTR_LEN(s1), RSTR_LEN(s2)); + + mrb_int len1 = RSTR_LEN(s1); + mrb_int len2 = RSTR_LEN(s2); + mrb_int len = lesser(len1, len2); char *p1 = RSTR_PTR(s1); char *p2 = RSTR_PTR(s2); + if (p1 == p2) return mrb_fixnum_value(0); for (mrb_int i=0; i c2) return mrb_fixnum_value(1); if (c1 < c2) return mrb_fixnum_value(-1); } - if (RSTR_LEN(s1) == RSTR_LEN(s2)) return mrb_fixnum_value(0); - if (RSTR_LEN(s1) > RSTR_LEN(s2)) return mrb_fixnum_value(1); + if (len1 == len2) return mrb_fixnum_value(0); + if (len1 > len2) return mrb_fixnum_value(1); return mrb_fixnum_value(-1); } @@ -1208,15 +1247,15 @@ mrb_str_casecmp(mrb_state *mrb, mrb_value self) * false if they are not equal, and nil if other is not a string. */ static mrb_value -mrb_str_casecmp_p(mrb_state *mrb, mrb_value self) +str_casecmp_p(mrb_state *mrb, mrb_value self) { - mrb_value c = mrb_str_casecmp(mrb, self); + mrb_value c = str_casecmp(mrb, self); if (mrb_nil_p(c)) return c; return mrb_bool_value(mrb_fixnum(c) == 0); } static mrb_value -mrb_str_lines(mrb_state *mrb, mrb_value self) +str_lines(mrb_state *mrb, mrb_value self) { mrb_value result; int ai; @@ -1248,7 +1287,7 @@ mrb_str_lines(mrb_state *mrb, mrb_value self) * Otherwise returns self.dup, which is not frozen. */ static mrb_value -mrb_str_uplus(mrb_state *mrb, mrb_value str) +str_uplus(mrb_state *mrb, mrb_value str) { if (mrb_frozen_p(mrb_obj_ptr(str))) { return mrb_str_dup(mrb, str); @@ -1270,7 +1309,7 @@ mrb_str_uplus(mrb_state *mrb, mrb_value str) * String#dedup is an alias for String#-@. */ static mrb_value -mrb_str_uminus(mrb_state *mrb, mrb_value str) +str_uminus(mrb_state *mrb, mrb_value str) { if (mrb_frozen_p(mrb_obj_ptr(str))) { return str; @@ -1283,42 +1322,43 @@ mrb_mruby_string_ext_gem_init(mrb_state* mrb) { struct RClass * s = mrb->string_class; - mrb_define_method(mrb, s, "dump", mrb_str_dump, MRB_ARGS_NONE()); - mrb_define_method(mrb, s, "swapcase!", mrb_str_swapcase_bang, MRB_ARGS_NONE()); - mrb_define_method(mrb, s, "swapcase", mrb_str_swapcase, MRB_ARGS_NONE()); - mrb_define_method(mrb, s, "concat", mrb_str_concat_m, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, s, "<<", mrb_str_concat_m, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, s, "count", mrb_str_count, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, s, "tr", mrb_str_tr, MRB_ARGS_REQ(2)); - mrb_define_method(mrb, s, "tr!", mrb_str_tr_bang, MRB_ARGS_REQ(2)); - mrb_define_method(mrb, s, "tr_s", mrb_str_tr_s, MRB_ARGS_REQ(2)); - mrb_define_method(mrb, s, "tr_s!", mrb_str_tr_s_bang, MRB_ARGS_REQ(2)); - mrb_define_method(mrb, s, "squeeze", mrb_str_squeeze, MRB_ARGS_OPT(1)); - mrb_define_method(mrb, s, "squeeze!", mrb_str_squeeze_bang, MRB_ARGS_OPT(1)); - mrb_define_method(mrb, s, "delete", mrb_str_delete, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, s, "delete!", mrb_str_delete_bang, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, s, "start_with?", mrb_str_start_with, MRB_ARGS_REST()); - mrb_define_method(mrb, s, "end_with?", mrb_str_end_with, MRB_ARGS_REST()); - mrb_define_method(mrb, s, "hex", mrb_str_hex, MRB_ARGS_NONE()); - mrb_define_method(mrb, s, "oct", mrb_str_oct, MRB_ARGS_NONE()); - mrb_define_method(mrb, s, "chr", mrb_str_chr, MRB_ARGS_NONE()); - mrb_define_method(mrb, s, "succ", mrb_str_succ, MRB_ARGS_NONE()); - mrb_define_method(mrb, s, "succ!", mrb_str_succ_bang, MRB_ARGS_NONE()); - mrb_define_method(mrb, s, "next", mrb_str_succ, MRB_ARGS_NONE()); - mrb_define_method(mrb, s, "next!", mrb_str_succ_bang, MRB_ARGS_NONE()); - mrb_define_method(mrb, s, "ord", mrb_str_ord, MRB_ARGS_NONE()); - mrb_define_method(mrb, s, "delete_prefix!", mrb_str_del_prefix_bang, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, s, "delete_prefix", mrb_str_del_prefix, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, s, "delete_suffix!", mrb_str_del_suffix_bang, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, s, "delete_suffix", mrb_str_del_suffix, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, s, "casecmp", mrb_str_casecmp, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, s, "casecmp?", mrb_str_casecmp_p, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, s, "+@", mrb_str_uplus, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, s, "-@", mrb_str_uminus, MRB_ARGS_REQ(1)); - - mrb_define_method(mrb, s, "__lines", mrb_str_lines, MRB_ARGS_NONE()); - - mrb_define_method(mrb, mrb->integer_class, "chr", mrb_int_chr, MRB_ARGS_OPT(1)); + mrb_define_method(mrb, s, "dump", mrb_str_dump, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "swapcase!", str_swapcase_bang, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "swapcase", str_swapcase, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "concat", str_concat_m, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "<<", str_concat_m, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "count", str_count, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "tr", str_tr_m, MRB_ARGS_REQ(2)); + mrb_define_method(mrb, s, "tr!", str_tr_bang, MRB_ARGS_REQ(2)); + mrb_define_method(mrb, s, "tr_s", str_tr_s, MRB_ARGS_REQ(2)); + mrb_define_method(mrb, s, "tr_s!", str_tr_s_bang, MRB_ARGS_REQ(2)); + mrb_define_method(mrb, s, "squeeze", str_squeeze_m, MRB_ARGS_OPT(1)); + mrb_define_method(mrb, s, "squeeze!", str_squeeze_bang, MRB_ARGS_OPT(1)); + mrb_define_method(mrb, s, "delete", str_delete_m, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "delete!", str_delete_bang, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "start_with?", str_start_with, MRB_ARGS_REST()); + mrb_define_method(mrb, s, "end_with?", str_end_with, MRB_ARGS_REST()); + mrb_define_method(mrb, s, "hex", str_hex, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "oct", str_oct, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "chr", str_chr, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "succ", str_succ, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "succ!", str_succ_bang, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "next", str_succ, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "next!", str_succ_bang, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "ord", str_ord, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "delete_prefix!", str_del_prefix_bang, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "delete_prefix", str_del_prefix, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "delete_suffix!", str_del_suffix_bang, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "delete_suffix", str_del_suffix, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "casecmp", str_casecmp, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "casecmp?", str_casecmp_p, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "+@", str_uplus, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "-@", str_uminus, MRB_ARGS_REQ(1)); + + mrb_define_method(mrb, s, "__lines", str_lines, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "__codepoints", str_codepoints, MRB_ARGS_NONE()); + + mrb_define_method(mrb, mrb->integer_class, "chr", int_chr, MRB_ARGS_OPT(1)); } void diff --git a/mruby/mrbgems/mruby-struct/mrblib/struct.rb b/mruby/mrbgems/mruby-struct/mrblib/struct.rb index f80c5451..20d9bde8 100644 --- a/mruby/mrbgems/mruby-struct/mrblib/struct.rb +++ b/mruby/mrbgems/mruby-struct/mrblib/struct.rb @@ -45,35 +45,6 @@ def select(&block) ary end - def _inspect(recur_list) - return "#" if recur_list[self.object_id] - recur_list[self.object_id] = true - name = self.class.to_s - if name[0] == "#" - str = "#" - end - - ## - # call-seq: - # struct.to_s -> string - # struct.inspect -> string - # - # Describe the contents of this struct in a string. - # - # 15.2.18.4.10(x) - # - def inspect - self._inspect({}) - end - ## # 15.2.18.4.11(x) # diff --git a/mruby/mrbgems/mruby-struct/src/struct.c b/mruby/mrbgems/mruby-struct/src/struct.c index 6dc0b5b0..757e4daf 100644 --- a/mruby/mrbgems/mruby-struct/src/struct.c +++ b/mruby/mrbgems/mruby-struct/src/struct.c @@ -30,7 +30,7 @@ struct_class(mrb_state *mrb) static void struct_corrupted(mrb_state *mrb) { - mrb_raise(mrb, E_TYPE_ERROR, "corrupted data"); + mrb_raise(mrb, E_TYPE_ERROR, "corrupted struct"); } static mrb_value @@ -45,27 +45,28 @@ struct_s_members(mrb_state *mrb, struct RClass *c) if (!mrb_array_p(members)) { struct_corrupted(mrb); } - break; + return members; } c = c->super; if (c == sclass || c == 0) { mrb_raise(mrb, E_TYPE_ERROR, "uninitialized struct"); } } - return members; } static mrb_value struct_members(mrb_state *mrb, mrb_value s) { - if (!mrb_struct_p(s) || RSTRUCT_LEN(s) == 0) { + if (!mrb_struct_p(s)) { struct_corrupted(mrb); } mrb_value members = struct_s_members(mrb, mrb_obj_class(mrb, s)); - if (RSTRUCT_LEN(s) != RARRAY_LEN(members)) { + mrb_int len = RSTRUCT_LEN(s); + mrb_int mlen = RARRAY_LEN(members); + if (len > 0 && len != mlen) { mrb_raisef(mrb, E_TYPE_ERROR, "struct size differs (%i required %i given)", - RARRAY_LEN(members), RSTRUCT_LEN(s)); + mlen, len); } return members; } @@ -102,13 +103,25 @@ mrb_struct_members(mrb_state *mrb, mrb_value obj) return mrb_struct_s_members_m(mrb, mrb_obj_value(mrb_obj_class(mrb, obj))); } +static mrb_int +num_members(mrb_state *mrb, mrb_value self) +{ + mrb_value members = struct_members(mrb, self); + return RARRAY_LEN(members); +} + static mrb_value mrb_struct_ref(mrb_state *mrb, mrb_value obj) { + mrb_int argc = mrb_get_argc(mrb); + if (argc != 0) { + mrb_argnum_error(mrb, argc, 0, 0); + } mrb_int i = mrb_integer(mrb_proc_cfunc_env_get(mrb, 0)); + mrb_int len = num_members(mrb, obj); mrb_value *ptr = RSTRUCT_PTR(obj); - if (!ptr) return mrb_nil_value(); + if (!ptr || len <= i) return mrb_nil_value(); return ptr[i]; } @@ -126,7 +139,7 @@ mrb_id_attrset(mrb_state *mrb, mrb_sym id) name = mrb_sym_name_len(mrb, id, &len); if (len > ONSTACK_STRLEN_MAX) { - buf = (char *)mrb_malloc(mrb, (size_t)len+1); + buf = (char*)mrb_malloc(mrb, (size_t)len+1); } else { buf = onstack; @@ -145,18 +158,9 @@ static mrb_value mrb_struct_set_m(mrb_state *mrb, mrb_value obj) { mrb_int i = mrb_integer(mrb_proc_cfunc_env_get(mrb, 0)); - mrb_value *ptr; mrb_value val = mrb_get_arg1(mrb); - mrb_struct_modify(mrb, obj); - ptr = RSTRUCT_PTR(obj); - if (ptr == NULL || i >= RSTRUCT_LEN(obj)) { - mrb_ary_set(mrb, obj, i, val); - } - else { - ptr[i] = val; - mrb_field_write_barrier_value(mrb, mrb_basic_ptr(obj), val); - } + mrb_ary_set(mrb, obj, i, val); return val; } @@ -205,6 +209,7 @@ make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass *kl } c = mrb_define_class_under_id(mrb, klass, id, klass); } + MRB_SET_INSTANCE_TT(c, MRB_TT_STRUCT); nstr = mrb_obj_value(c); mrb_iv_set(mrb, nstr, MRB_SYM(__members__), members); @@ -253,55 +258,46 @@ make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass *kl static mrb_value mrb_struct_s_def(mrb_state *mrb, mrb_value klass) { - mrb_value name, rest; + mrb_value name = mrb_nil_value(); const mrb_value *pargv; mrb_int argcnt; - mrb_int i; mrb_value b, st; - mrb_sym id; const mrb_value *argv; mrb_int argc; - name = mrb_nil_value(); mrb_get_args(mrb, "*&", &argv, &argc, &b); - if (argc == 0) { /* special case to avoid crash */ - mrb_argnum_error(mrb, argc, 1, -1); + if (argc == 0) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (given 0, expected 1+)"); } - else { - pargv = argv; - argcnt = argc; - if (argc > 0) { - name = argv[0]; - if (mrb_symbol_p(name)) { - /* 1stArgument:symbol -> name=nil rest=argv[0..n] */ - name = mrb_nil_value(); - } - else { - pargv++; - argcnt--; + pargv = argv; + argcnt = argc; + if (argc > 0 && !mrb_symbol_p(argv[0])) { + /* 1stArgument:!symbol -> name=argv[0] rest=argv[0..n] */ + name = argv[0]; + pargv++; + argcnt--; + } + mrb_value members = mrb_ary_new_from_values(mrb, argcnt, pargv); + for (mrb_int i=0; i= RSTRUCT_LEN(s)) return mrb_nil_value(); return RSTRUCT_PTR(s)[idx]; } @@ -434,19 +432,16 @@ mrb_struct_aref(mrb_state *mrb, mrb_value s) static mrb_value mrb_struct_aset_sym(mrb_state *mrb, mrb_value s, mrb_sym id, mrb_value val) { - mrb_value members, *ptr; + mrb_value members; const mrb_value *ptr_members; mrb_int i, len; members = struct_members(mrb, s); len = RARRAY_LEN(members); - ptr = RSTRUCT_PTR(s); ptr_members = RARRAY_PTR(members); for (i=0; i string + * struct.inspect -> string + * + * Returns a string representation of Data + */ +static mrb_value +mrb_struct_to_s(mrb_state *mrb, mrb_value self) +{ + mrb_value members, ret, cname; + mrb_value *mems; + mrb_int mlen; + + mrb->c->ci->mid = MRB_SYM(inspect); + ret = mrb_str_new_lit(mrb, "#"); + return ret; + } + members = struct_members(mrb, self); + mlen = RARRAY_LEN(members); + mems = RARRAY_PTR(members); + for (mrb_int i=0; i0) mrb_str_cat_lit(mrb, ret, ", "); + mrb_str_cat(mrb, ret, name, len); + mrb_str_cat_lit(mrb, ret, "="); + mrb_str_cat_str(mrb, ret, mrb_inspect(mrb, RARRAY_PTR(self)[i])); + mrb_gc_arena_restore(mrb, ai); + } + mrb_str_cat_lit(mrb, ret, ">"); + + return ret; +} + /* * A Struct is a convenient way to bundle a number of * attributes together, using accessor methods, without having to write @@ -656,7 +697,7 @@ mrb_mruby_struct_gem_init(mrb_state* mrb) { struct RClass *st; st = mrb_define_class(mrb, "Struct", mrb->object_class); - MRB_SET_INSTANCE_TT(st, MRB_TT_STRUCT); + MRB_SET_INSTANCE_TT(st, MRB_TT_UNDEF); mrb_define_class_method(mrb, st, "new", mrb_struct_s_def, MRB_ARGS_ANY()); /* 15.2.18.3.1 */ @@ -667,6 +708,8 @@ mrb_mruby_struct_gem_init(mrb_state* mrb) mrb_define_method(mrb, st, "initialize", mrb_struct_initialize, MRB_ARGS_ANY()); /* 15.2.18.4.8 */ mrb_define_method(mrb, st, "initialize_copy", mrb_struct_init_copy, MRB_ARGS_REQ(1)); /* 15.2.18.4.9 */ mrb_define_method(mrb, st, "eql?", mrb_struct_eql, MRB_ARGS_REQ(1)); /* 15.2.18.4.12(x) */ + mrb_define_method(mrb, st, "to_s", mrb_struct_to_s, MRB_ARGS_NONE()); /* 15.2.18.4.11(x) */ + mrb_define_method(mrb, st, "inspect", mrb_struct_to_s, MRB_ARGS_NONE()); /* 15.2.18.4.10(x) */ mrb_define_method(mrb, st, "size", mrb_struct_len, MRB_ARGS_NONE()); mrb_define_method(mrb, st, "length", mrb_struct_len, MRB_ARGS_NONE()); diff --git a/mruby/mrbgems/mruby-struct/test/struct.rb b/mruby/mrbgems/mruby-struct/test/struct.rb index db0fa56d..384a9206 100644 --- a/mruby/mrbgems/mruby-struct/test/struct.rb +++ b/mruby/mrbgems/mruby-struct/test/struct.rb @@ -119,7 +119,7 @@ c = Struct.new(:m1, :m2, :m3, :m4, :m5, :recur) cc = c.new(1,2,3,4,5,nil) cc.recur = cc - assert_equal "#>", cc.inspect + assert_equal "#>", cc.inspect end assert('Struct#length, Struct#size') do diff --git a/mruby/mrbgems/mruby-test-inline-struct/test/inline.c b/mruby/mrbgems/mruby-test-inline-struct/test/inline.c index a54bf2b0..c92caa5d 100644 --- a/mruby/mrbgems/mruby-test-inline-struct/test/inline.c +++ b/mruby/mrbgems/mruby-test-inline-struct/test/inline.c @@ -56,9 +56,8 @@ istruct_test_test_receive(mrb_state *mrb, mrb_value self) static mrb_value istruct_test_test_receive_direct(mrb_state *mrb, mrb_value self) { - mrb_value is; + mrb_value is = mrb_get_arg1(mrb); struct RClass *klass = mrb_class_get(mrb, "InlineStructTest"); - 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 */ diff --git a/mruby/mrbgems/mruby-test/driver.c b/mruby/mrbgems/mruby-test/driver.c index 0ccba9ea..96ae3e07 100644 --- a/mruby/mrbgems/mruby-test/driver.c +++ b/mruby/mrbgems/mruby-test/driver.c @@ -172,7 +172,7 @@ str_match_p(mrb_state *mrb, if (lbrace && rbrace) { /* expand brace */ - char *ex_pat = (char *)mrb_malloc(mrb, pat_len-2); /* expanded pattern */ + char *ex_pat = (char*)mrb_malloc(mrb, pat_len-2); /* expanded pattern */ char *ex_p = ex_pat; COPY_AND_INC(ex_p, pat, lbrace-pat); diff --git a/mruby/mrbgems/mruby-test/mrbgem.rake b/mruby/mrbgems/mruby-test/mrbgem.rake index 927447b4..c8070dd0 100644 --- a/mruby/mrbgems/mruby-test/mrbgem.rake +++ b/mruby/mrbgems/mruby-test/mrbgem.rake @@ -66,37 +66,29 @@ MRuby::Gem::Specification.new('mruby-test') do |spec| f.puts %Q[void mrb_t_pass_result(mrb_state *dst, mrb_state *src);] f.puts %Q[void GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb_state *mrb) {] unless g.test_rbfiles.empty? - f.puts %Q[ mrb_state *mrb2;] unless g.test_args.empty? f.puts %Q[ mrb_value test_args_hash;] end - f.puts %Q[ int ai;] + f.puts %Q[ mrb_state *mrb2 = mrb_open_core(mrb_default_allocf, NULL);] + f.puts %Q[ if (mrb2 == NULL) {] + f.puts %Q[ fprintf(stderr, "Invalid mrb_state, exiting \%s", __func__);] + f.puts %Q[ exit(EXIT_FAILURE);] + f.puts %Q[ }] + f.puts %Q[ mrb_const_set(mrb2, mrb_obj_value(mrb2->object_class), mrb_intern_lit(mrb2, "GEMNAME"), mrb_str_new(mrb2, "#{g.name}", #{g.name.length}));] + if test_preload.nil? + f.puts %Q[ mrb_load_irep(mrb2, mrbtest_assert_irep);] + else + f.puts %Q[ mrb_load_irep(mrb2, gem_test_irep_#{g.funcname}_preload);] + end + dep_list.each do |d| + f.puts %Q[ GENERATED_TMP_mrb_#{d.funcname}_gem_init(mrb2);] + f.puts %Q[ mrb_state_atexit(mrb2, GENERATED_TMP_mrb_#{d.funcname}_gem_final);] + end + f.puts %Q[ mrb_init_test_driver(mrb2, mrb_test(mrb_gv_get(mrb, mrb_intern_lit(mrb, "$mrbtest_verbose"))));] + f.puts %Q[ ] g.test_rbfiles.count.times do |i| - f.puts %Q[ ai = mrb_gc_arena_save(mrb);] - f.puts %Q[ mrb2 = mrb_open_core(mrb_default_allocf, NULL);] - f.puts %Q[ if (mrb2 == NULL) {] - f.puts %Q[ fprintf(stderr, "Invalid mrb_state, exiting \%s", __func__);] - f.puts %Q[ exit(EXIT_FAILURE);] - f.puts %Q[ }] - dep_list.each do |d| - f.puts %Q[ GENERATED_TMP_mrb_#{d.funcname}_gem_init(mrb2);] - f.puts %Q[ mrb_state_atexit(mrb2, GENERATED_TMP_mrb_#{d.funcname}_gem_final);] - end - f.puts %Q[ mrb_init_test_driver(mrb2, mrb_test(mrb_gv_get(mrb, mrb_intern_lit(mrb, "$mrbtest_verbose"))));] - if test_preload.nil? - f.puts %Q[ mrb_load_irep(mrb2, mrbtest_assert_irep);] - else - f.puts %Q[ mrb_load_irep(mrb2, gem_test_irep_#{g.funcname}_preload);] - end - f.puts %Q[ if (mrb2->exc) {] - f.puts %Q[ mrb_print_error(mrb2);] - f.puts %Q[ mrb_close(mrb2);] - f.puts %Q[ exit(EXIT_FAILURE);] - f.puts %Q[ }] - f.puts %Q[ mrb_const_set(mrb2, mrb_obj_value(mrb2->object_class), mrb_intern_lit(mrb2, "GEMNAME"), mrb_str_new(mrb2, "#{g.name}", #{g.name.length}));] - unless g.test_args.empty? - f.puts %Q[ test_args_hash = mrb_hash_new_capa(mrb, #{g.test_args.length}); ] + f.puts %Q[ test_args_hash = mrb_hash_new_capa(mrb2, #{g.test_args.length}); ] g.test_args.each do |arg_name, arg_value| escaped_arg_name = arg_name.gsub('\\', '\\\\\\\\').gsub('"', '\"') escaped_arg_value = arg_value.gsub('\\', '\\\\\\\\').gsub('"', '\"') @@ -106,14 +98,16 @@ MRuby::Gem::Specification.new('mruby-test') do |spec| end f.puts %Q[ mrb_#{g.funcname}_gem_test(mrb2);] if g.custom_test_init? - f.puts %Q[ mrb_load_irep(mrb2, gem_test_irep_#{g.funcname}_#{i});] + f.puts %Q[ if (mrb2->exc) {] + f.puts %Q[ mrb_print_error(mrb2);] + f.puts %Q[ mrb_close(mrb2);] + f.puts %Q[ exit(EXIT_FAILURE);] + f.puts %Q[ }] f.puts %Q[ ] - - f.puts %Q[ mrb_t_pass_result(mrb, mrb2);] - f.puts %Q[ mrb_close(mrb2);] - f.puts %Q[ mrb_gc_arena_restore(mrb, ai);] end + f.puts %Q[ mrb_t_pass_result(mrb, mrb2);] + f.puts %Q[ mrb_close(mrb2);] end f.puts %Q[}] end @@ -144,14 +138,26 @@ MRuby::Gem::Specification.new('mruby-test') do |spec| f.puts %Q[ * All manual changes will get lost.] f.puts %Q[ */] f.puts %Q[] - f.puts %Q[struct mrb_state;] - f.puts %Q[typedef struct mrb_state mrb_state;] + f.puts %Q[#include ] + f.puts %Q[#include ] + f.puts %Q[#include ] + f.puts %Q[] build.gems.each do |g| f.puts %Q[void GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb_state *mrb);] end f.puts %Q[void mrbgemtest_init(mrb_state* mrb) {] build.gems.each do |g| - f.puts %Q[ GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb);] + if g.skip_test? + f.puts %Q[ do {] + f.puts %Q[ mrb_value asserts = mrb_gv_get(mrb, mrb_intern_lit(mrb, "$asserts"));] + f.puts %Q[ mrb_ary_push(mrb, asserts, mrb_str_new_lit(mrb, ] + f.puts %Q[ "Warn: Skipping tests for gem (#{ + g.name == 'mruby-test' ? 'core' : "mrbgems: #{g.name}" + })"));] + f.puts %Q[ } while (0);] + else + f.puts %Q[ GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb);] + end end f.puts %Q[}] end diff --git a/mruby/mrbgems/mruby-time/mrblib/time.rb b/mruby/mrbgems/mruby-time/mrblib/time.rb deleted file mode 100644 index df0d8ca8..00000000 --- a/mruby/mrbgems/mruby-time/mrblib/time.rb +++ /dev/null @@ -1,9 +0,0 @@ -class Time - def sunday?; wday == 0 end - def monday?; wday == 1 end - def tuesday?; wday == 2 end - def wednesday?; wday == 3 end - def thursday?; wday == 4 end - def friday?; wday == 5 end - def saturday?; wday == 6 end -end diff --git a/mruby/mrbgems/mruby-time/src/time.c b/mruby/mrbgems/mruby-time/src/time.c index 63a9d252..001d46b7 100644 --- a/mruby/mrbgems/mruby-time/src/time.c +++ b/mruby/mrbgems/mruby-time/src/time.c @@ -157,10 +157,11 @@ timegm(struct tm *tm) unsigned int *nday = (unsigned int*) ndays[is_leapyear(tm->tm_year+1900)]; static const int epoch_year = 70; - if(tm->tm_year >= epoch_year) { + if (tm->tm_year >= epoch_year) { for (i = epoch_year; i < tm->tm_year; ++i) r += is_leapyear(i+1900) ? 366*24*60*60 : 365*24*60*60; - } else { + } + else { for (i = tm->tm_year; i < epoch_year; ++i) r -= is_leapyear(i+1900) ? 366*24*60*60 : 365*24*60*60; } @@ -196,16 +197,7 @@ struct mrb_time { struct tm datetime; }; -static const struct mrb_data_type mrb_time_type = { "Time", mrb_free }; - -#ifndef MRB_NO_FLOAT -void mrb_check_num_exact(mrb_state *mrb, mrb_float num); -typedef mrb_float mrb_sec; -#define mrb_sec_value(mrb, sec) mrb_float_value(mrb, sec) -#else -typedef mrb_int mrb_sec; -#define mrb_sec_value(mrb, sec) mrb_int_value(mrb, sec) -#endif +static const struct mrb_data_type time_type = { "Time", mrb_free }; #define MRB_TIME_T_UINT (~(time_t)0 > 0) #define MRB_TIME_MIN ( \ @@ -217,7 +209,6 @@ typedef mrb_int mrb_sec; (sizeof(time_t) <= 4 ? INT32_MAX : INT64_MAX) \ ) -#ifndef MRB_NO_FLOAT /* return true if time_t is fit in mrb_int */ static mrb_bool fixable_time_t_p(time_t v) @@ -228,7 +219,6 @@ fixable_time_t_p(time_t v) if (MRB_INT_MIN > (mrb_int)v) return FALSE; return TRUE; } -#endif static time_t mrb_to_time_t(mrb_state *mrb, mrb_value obj, time_t *usec) @@ -247,16 +237,41 @@ mrb_to_time_t(mrb_state *mrb, mrb_value obj, time_t *usec) } if (usec) { - t = (time_t)f; - *usec = (time_t)llround((f - t) * 1.0e+6); + double tt = floor(f); + if (!isfinite(tt)) goto out_of_range; + t = (time_t)tt; + *usec = (time_t)trunc((f - tt) * 1.0e+6); } else { - t = (time_t)llround(f); + double tt = round(f); + if (!isfinite(tt)) goto out_of_range; + t = (time_t)tt; } } break; #endif /* MRB_NO_FLOAT */ - default: + +#ifdef MRB_USE_BIGINT + case MRB_TT_BIGINT: + { + if (sizeof(time_t) > sizeof(mrb_int)) { + if (MRB_TIME_T_UINT) { + t = (time_t)mrb_bint_as_uint64(mrb, obj); + } + else { + t = (time_t)mrb_bint_as_int64(mrb, obj); + } + if (usec) { *usec = 0; } + break; + } + else { + mrb_int i = mrb_bint_as_int(mrb, obj); + obj = mrb_int_value(mrb, i); + } + } + /* fall through */ +#endif /* MRB_USE_BIGINT */ + case MRB_TT_INTEGER: { mrb_int i = mrb_integer(obj); @@ -270,6 +285,10 @@ mrb_to_time_t(mrb_state *mrb, mrb_value obj, time_t *usec) if (usec) { *usec = 0; } } break; + + default: + mrb_raisef(mrb, E_TYPE_ERROR, "cannot convert %Y to time", obj); + return 0; } return t; @@ -278,10 +297,29 @@ mrb_to_time_t(mrb_state *mrb, mrb_value obj, time_t *usec) mrb_raisef(mrb, E_ARGUMENT_ERROR, "%v out of Time range", obj); /* not reached */ - if (usec) { *usec = 0; } return 0; } +static mrb_value +time_value_from_time_t(mrb_state *mrb, time_t t) +{ + if (!fixable_time_t_p(t)) { +#if defined(MRB_USE_BIGINT) + if (MRB_TIME_T_UINT) { + return mrb_bint_new_uint64(mrb, (uint64_t)t); + } + else { + return mrb_bint_new_int64(mrb, (int64_t)t); + } +#elif !defined(MRB_NO_FLOAT) + return mrb_float_value(mrb, (mrb_float)t); +#else + mrb_raisef(mrb, E_ARGUMENT_ERROR, "Time too big"); +#endif + } + return mrb_int_value(mrb, (mrb_int)t); +} + /** Updates the datetime of a mrb_time based on it's timezone and seconds setting. Returns self on success, NULL of failure. if `dealloc` is set `true`, it frees `self` on error. */ @@ -298,10 +336,8 @@ time_update_datetime(mrb_state *mrb, struct mrb_time *self, int dealloc) aid = localtime_r(&t, &self->datetime); } if (!aid) { - mrb_sec sec = (mrb_sec)t; - if (dealloc) mrb_free(mrb, self); - mrb_raisef(mrb, E_ARGUMENT_ERROR, "%v out of Time range", mrb_sec_value(mrb, sec)); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "%v out of Time range", time_value_from_time_t(mrb, t)); /* not reached */ return NULL; } @@ -313,9 +349,9 @@ time_update_datetime(mrb_state *mrb, struct mrb_time *self, int dealloc) } static mrb_value -mrb_time_wrap(mrb_state *mrb, struct RClass *tc, struct mrb_time *tm) +time_wrap(mrb_state *mrb, struct RClass *tc, struct mrb_time *tm) { - return mrb_obj_value(Data_Wrap_Struct(mrb, tc, &mrb_time_type, tm)); + return mrb_obj_value(Data_Wrap_Struct(mrb, tc, &time_type, tm)); } /* Allocates a mrb_time object and initializes it. */ @@ -324,10 +360,10 @@ time_alloc_time(mrb_state *mrb, time_t sec, time_t usec, enum mrb_timezone timez { struct mrb_time *tm; - tm = (struct mrb_time *)mrb_malloc(mrb, sizeof(struct mrb_time)); + tm = (struct mrb_time*)mrb_malloc(mrb, sizeof(struct mrb_time)); tm->sec = sec; tm->usec = usec; - if (MRB_TIME_T_UINT && tm->usec < 0) { + if (!MRB_TIME_T_UINT && tm->usec < 0) { long sec2 = (long)NDIV(tm->usec,1000000); /* negative div */ tm->usec -= sec2 * 1000000; tm->sec += sec2; @@ -355,15 +391,15 @@ time_alloc(mrb_state *mrb, mrb_value sec, mrb_value usec, enum mrb_timezone time } static mrb_value -mrb_time_make_time(mrb_state *mrb, struct RClass *c, time_t sec, time_t usec, enum mrb_timezone timezone) +time_make_time(mrb_state *mrb, struct RClass *c, time_t sec, time_t usec, enum mrb_timezone timezone) { - return mrb_time_wrap(mrb, c, time_alloc_time(mrb, sec, usec, timezone)); + return time_wrap(mrb, c, time_alloc_time(mrb, sec, usec, timezone)); } static mrb_value -mrb_time_make(mrb_state *mrb, struct RClass *c, mrb_value sec, mrb_value usec, enum mrb_timezone timezone) +time_make(mrb_state *mrb, struct RClass *c, mrb_value sec, mrb_value usec, enum mrb_timezone timezone) { - return mrb_time_wrap(mrb, c, time_alloc(mrb, sec, usec, timezone)); + return time_wrap(mrb, c, time_alloc(mrb, sec, usec, timezone)); } static struct mrb_time* @@ -411,7 +447,7 @@ current_mrb_time(mrb_state *mrb) usec = tv.tv_usec; } #endif - tm = (struct mrb_time *)mrb_malloc(mrb, sizeof(*tm)); + tm = (struct mrb_time*)mrb_malloc(mrb, sizeof(*tm)); *tm = tmzero; tm->sec = sec; tm->usec = usec; tm->timezone = MRB_TIMEZONE_LOCAL; @@ -422,28 +458,28 @@ current_mrb_time(mrb_state *mrb) /* Allocates a new Time object with given millis value. */ static mrb_value -mrb_time_now(mrb_state *mrb, mrb_value self) +time_now(mrb_state *mrb, mrb_value self) { - return mrb_time_wrap(mrb, mrb_class_ptr(self), current_mrb_time(mrb)); + return time_wrap(mrb, mrb_class_ptr(self), current_mrb_time(mrb)); } MRB_API mrb_value -mrb_time_at(mrb_state *mrb, time_t sec, time_t usec, enum mrb_timezone zone) +time_at(mrb_state *mrb, time_t sec, time_t usec, enum mrb_timezone zone) { - return mrb_time_make_time(mrb, mrb_class_get_id(mrb, MRB_SYM(Time)), sec, usec, zone); + return time_make_time(mrb, mrb_class_get_id(mrb, MRB_SYM(Time)), sec, usec, zone); } /* 15.2.19.6.1 */ /* Creates an instance of time at the given time in seconds, etc. */ static mrb_value -mrb_time_at_m(mrb_state *mrb, mrb_value self) +time_at_m(mrb_state *mrb, mrb_value self) { mrb_value sec; mrb_value usec = mrb_fixnum_value(0); mrb_get_args(mrb, "o|o", &sec, &usec); - return mrb_time_make(mrb, mrb_class_ptr(self), sec, usec, MRB_TIMEZONE_LOCAL); + return time_make(mrb, mrb_class_ptr(self), sec, usec, MRB_TIMEZONE_LOCAL); } static struct mrb_time* @@ -460,7 +496,8 @@ time_mktime(mrb_state *mrb, mrb_int ayear, mrb_int amonth, mrb_int aday, #define OUTINT(x) 0 #endif - if (ayear < 1900 || OUTINT(ayear-1900) || + ayear -= 1900; + if (OUTINT(ayear) || amonth < 1 || amonth > 12 || aday < 1 || aday > 31 || ahour < 0 || ahour > 24 || @@ -469,7 +506,7 @@ time_mktime(mrb_state *mrb, mrb_int ayear, mrb_int amonth, mrb_int aday, asec < 0 || asec > 60) mrb_raise(mrb, E_ARGUMENT_ERROR, "argument out of range"); - nowtime.tm_year = (int)(ayear - 1900); + nowtime.tm_year = (int)ayear; nowtime.tm_mon = (int)(amonth - 1); nowtime.tm_mday = (int)aday; nowtime.tm_hour = (int)ahour; @@ -500,13 +537,13 @@ time_mktime(mrb_state *mrb, mrb_int ayear, mrb_int amonth, mrb_int aday, /* 15.2.19.6.2 */ /* Creates an instance of time at the given time in UTC. */ static mrb_value -mrb_time_gm(mrb_state *mrb, mrb_value self) +time_gm(mrb_state *mrb, mrb_value self) { mrb_int ayear = 0, amonth = 1, aday = 1, ahour = 0, amin = 0, asec = 0, ausec = 0; mrb_get_args(mrb, "i|iiiiii", &ayear, &amonth, &aday, &ahour, &amin, &asec, &ausec); - return mrb_time_wrap(mrb, mrb_class_ptr(self), + return time_wrap(mrb, mrb_class_ptr(self), time_mktime(mrb, ayear, amonth, aday, ahour, amin, asec, ausec, MRB_TIMEZONE_UTC)); } @@ -514,13 +551,13 @@ mrb_time_gm(mrb_state *mrb, mrb_value self) /* 15.2.19.6.3 */ /* Creates an instance of time at the given time in local time zone. */ static mrb_value -mrb_time_local(mrb_state *mrb, mrb_value self) +time_local(mrb_state *mrb, mrb_value self) { mrb_int ayear = 0, amonth = 1, aday = 1, ahour = 0, amin = 0, asec = 0, ausec = 0; mrb_get_args(mrb, "i|iiiiii", &ayear, &amonth, &aday, &ahour, &amin, &asec, &ausec); - return mrb_time_wrap(mrb, mrb_class_ptr(self), + return time_wrap(mrb, mrb_class_ptr(self), time_mktime(mrb, ayear, amonth, aday, ahour, amin, asec, ausec, MRB_TIMEZONE_LOCAL)); } @@ -529,7 +566,7 @@ time_get_ptr(mrb_state *mrb, mrb_value time) { struct mrb_time *tm; - tm = DATA_GET_PTR(mrb, time, &mrb_time_type, struct mrb_time); + tm = DATA_GET_PTR(mrb, time, &time_type, struct mrb_time); if (!tm) { mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized time"); } @@ -537,27 +574,27 @@ time_get_ptr(mrb_state *mrb, mrb_value time) } static mrb_value -mrb_time_eq(mrb_state *mrb, mrb_value self) +time_eq(mrb_state *mrb, mrb_value self) { mrb_value other = mrb_get_arg1(mrb); struct mrb_time *tm1, *tm2; mrb_bool eq_p; - tm1 = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); - tm2 = DATA_CHECK_GET_PTR(mrb, other, &mrb_time_type, struct mrb_time); + tm1 = DATA_GET_PTR(mrb, self, &time_type, struct mrb_time); + tm2 = DATA_CHECK_GET_PTR(mrb, other, &time_type, struct mrb_time); eq_p = tm1 && tm2 && tm1->sec == tm2->sec && tm1->usec == tm2->usec; return mrb_bool_value(eq_p); } static mrb_value -mrb_time_cmp(mrb_state *mrb, mrb_value self) +time_cmp(mrb_state *mrb, mrb_value self) { mrb_value other = mrb_get_arg1(mrb); struct mrb_time *tm1, *tm2; - tm1 = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); - tm2 = DATA_CHECK_GET_PTR(mrb, other, &mrb_time_type, struct mrb_time); + tm1 = DATA_GET_PTR(mrb, self, &time_type, struct mrb_time); + tm2 = DATA_CHECK_GET_PTR(mrb, other, &time_type, struct mrb_time); if (!tm1 || !tm2) return mrb_nil_value(); if (tm1->sec > tm2->sec) { return mrb_fixnum_value(1); @@ -582,7 +619,7 @@ int_overflow(mrb_state *mrb, const char *reason) } static mrb_value -mrb_time_plus(mrb_state *mrb, mrb_value self) +time_plus(mrb_state *mrb, mrb_value self) { mrb_value o = mrb_get_arg1(mrb); struct mrb_time *tm; @@ -607,22 +644,22 @@ mrb_time_plus(mrb_state *mrb, mrb_value self) } sec = tm->sec + sec; #endif - return mrb_time_make_time(mrb, mrb_obj_class(mrb, self), sec, tm->usec+usec, tm->timezone); + return time_make_time(mrb, mrb_obj_class(mrb, self), sec, tm->usec+usec, tm->timezone); } static mrb_value -mrb_time_minus(mrb_state *mrb, mrb_value self) +time_minus(mrb_state *mrb, mrb_value self) { mrb_value other = mrb_get_arg1(mrb); struct mrb_time *tm, *tm2; tm = time_get_ptr(mrb, self); - tm2 = DATA_CHECK_GET_PTR(mrb, other, &mrb_time_type, struct mrb_time); + tm2 = DATA_CHECK_GET_PTR(mrb, other, &time_type, struct mrb_time); if (tm2) { #ifndef MRB_NO_FLOAT mrb_float f; - f = (mrb_sec)(tm->sec - tm2->sec) - + (mrb_sec)(tm->usec - tm2->usec) / 1.0e6; + f = (mrb_float)(tm->sec - tm2->sec) + + (mrb_float)(tm->usec - tm2->usec) / 1.0e6; return mrb_float_value(mrb, f); #else mrb_int f; @@ -651,14 +688,14 @@ mrb_time_minus(mrb_state *mrb, mrb_value self) } sec = tm->sec - sec; #endif - return mrb_time_make_time(mrb, mrb_obj_class(mrb, self), sec, tm->usec-usec, tm->timezone); + return time_make_time(mrb, mrb_obj_class(mrb, self), sec, tm->usec-usec, tm->timezone); } } /* 15.2.19.7.30 */ /* Returns week day number of time. */ static mrb_value -mrb_time_wday(mrb_state *mrb, mrb_value self) +time_wday(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; @@ -669,7 +706,7 @@ mrb_time_wday(mrb_state *mrb, mrb_value self) /* 15.2.19.7.31 */ /* Returns year day number of time. */ static mrb_value -mrb_time_yday(mrb_state *mrb, mrb_value self) +time_yday(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; @@ -680,7 +717,7 @@ mrb_time_yday(mrb_state *mrb, mrb_value self) /* 15.2.19.7.32 */ /* Returns year of time. */ static mrb_value -mrb_time_year(mrb_state *mrb, mrb_value self) +time_year(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; @@ -708,7 +745,7 @@ time_zonename(mrb_state *mrb, struct mrb_time *tm, char *buf, size_t len) /* 15.2.19.7.33 */ /* Returns name of time's timezone. */ static mrb_value -mrb_time_zone(mrb_state *mrb, mrb_value self) +time_zone(mrb_state *mrb, mrb_value self) { struct mrb_time *tm = time_get_ptr(mrb, self); if (tm->timezone == MRB_TIMEZONE_UTC) { @@ -722,7 +759,7 @@ mrb_time_zone(mrb_state *mrb, mrb_value self) /* 15.2.19.7.4 */ /* Returns a string that describes the time. */ static mrb_value -mrb_time_asctime(mrb_state *mrb, mrb_value self) +time_asctime(mrb_state *mrb, mrb_value self) { struct mrb_time *tm = time_get_ptr(mrb, self); struct tm *d = &tm->datetime; @@ -750,7 +787,7 @@ mrb_time_asctime(mrb_state *mrb, mrb_value self) /* 15.2.19.7.6 */ /* Returns the day in the month of the time. */ static mrb_value -mrb_time_day(mrb_state *mrb, mrb_value self) +time_day(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; @@ -762,7 +799,7 @@ mrb_time_day(mrb_state *mrb, mrb_value self) /* 15.2.19.7.7 */ /* Returns true if daylight saving was applied for this time. */ static mrb_value -mrb_time_dst_p(mrb_state *mrb, mrb_value self) +time_dst_p(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; @@ -774,37 +811,37 @@ mrb_time_dst_p(mrb_state *mrb, mrb_value self) /* 15.2.19.7.10 */ /* Returns the Time object of the UTC(GMT) timezone. */ static mrb_value -mrb_time_getutc(mrb_state *mrb, mrb_value self) +time_getutc(mrb_state *mrb, mrb_value self) { struct mrb_time *tm, *tm2; tm = time_get_ptr(mrb, self); - tm2 = (struct mrb_time *)mrb_malloc(mrb, sizeof(*tm)); + tm2 = (struct mrb_time*)mrb_malloc(mrb, sizeof(*tm)); *tm2 = *tm; tm2->timezone = MRB_TIMEZONE_UTC; time_update_datetime(mrb, tm2, TRUE); - return mrb_time_wrap(mrb, mrb_obj_class(mrb, self), tm2); + return time_wrap(mrb, mrb_obj_class(mrb, self), tm2); } /* 15.2.19.7.9 */ /* Returns the Time object of the LOCAL timezone. */ static mrb_value -mrb_time_getlocal(mrb_state *mrb, mrb_value self) +time_getlocal(mrb_state *mrb, mrb_value self) { struct mrb_time *tm, *tm2; tm = time_get_ptr(mrb, self); - tm2 = (struct mrb_time *)mrb_malloc(mrb, sizeof(*tm)); + tm2 = (struct mrb_time*)mrb_malloc(mrb, sizeof(*tm)); *tm2 = *tm; tm2->timezone = MRB_TIMEZONE_LOCAL; time_update_datetime(mrb, tm2, TRUE); - return mrb_time_wrap(mrb, mrb_obj_class(mrb, self), tm2); + return time_wrap(mrb, mrb_obj_class(mrb, self), tm2); } /* 15.2.19.7.15 */ /* Returns hour of time. */ static mrb_value -mrb_time_hour(mrb_state *mrb, mrb_value self) +time_hour(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; @@ -815,7 +852,7 @@ mrb_time_hour(mrb_state *mrb, mrb_value self) /* 15.2.19.7.16 */ /* Initializes a time by setting the amount of milliseconds since the epoch.*/ static mrb_value -mrb_time_initialize(mrb_state *mrb, mrb_value self) +time_init(mrb_state *mrb, mrb_value self) { mrb_int ayear = 0, amonth = 1, aday = 1, ahour = 0, amin = 0, asec = 0, ausec = 0; @@ -828,7 +865,7 @@ mrb_time_initialize(mrb_state *mrb, mrb_value self) if (tm) { mrb_free(mrb, tm); } - mrb_data_init(self, NULL, &mrb_time_type); + mrb_data_init(self, NULL, &time_type); if (n == 0) { tm = current_mrb_time(mrb); @@ -836,14 +873,14 @@ mrb_time_initialize(mrb_state *mrb, mrb_value self) else { tm = time_mktime(mrb, ayear, amonth, aday, ahour, amin, asec, ausec, MRB_TIMEZONE_LOCAL); } - mrb_data_init(self, tm, &mrb_time_type); + mrb_data_init(self, tm, &time_type); return self; } /* 15.2.19.7.17(x) */ /* Initializes a copy of this time object. */ static mrb_value -mrb_time_initialize_copy(mrb_state *mrb, mrb_value copy) +time_init_copy(mrb_state *mrb, mrb_value copy) { mrb_value src = mrb_get_arg1(mrb); struct mrb_time *t1, *t2; @@ -852,14 +889,14 @@ mrb_time_initialize_copy(mrb_state *mrb, mrb_value copy) if (!mrb_obj_is_instance_of(mrb, src, mrb_obj_class(mrb, copy))) { mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class"); } - t1 = (struct mrb_time *)DATA_PTR(copy); - t2 = (struct mrb_time *)DATA_PTR(src); + t1 = (struct mrb_time*)DATA_PTR(copy); + t2 = (struct mrb_time*)DATA_PTR(src); if (!t2) { mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized time"); } if (!t1) { - t1 = (struct mrb_time *)mrb_malloc(mrb, sizeof(struct mrb_time)); - mrb_data_init(copy, t1, &mrb_time_type); + t1 = (struct mrb_time*)mrb_malloc(mrb, sizeof(struct mrb_time)); + mrb_data_init(copy, t1, &time_type); } *t1 = *t2; return copy; @@ -868,7 +905,7 @@ mrb_time_initialize_copy(mrb_state *mrb, mrb_value copy) /* 15.2.19.7.18 */ /* Sets the timezone attribute of the Time object to LOCAL. */ static mrb_value -mrb_time_localtime(mrb_state *mrb, mrb_value self) +time_localtime(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; @@ -881,7 +918,7 @@ mrb_time_localtime(mrb_state *mrb, mrb_value self) /* 15.2.19.7.19 */ /* Returns day of month of time. */ static mrb_value -mrb_time_mday(mrb_state *mrb, mrb_value self) +time_mday(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; @@ -892,7 +929,7 @@ mrb_time_mday(mrb_state *mrb, mrb_value self) /* 15.2.19.7.20 */ /* Returns minutes of time. */ static mrb_value -mrb_time_min(mrb_state *mrb, mrb_value self) +time_min(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; @@ -903,7 +940,7 @@ mrb_time_min(mrb_state *mrb, mrb_value self) /* 15.2.19.7.21 (mon) and 15.2.19.7.22 (month) */ /* Returns month of time. */ static mrb_value -mrb_time_mon(mrb_state *mrb, mrb_value self) +time_mon(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; @@ -914,7 +951,7 @@ mrb_time_mon(mrb_state *mrb, mrb_value self) /* 15.2.19.7.23 */ /* Returns seconds in minute of time. */ static mrb_value -mrb_time_sec(mrb_state *mrb, mrb_value self) +time_sec(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; @@ -926,7 +963,7 @@ mrb_time_sec(mrb_state *mrb, mrb_value self) /* 15.2.19.7.24 */ /* Returns a Float with the time since the epoch in seconds. */ static mrb_value -mrb_time_to_f(mrb_state *mrb, mrb_value self) +time_to_f(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; @@ -938,23 +975,18 @@ mrb_time_to_f(mrb_state *mrb, mrb_value self) /* 15.2.19.7.25 */ /* Returns an Integer with the time since the epoch in seconds. */ static mrb_value -mrb_time_to_i(mrb_state *mrb, mrb_value self) +time_to_i(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; tm = time_get_ptr(mrb, self); -#ifndef MRB_NO_FLOAT - if (!fixable_time_t_p(tm->sec)) { - return mrb_float_value(mrb, (mrb_float)tm->sec); - } -#endif - return mrb_int_value(mrb, (mrb_int)tm->sec); + return time_value_from_time_t(mrb, tm->sec); } /* 15.2.19.7.26 */ /* Returns the number of microseconds for time. */ static mrb_value -mrb_time_usec(mrb_state *mrb, mrb_value self) +time_usec(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; @@ -965,7 +997,7 @@ mrb_time_usec(mrb_state *mrb, mrb_value self) /* 15.2.19.7.27 */ /* Sets the timezone attribute of the Time object to UTC. */ static mrb_value -mrb_time_utc(mrb_state *mrb, mrb_value self) +time_utc(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; @@ -978,7 +1010,7 @@ mrb_time_utc(mrb_state *mrb, mrb_value self) /* 15.2.19.7.28 */ /* Returns true if this time is in the UTC timezone false if not. */ static mrb_value -mrb_time_utc_p(mrb_state *mrb, mrb_value self) +time_utc_p(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; @@ -987,7 +1019,7 @@ mrb_time_utc_p(mrb_state *mrb, mrb_value self) } static mrb_value -mrb_time_to_s(mrb_state *mrb, mrb_value self) +time_to_s(mrb_state *mrb, mrb_value self) { struct mrb_time *tm = time_get_ptr(mrb, self); char buf[64]; @@ -1006,7 +1038,7 @@ mrb_time_to_s(mrb_state *mrb, mrb_value self) } static mrb_value -mrb_time_hash(mrb_state *mrb, mrb_value self) +time_hash(mrb_state *mrb, mrb_value self) { struct mrb_time *tm = time_get_ptr(mrb, self); uint32_t hash = mrb_byte_hash((uint8_t*)&tm->sec, sizeof(time_t)); @@ -1015,6 +1047,52 @@ mrb_time_hash(mrb_state *mrb, mrb_value self) return mrb_int_value(mrb, hash); } +#define wday_impl(num) \ + struct mrb_time *tm = time_get_ptr(mrb, self);\ + return mrb_bool_value(tm->datetime.tm_wday == (num)); + +static mrb_value +time_sunday(mrb_state *mrb, mrb_value self) +{ + wday_impl(0); +} + +static mrb_value +time_monday(mrb_state *mrb, mrb_value self) +{ + wday_impl(1); +} + +static mrb_value +time_tuesday(mrb_state *mrb, mrb_value self) +{ + wday_impl(2); +} + +static mrb_value +time_wednesday(mrb_state *mrb, mrb_value self) +{ + wday_impl(3); +} + +static mrb_value +time_thursday(mrb_state *mrb, mrb_value self) +{ + wday_impl(4); +} + +static mrb_value +time_friday(mrb_state *mrb, mrb_value self) +{ + wday_impl(5); +} + +static mrb_value +time_saturday(mrb_state *mrb, mrb_value self) +{ + wday_impl(6); +} + void mrb_mruby_time_gem_init(mrb_state* mrb) { @@ -1023,53 +1101,61 @@ mrb_mruby_time_gem_init(mrb_state* mrb) tc = mrb_define_class(mrb, "Time", mrb->object_class); MRB_SET_INSTANCE_TT(tc, MRB_TT_CDATA); mrb_include_module(mrb, tc, mrb_module_get(mrb, "Comparable")); - mrb_define_class_method(mrb, tc, "at", mrb_time_at_m, MRB_ARGS_ARG(1, 1)); /* 15.2.19.6.1 */ - mrb_define_class_method(mrb, tc, "gm", mrb_time_gm, MRB_ARGS_ARG(1,6)); /* 15.2.19.6.2 */ - mrb_define_class_method(mrb, tc, "local", mrb_time_local, MRB_ARGS_ARG(1,6)); /* 15.2.19.6.3 */ - mrb_define_class_method(mrb, tc, "mktime", mrb_time_local, MRB_ARGS_ARG(1,6));/* 15.2.19.6.4 */ - mrb_define_class_method(mrb, tc, "now", mrb_time_now, MRB_ARGS_NONE()); /* 15.2.19.6.5 */ - mrb_define_class_method(mrb, tc, "utc", mrb_time_gm, MRB_ARGS_ARG(1,6)); /* 15.2.19.6.6 */ - - mrb_define_method(mrb, tc, "hash" , mrb_time_hash , MRB_ARGS_NONE()); - mrb_define_method(mrb, tc, "eql?" , mrb_time_eq , MRB_ARGS_REQ(1)); - mrb_define_method(mrb, tc, "==" , mrb_time_eq , MRB_ARGS_REQ(1)); - mrb_define_method(mrb, tc, "<=>" , mrb_time_cmp , MRB_ARGS_REQ(1)); /* 15.2.19.7.1 */ - mrb_define_method(mrb, tc, "+" , mrb_time_plus , MRB_ARGS_REQ(1)); /* 15.2.19.7.2 */ - mrb_define_method(mrb, tc, "-" , mrb_time_minus , MRB_ARGS_REQ(1)); /* 15.2.19.7.3 */ - mrb_define_method(mrb, tc, "to_s" , mrb_time_to_s , MRB_ARGS_NONE()); - mrb_define_method(mrb, tc, "inspect", mrb_time_to_s , MRB_ARGS_NONE()); - mrb_define_method(mrb, tc, "asctime", mrb_time_asctime, MRB_ARGS_NONE()); /* 15.2.19.7.4 */ - mrb_define_method(mrb, tc, "ctime" , mrb_time_asctime, MRB_ARGS_NONE()); /* 15.2.19.7.5 */ - mrb_define_method(mrb, tc, "day" , mrb_time_day , MRB_ARGS_NONE()); /* 15.2.19.7.6 */ - mrb_define_method(mrb, tc, "dst?" , mrb_time_dst_p , MRB_ARGS_NONE()); /* 15.2.19.7.7 */ - mrb_define_method(mrb, tc, "getgm" , mrb_time_getutc , MRB_ARGS_NONE()); /* 15.2.19.7.8 */ - mrb_define_method(mrb, tc, "getlocal",mrb_time_getlocal,MRB_ARGS_NONE()); /* 15.2.19.7.9 */ - mrb_define_method(mrb, tc, "getutc" , mrb_time_getutc , MRB_ARGS_NONE()); /* 15.2.19.7.10 */ - mrb_define_method(mrb, tc, "gmt?" , mrb_time_utc_p , MRB_ARGS_NONE()); /* 15.2.19.7.11 */ - mrb_define_method(mrb, tc, "gmtime" , mrb_time_utc , MRB_ARGS_NONE()); /* 15.2.19.7.13 */ - mrb_define_method(mrb, tc, "hour" , mrb_time_hour, MRB_ARGS_NONE()); /* 15.2.19.7.15 */ - mrb_define_method(mrb, tc, "localtime", mrb_time_localtime, MRB_ARGS_NONE()); /* 15.2.19.7.18 */ - mrb_define_method(mrb, tc, "mday" , mrb_time_mday, MRB_ARGS_NONE()); /* 15.2.19.7.19 */ - mrb_define_method(mrb, tc, "min" , mrb_time_min, MRB_ARGS_NONE()); /* 15.2.19.7.20 */ - - mrb_define_method(mrb, tc, "mon" , mrb_time_mon, MRB_ARGS_NONE()); /* 15.2.19.7.21 */ - mrb_define_method(mrb, tc, "month", mrb_time_mon, MRB_ARGS_NONE()); /* 15.2.19.7.22 */ - - mrb_define_method(mrb, tc, "sec" , mrb_time_sec, MRB_ARGS_NONE()); /* 15.2.19.7.23 */ - mrb_define_method(mrb, tc, "to_i", mrb_time_to_i, MRB_ARGS_NONE()); /* 15.2.19.7.25 */ + mrb_define_class_method(mrb, tc, "at", time_at_m, MRB_ARGS_ARG(1, 1)); /* 15.2.19.6.1 */ + mrb_define_class_method(mrb, tc, "gm", time_gm, MRB_ARGS_ARG(1,6)); /* 15.2.19.6.2 */ + mrb_define_class_method(mrb, tc, "local", time_local, MRB_ARGS_ARG(1,6)); /* 15.2.19.6.3 */ + mrb_define_class_method(mrb, tc, "mktime", time_local, MRB_ARGS_ARG(1,6));/* 15.2.19.6.4 */ + mrb_define_class_method(mrb, tc, "now", time_now, MRB_ARGS_NONE()); /* 15.2.19.6.5 */ + mrb_define_class_method(mrb, tc, "utc", time_gm, MRB_ARGS_ARG(1,6)); /* 15.2.19.6.6 */ + + mrb_define_method(mrb, tc, "hash" , time_hash , MRB_ARGS_NONE()); + mrb_define_method(mrb, tc, "eql?" , time_eq , MRB_ARGS_REQ(1)); + mrb_define_method(mrb, tc, "==" , time_eq , MRB_ARGS_REQ(1)); + mrb_define_method(mrb, tc, "<=>" , time_cmp , MRB_ARGS_REQ(1)); /* 15.2.19.7.1 */ + mrb_define_method(mrb, tc, "+" , time_plus , MRB_ARGS_REQ(1)); /* 15.2.19.7.2 */ + mrb_define_method(mrb, tc, "-" , time_minus , MRB_ARGS_REQ(1)); /* 15.2.19.7.3 */ + mrb_define_method(mrb, tc, "to_s" , time_to_s , MRB_ARGS_NONE()); + mrb_define_method(mrb, tc, "inspect", time_to_s , MRB_ARGS_NONE()); + mrb_define_method(mrb, tc, "asctime", time_asctime, MRB_ARGS_NONE()); /* 15.2.19.7.4 */ + mrb_define_method(mrb, tc, "ctime" , time_asctime, MRB_ARGS_NONE()); /* 15.2.19.7.5 */ + mrb_define_method(mrb, tc, "day" , time_day , MRB_ARGS_NONE()); /* 15.2.19.7.6 */ + mrb_define_method(mrb, tc, "dst?" , time_dst_p , MRB_ARGS_NONE()); /* 15.2.19.7.7 */ + mrb_define_method(mrb, tc, "getgm" , time_getutc , MRB_ARGS_NONE()); /* 15.2.19.7.8 */ + mrb_define_method(mrb, tc, "getlocal",time_getlocal,MRB_ARGS_NONE()); /* 15.2.19.7.9 */ + mrb_define_method(mrb, tc, "getutc" , time_getutc , MRB_ARGS_NONE()); /* 15.2.19.7.10 */ + mrb_define_method(mrb, tc, "gmt?" , time_utc_p , MRB_ARGS_NONE()); /* 15.2.19.7.11 */ + mrb_define_method(mrb, tc, "gmtime" , time_utc , MRB_ARGS_NONE()); /* 15.2.19.7.13 */ + mrb_define_method(mrb, tc, "hour" , time_hour, MRB_ARGS_NONE()); /* 15.2.19.7.15 */ + mrb_define_method(mrb, tc, "localtime", time_localtime, MRB_ARGS_NONE()); /* 15.2.19.7.18 */ + mrb_define_method(mrb, tc, "mday" , time_mday, MRB_ARGS_NONE()); /* 15.2.19.7.19 */ + mrb_define_method(mrb, tc, "min" , time_min, MRB_ARGS_NONE()); /* 15.2.19.7.20 */ + + mrb_define_method(mrb, tc, "mon" , time_mon, MRB_ARGS_NONE()); /* 15.2.19.7.21 */ + mrb_define_method(mrb, tc, "month", time_mon, MRB_ARGS_NONE()); /* 15.2.19.7.22 */ + + mrb_define_method(mrb, tc, "sec" , time_sec, MRB_ARGS_NONE()); /* 15.2.19.7.23 */ + mrb_define_method(mrb, tc, "to_i", time_to_i, MRB_ARGS_NONE()); /* 15.2.19.7.25 */ #ifndef MRB_NO_FLOAT - mrb_define_method(mrb, tc, "to_f", mrb_time_to_f, MRB_ARGS_NONE()); /* 15.2.19.7.24 */ + mrb_define_method(mrb, tc, "to_f", time_to_f, MRB_ARGS_NONE()); /* 15.2.19.7.24 */ #endif - mrb_define_method(mrb, tc, "usec", mrb_time_usec, MRB_ARGS_NONE()); /* 15.2.19.7.26 */ - mrb_define_method(mrb, tc, "utc" , mrb_time_utc, MRB_ARGS_NONE()); /* 15.2.19.7.27 */ - mrb_define_method(mrb, tc, "utc?", mrb_time_utc_p,MRB_ARGS_NONE()); /* 15.2.19.7.28 */ - mrb_define_method(mrb, tc, "wday", mrb_time_wday, MRB_ARGS_NONE()); /* 15.2.19.7.30 */ - mrb_define_method(mrb, tc, "yday", mrb_time_yday, MRB_ARGS_NONE()); /* 15.2.19.7.31 */ - mrb_define_method(mrb, tc, "year", mrb_time_year, MRB_ARGS_NONE()); /* 15.2.19.7.32 */ - mrb_define_method(mrb, tc, "zone", mrb_time_zone, MRB_ARGS_NONE()); /* 15.2.19.7.33 */ - - mrb_define_method(mrb, tc, "initialize", mrb_time_initialize, MRB_ARGS_REQ(1)); /* 15.2.19.7.16 */ - mrb_define_method(mrb, tc, "initialize_copy", mrb_time_initialize_copy, MRB_ARGS_REQ(1)); /* 15.2.19.7.17 */ + mrb_define_method(mrb, tc, "usec", time_usec, MRB_ARGS_NONE()); /* 15.2.19.7.26 */ + mrb_define_method(mrb, tc, "utc" , time_utc, MRB_ARGS_NONE()); /* 15.2.19.7.27 */ + mrb_define_method(mrb, tc, "utc?", time_utc_p,MRB_ARGS_NONE()); /* 15.2.19.7.28 */ + mrb_define_method(mrb, tc, "wday", time_wday, MRB_ARGS_NONE()); /* 15.2.19.7.30 */ + mrb_define_method(mrb, tc, "yday", time_yday, MRB_ARGS_NONE()); /* 15.2.19.7.31 */ + mrb_define_method(mrb, tc, "year", time_year, MRB_ARGS_NONE()); /* 15.2.19.7.32 */ + mrb_define_method(mrb, tc, "zone", time_zone, MRB_ARGS_NONE()); /* 15.2.19.7.33 */ + + mrb_define_method(mrb, tc, "initialize", time_init, MRB_ARGS_REQ(1)); /* 15.2.19.7.16 */ + mrb_define_method(mrb, tc, "initialize_copy", time_init_copy, MRB_ARGS_REQ(1)); /* 15.2.19.7.17 */ + + mrb_define_method(mrb, tc, "sunday?", time_sunday, MRB_ARGS_NONE()); + mrb_define_method(mrb, tc, "monday?", time_monday, MRB_ARGS_NONE()); + mrb_define_method(mrb, tc, "tuesday?", time_tuesday, MRB_ARGS_NONE()); + mrb_define_method(mrb, tc, "wednesday?", time_wednesday, MRB_ARGS_NONE()); + mrb_define_method(mrb, tc, "thursday?", time_thursday, MRB_ARGS_NONE()); + mrb_define_method(mrb, tc, "friday?", time_friday, MRB_ARGS_NONE()); + mrb_define_method(mrb, tc, "saturday?", time_saturday, MRB_ARGS_NONE()); /* methods not available: diff --git a/mruby/mrblib/array.rb b/mruby/mrblib/array.rb index af3c17cb..6c2b6cfe 100644 --- a/mruby/mrblib/array.rb +++ b/mruby/mrblib/array.rb @@ -101,27 +101,6 @@ def initialize(size=0, obj=nil, &block) self end - def _inspect(recur_list) - size = self.size - return "[]" if size == 0 - return "[...]" if recur_list[self.object_id] - recur_list[self.object_id] = true - ary=[] - i=0 - while i true or false diff --git a/mruby/mrblib/compar.rb b/mruby/mrblib/compar.rb index b39d619f..2ac70ac6 100644 --- a/mruby/mrblib/compar.rb +++ b/mruby/mrblib/compar.rb @@ -49,7 +49,7 @@ def <= other # ISO 15.3.3.2.3 def == other cmp = self <=> other - cmp == 0 + cmp.equal?(0) end ## diff --git a/mruby/mrblib/hash.rb b/mruby/mrblib/hash.rb index bfec4c2a..90b67364 100644 --- a/mruby/mrblib/hash.rb +++ b/mruby/mrblib/hash.rb @@ -181,9 +181,9 @@ def each_value(&block) # # ISO 15.2.13.4.22 def merge(*others, &block) - i=0; len=others.size h = self.dup return h.__merge(*others) unless block + i=0; len=others.size while i" + vals[i]._inspect(recur_list)) - i+=1 - end - "{"+ary.join(", ")+"}" - end - ## - # Return the contents of this hash as a string. - # - def inspect - self._inspect({}) - end - alias to_s inspect - ## # call-seq: # hsh.reject! {| key, value | block } -> hsh or nil diff --git a/mruby/mrblib/kernel.rb b/mruby/mrblib/kernel.rb index 7c3ea942..f72ab610 100644 --- a/mruby/mrblib/kernel.rb +++ b/mruby/mrblib/kernel.rb @@ -39,11 +39,6 @@ def !~(y) !(self =~ y) end - # internal method for inspect - def _inspect(_recur_list) - self.inspect - end - def to_enum(*a) raise NotImplementedError.new("fiber required for enumerator") end diff --git a/mruby/mrblib/numeric.rb b/mruby/mrblib/numeric.rb index 67e76ece..a047f019 100644 --- a/mruby/mrblib/numeric.rb +++ b/mruby/mrblib/numeric.rb @@ -69,7 +69,7 @@ def next # Calls the given block +self+ times. # # ISO 15.2.8.3.22 - def times &block + def times(&block) return to_enum :times unless block i = 0 diff --git a/mruby/oss-fuzz/mruby_proto_fuzzer.cpp b/mruby/oss-fuzz/mruby_proto_fuzzer.cpp index f1ecb44e..2d56b79c 100644 --- a/mruby/oss-fuzz/mruby_proto_fuzzer.cpp +++ b/mruby/oss-fuzz/mruby_proto_fuzzer.cpp @@ -18,7 +18,7 @@ int FuzzRB(const uint8_t *Data, size_t size) { if (!mrb) return 0; - char *code = (char *)malloc(size+1); + char *code = (char*)malloc(size+1); if (!code) return 0; memcpy(code, Data, size); diff --git a/mruby/src/array.c b/mruby/src/array.c index d841a994..67b12ca3 100644 --- a/mruby/src/array.c +++ b/mruby/src/array.c @@ -90,9 +90,7 @@ mrb_ary_new(mrb_state *mrb) static inline void array_copy(mrb_value *dst, const mrb_value *src, mrb_int size) { - mrb_int i; - - for (i = 0; i < size; i++) { + for (mrb_int i = 0; i < size; i++) { dst[i] = src[i]; } } @@ -160,7 +158,7 @@ ary_modify(mrb_state *mrb, struct RArray *a) p = a->as.heap.ptr; len = a->as.heap.len * sizeof(mrb_value); - ptr = (mrb_value *)mrb_malloc(mrb, len); + ptr = (mrb_value*)mrb_malloc(mrb, len); if (p) { array_copy(ptr, p, a->as.heap.len); } @@ -183,13 +181,13 @@ static void ary_make_shared(mrb_state *mrb, struct RArray *a) { if (!ARY_SHARED_P(a) && !ARY_EMBED_P(a)) { - mrb_shared_array *shared = (mrb_shared_array *)mrb_malloc(mrb, sizeof(mrb_shared_array)); + mrb_shared_array *shared = (mrb_shared_array*)mrb_malloc(mrb, sizeof(mrb_shared_array)); mrb_value *ptr = a->as.heap.ptr; mrb_int len = a->as.heap.len; shared->refcnt = 1; if (a->as.heap.aux.capa > len) { - a->as.heap.ptr = shared->ptr = (mrb_value *)mrb_realloc(mrb, ptr, sizeof(mrb_value)*len+1); + a->as.heap.ptr = shared->ptr = (mrb_value*)mrb_realloc(mrb, ptr, sizeof(mrb_value)*len+1); } else { shared->ptr = ptr; @@ -224,7 +222,7 @@ ary_expand_capa(mrb_state *mrb, struct RArray *a, mrb_int len) if (ARY_EMBED_P(a)) { mrb_value *ptr = ARY_EMBED_PTR(a); mrb_int len = ARY_EMBED_LEN(a); - mrb_value *expanded_ptr = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*capa); + mrb_value *expanded_ptr = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value)*capa); ARY_UNSET_EMBED_FLAG(a); array_copy(expanded_ptr, ptr, len); @@ -233,7 +231,7 @@ ary_expand_capa(mrb_state *mrb, struct RArray *a, mrb_int len) a->as.heap.ptr = expanded_ptr; } else if (capa > a->as.heap.aux.capa) { - mrb_value *expanded_ptr = (mrb_value *)mrb_realloc(mrb, a->as.heap.ptr, sizeof(mrb_value)*capa); + mrb_value *expanded_ptr = (mrb_value*)mrb_realloc(mrb, a->as.heap.ptr, sizeof(mrb_value)*capa); a->as.heap.aux.capa = capa; a->as.heap.ptr = expanded_ptr; @@ -262,7 +260,7 @@ ary_shrink_capa(mrb_state *mrb, struct RArray *a) if (capa > a->as.heap.len && capa < a->as.heap.aux.capa) { a->as.heap.aux.capa = capa; - a->as.heap.ptr = (mrb_value *)mrb_realloc(mrb, a->as.heap.ptr, sizeof(mrb_value)*capa); + a->as.heap.ptr = (mrb_value*)mrb_realloc(mrb, a->as.heap.ptr, sizeof(mrb_value)*capa); } } @@ -450,16 +448,16 @@ mrb_ary_times(mrb_state *mrb, mrb_value self) { struct RArray *a1 = mrb_ary_ptr(self); struct RArray *a2; - mrb_value *ptr, sep, tmp; + mrb_value *ptr, arg, tmp; mrb_int times, len1; - mrb_get_args(mrb, "o", &sep); - tmp = mrb_check_string_type(mrb, sep); + arg = mrb_get_arg1(mrb); + tmp = mrb_check_string_type(mrb, arg); if (!mrb_nil_p(tmp)) { return mrb_ary_join(mrb, self, tmp); } - mrb_get_args(mrb, "i", ×); + times = mrb_as_int(mrb, arg); if (times < 0) { mrb_raise(mrb, E_ARGUMENT_ERROR, "negative argument"); } @@ -543,9 +541,13 @@ mrb_ary_push_m(mrb_state *mrb, mrb_value self) mrb_int len, len2; struct RArray *a; + argc = mrb_get_argc(mrb); + if (argc == 1) { + mrb_ary_push(mrb, self, mrb_get_argv(mrb)[0]); + return self; + } a = mrb_ary_ptr(self); ary_modify(mrb, a); - argc = mrb_get_argc(mrb); len = ARY_LEN(a); len2 = len + argc; if (ARY_CAPA(a) < len2) { @@ -612,12 +614,12 @@ mrb_ary_shift(mrb_state *mrb, mrb_value self) static mrb_value mrb_ary_shift_m(mrb_state *mrb, mrb_value self) { - mrb_int n; - if (mrb_get_args(mrb, "|i", &n) == 0) { + if (mrb_get_argc(mrb) == 0) { return mrb_ary_shift(mrb, self); } + mrb_int n = mrb_as_int(mrb, mrb_get_arg1(mrb)); struct RArray *a = mrb_ary_ptr(self); mrb_int len = ARY_LEN(a); mrb_value val; @@ -1026,7 +1028,6 @@ mrb_ary_aset(mrb_state *mrb, mrb_value self) mrb_value v1, v2, v3; mrb_int i, len; - ary_modify(mrb, mrb_ary_ptr(self)); if (mrb_get_argc(mrb) == 2) { const mrb_value *vs = mrb_get_argv(mrb); v1 = vs[0]; v2 = vs[1]; @@ -1061,7 +1062,7 @@ mrb_ary_delete_at(mrb_state *mrb, mrb_value self) mrb_value *ptr; mrb_int len, alen; - mrb_get_args(mrb, "i", &index); + index = mrb_as_int(mrb, mrb_get_arg1(mrb)); alen = ARY_LEN(a); if (index < 0) index += alen; if (index < 0 || alen <= index) return mrb_nil_value(); @@ -1131,9 +1132,8 @@ static mrb_value mrb_ary_index_m(mrb_state *mrb, mrb_value self) { mrb_value obj = mrb_get_arg1(mrb); - mrb_int i; - for (i = 0; i < RARRAY_LEN(self); i++) { + for (mrb_int i = 0; i < RARRAY_LEN(self); i++) { if (mrb_equal(mrb, RARRAY_PTR(self)[i], obj)) { return mrb_int_value(mrb, i); } @@ -1145,9 +1145,10 @@ static mrb_value mrb_ary_rindex_m(mrb_state *mrb, mrb_value self) { mrb_value obj = mrb_get_arg1(mrb); - mrb_int i, len; - for (i = RARRAY_LEN(self) - 1; i >= 0; i--) { + for (mrb_int i = RARRAY_LEN(self) - 1; i >= 0; i--) { + mrb_int len; + if (mrb_equal(mrb, RARRAY_PTR(self)[i], obj)) { return mrb_int_value(mrb, i); } @@ -1173,7 +1174,7 @@ mrb_ary_splat(mrb_state *mrb, mrb_value v) return mrb_ary_new_from_values(mrb, 1, &v); } - ary = mrb_funcall_id(mrb, v, MRB_SYM(to_a), 0); + ary = mrb_funcall_argv(mrb, v, MRB_SYM(to_a), 0, NULL); if (mrb_nil_p(ary)) { return mrb_ary_new_from_values(mrb, 1, &v); } @@ -1245,11 +1246,10 @@ mrb_ary_entry(mrb_value ary, mrb_int n) static mrb_value join_ary(mrb_state *mrb, mrb_value ary, mrb_value sep, mrb_value list) { - mrb_int i; mrb_value result, val, tmp; /* check recursive */ - for (i=0; i 0 && !mrb_nil_p(sep)) { mrb_str_cat_str(mrb, result, sep); } @@ -1328,6 +1328,33 @@ mrb_ary_join_m(mrb_state *mrb, mrb_value ary) return mrb_ary_join(mrb, ary, sep); } +/* + * call-seq: + * ary.to_s -> string + * ary.inspect -> string + * + * Return the contents of this array as a string. + */ +static mrb_value +mrb_ary_to_s(mrb_state *mrb, mrb_value self) +{ + mrb->c->ci->mid = MRB_SYM(inspect); + mrb_value ret = mrb_str_new_lit(mrb, "["); + int ai = mrb_gc_arena_save(mrb); + if (mrb_inspect_recursive_p(mrb, self)) { + mrb_str_cat_lit(mrb, ret, "...]"); + return ret; + } + for (mrb_int i=0; i0) mrb_str_cat_lit(mrb, ret, ", "); + mrb_str_cat_str(mrb, ret, mrb_inspect(mrb, RARRAY_PTR(self)[i])); + mrb_gc_arena_restore(mrb, ai); + } + mrb_str_cat_lit(mrb, ret, "]"); + + return ret; +} + static mrb_value mrb_ary_eq(mrb_state *mrb, mrb_value ary1) { @@ -1406,6 +1433,8 @@ mrb_init_array(mrb_state *mrb) mrb_define_method(mrb, a, "size", mrb_ary_size, MRB_ARGS_NONE()); /* 15.2.12.5.28 */ mrb_define_method(mrb, a, "slice", mrb_ary_aget, MRB_ARGS_ARG(1,1)); /* 15.2.12.5.29 */ mrb_define_method(mrb, a, "unshift", mrb_ary_unshift_m, MRB_ARGS_ANY()); /* 15.2.12.5.30 */ + mrb_define_method(mrb, a, "to_s", mrb_ary_to_s, MRB_ARGS_NONE()); + mrb_define_method(mrb, a, "inspect", mrb_ary_to_s, MRB_ARGS_NONE()); mrb_define_method(mrb, a, "__ary_eq", mrb_ary_eq, MRB_ARGS_REQ(1)); mrb_define_method(mrb, a, "__ary_cmp", mrb_ary_cmp, MRB_ARGS_REQ(1)); diff --git a/mruby/src/backtrace.c b/mruby/src/backtrace.c index 4a0fdc11..816b0e6d 100644 --- a/mruby/src/backtrace.c +++ b/mruby/src/backtrace.c @@ -18,59 +18,54 @@ #include struct backtrace_location { - int32_t lineno; mrb_sym method_id; - const char *filename; + int32_t idx; + const mrb_irep *irep; }; typedef void (*each_backtrace_func)(mrb_state*, const struct backtrace_location*, void*); static const mrb_data_type bt_type = { "Backtrace", mrb_free }; -struct RObject *mrb_unpack_backtrace(mrb_state *mrb, struct RObject *backtrace); - -static void +static uint32_t each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, each_backtrace_func func, void *data) { - if (ciidx >= mrb->c->ciend - mrb->c->cibase) - ciidx = 10; /* ciidx is broken... */ + uint32_t n = 0; for (ptrdiff_t i=ciidx; i >= 0; i--) { struct backtrace_location loc; mrb_callinfo *ci; - const mrb_irep *irep = 0; const mrb_code *pc; - uint32_t idx; ci = &mrb->c->cibase[i]; if (!ci->proc || MRB_PROC_CFUNC_P(ci->proc)) { if (!ci->mid) continue; - loc.lineno = -1; - idx = 0; + loc.irep = NULL; } else { - irep = ci->proc->body.irep; - if (!irep) continue; + loc.irep = ci->proc->body.irep; + if (!loc.irep) continue; + if (!loc.irep->debug_info) continue; if (mrb->c->cibase[i].pc) { pc = &mrb->c->cibase[i].pc[-1]; } else { continue; } - idx = (uint32_t)(pc - irep->iseq); - loc.lineno = mrb_debug_get_line(mrb, irep, idx); + loc.idx = (uint32_t)(pc - loc.irep->iseq); } loc.method_id = ci->mid; - if (loc.lineno == -1) { + if (loc.irep == NULL) { for (ptrdiff_t j=i-1; j >= 0; j--) { ci = &mrb->c->cibase[j]; if (!ci->proc) continue; if (MRB_PROC_CFUNC_P(ci->proc)) continue; - irep = ci->proc->body.irep; + const mrb_irep *irep = ci->proc->body.irep; if (!irep) continue; + if (!irep->debug_info) continue; if (mrb->c->cibase[j].pc) { pc = &mrb->c->cibase[j].pc[-1]; @@ -79,94 +74,15 @@ each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, each_backtrace_func func, void * continue; } - idx = (uint32_t)(pc - irep->iseq); - loc.lineno = mrb_debug_get_line(mrb, irep, idx); - if (loc.lineno > 0) break; + loc.irep = irep; + loc.idx = (uint32_t)(pc - loc.irep->iseq); + break; } } - - loc.filename = mrb_debug_get_filename(mrb, irep, idx); - if (!loc.filename) { - loc.filename = "(unknown)"; - } - - func(mrb, &loc, data); - } -} - -#ifndef MRB_NO_STDIO - -static void -print_backtrace(mrb_state *mrb, struct RObject *exc, struct RArray *backtrace) -{ - mrb_int i; - mrb_int n = (backtrace ? ARY_LEN(backtrace) : 0); - mrb_value *loc, mesg; - - if (n != 0) { - if (n > 1) { - fputs("trace (most recent call last):\n", stderr); - } - for (i=n-1,loc=&ARY_PTR(backtrace)[i]; i>0; i--,loc--) { - if (mrb_string_p(*loc)) { - fprintf(stderr, "\t[%d] ", (int)i); - fwrite(RSTRING_PTR(*loc), (int)RSTRING_LEN(*loc), 1, stderr); - fputc('\n', stderr); - } - } - if (mrb_string_p(*loc)) { - fwrite(RSTRING_PTR(*loc), (int)RSTRING_LEN(*loc), 1, stderr); - fputs(": ", stderr); - } - } - else { - fputs("(unknown):0: ", stderr); - } - - if (exc == mrb->nomem_err) { - static const char nomem[] = "Out of memory (NoMemoryError)\n"; - fwrite(nomem, sizeof(nomem)-1, 1, stderr); - } - else { - mesg = mrb_exc_inspect(mrb, mrb_obj_value(exc)); - fwrite(RSTRING_PTR(mesg), RSTRING_LEN(mesg), 1, stderr); - fputc('\n', stderr); + if (func) func(mrb, &loc, data); + n++; } -} - -/* mrb_print_backtrace - - function to retrieve backtrace information from the last exception. -*/ - -MRB_API void -mrb_print_backtrace(mrb_state *mrb) -{ - if (!mrb->exc || mrb->exc->tt != MRB_TT_EXCEPTION) { - return; - } - - struct RObject *backtrace = ((struct RException*)mrb->exc)->backtrace; - if (backtrace && backtrace->tt != MRB_TT_ARRAY) backtrace = mrb_unpack_backtrace(mrb, backtrace); - print_backtrace(mrb, mrb->exc, (struct RArray*)backtrace); -} -#else - -MRB_API void -mrb_print_backtrace(mrb_state *mrb) -{ -} - -#endif - -static void -count_backtrace_i(mrb_state *mrb, - const struct backtrace_location *loc, - void *data) -{ - int *lenp = (int*)data; - - (*lenp)++; + return n; } static void @@ -186,17 +102,23 @@ packed_backtrace(mrb_state *mrb) { struct RData *backtrace; ptrdiff_t ciidx = mrb->c->ci - mrb->c->cibase; - int len = 0; - int size; - void *ptr; - each_backtrace(mrb, ciidx, count_backtrace_i, &len); - size = len * sizeof(struct backtrace_location); + if (ciidx >= mrb->c->ciend - mrb->c->cibase) + ciidx = mrb->c->ciend - mrb->c->cibase; /* ciidx is broken... */ + + /* count the number of backtraces */ + int len = each_backtrace(mrb, ciidx, NULL, NULL); backtrace = mrb_data_object_alloc(mrb, NULL, NULL, &bt_type); - ptr = mrb_malloc(mrb, size); - backtrace->data = ptr; - backtrace->flags = (uint32_t)len; - each_backtrace(mrb, ciidx, pack_backtrace_i, &ptr); + if (len > 0) { + void *ptr = mrb_malloc(mrb, len * sizeof(struct backtrace_location)); + backtrace->data = ptr; + backtrace->flags = len; + each_backtrace(mrb, ciidx, pack_backtrace_i, &ptr); + } + else { + backtrace->data = NULL; + backtrace->flags = 0; + } return (struct RObject*)backtrace; } @@ -213,6 +135,7 @@ mrb_keep_backtrace(mrb_state *mrb, mrb_value exc) { int ai; + if (mrb->c->ci == NULL) return; if (mrb_exc_ptr(exc)->backtrace) return; ai = mrb_gc_arena_save(mrb); struct RObject *backtrace = packed_backtrace(mrb); @@ -220,7 +143,7 @@ mrb_keep_backtrace(mrb_state *mrb, mrb_value exc) mrb_gc_arena_restore(mrb, ai); } -struct RObject* +static struct RObject* mrb_unpack_backtrace(mrb_state *mrb, struct RObject *backtrace) { const struct backtrace_location *bt; @@ -241,12 +164,17 @@ mrb_unpack_backtrace(mrb_state *mrb, struct RObject *backtrace) for (i = 0; i < n; i++) { const struct backtrace_location *entry = &bt[i]; mrb_value btline; + int32_t lineno; + const char *filename; - if (entry->lineno != -1) {//debug info was available - btline = mrb_format(mrb, "%s:%d", entry->filename, (int)entry->lineno); + if (!mrb_debug_get_position(mrb, entry->irep, entry->idx, &lineno, &filename)) { + btline = mrb_str_new_lit(mrb, "(unknown):0"); + } + else if (lineno != -1) {//debug info was available + btline = mrb_format(mrb, "%s:%d", filename, (int)lineno); } else { //all that was left was the stack frame - btline = mrb_format(mrb, "%s:0", entry->filename); + btline = mrb_format(mrb, "%s:0", filename); } if (entry->method_id != 0) { mrb_str_cat_lit(mrb, btline, ":in "); @@ -280,3 +208,66 @@ mrb_get_backtrace(mrb_state *mrb) { return mrb_obj_value(mrb_unpack_backtrace(mrb, packed_backtrace(mrb))); } + +#ifndef MRB_NO_STDIO + +static void +print_backtrace(mrb_state *mrb, struct RObject *exc, struct RArray *backtrace) +{ + mrb_int i; + mrb_int n = (backtrace ? ARY_LEN(backtrace) : 0); + mrb_value *loc, mesg; + + if (n != 0) { + if (n > 1) { + fputs("trace (most recent call last):\n", stderr); + } + for (i=n-1,loc=&ARY_PTR(backtrace)[i]; i>0; i--,loc--) { + if (mrb_string_p(*loc)) { + fprintf(stderr, "\t[%d] ", (int)i); + fwrite(RSTRING_PTR(*loc), (int)RSTRING_LEN(*loc), 1, stderr); + fputc('\n', stderr); + } + } + if (mrb_string_p(*loc)) { + fwrite(RSTRING_PTR(*loc), (int)RSTRING_LEN(*loc), 1, stderr); + fputs(": ", stderr); + } + } + else { + fputs("(unknown):0: ", stderr); + } + + if (exc == mrb->nomem_err) { + static const char nomem[] = "Out of memory (NoMemoryError)\n"; + fwrite(nomem, sizeof(nomem)-1, 1, stderr); + } + else { + mesg = mrb_exc_inspect(mrb, mrb_obj_value(exc)); + fwrite(RSTRING_PTR(mesg), RSTRING_LEN(mesg), 1, stderr); + fputc('\n', stderr); + } +} + +/* mrb_print_backtrace + + function to retrieve backtrace information from the last exception. +*/ + +MRB_API void +mrb_print_backtrace(mrb_state *mrb) +{ + if (!mrb->exc || mrb->exc->tt != MRB_TT_EXCEPTION) { + return; + } + + struct RObject *backtrace = ((struct RException*)mrb->exc)->backtrace; + if (backtrace && backtrace->tt != MRB_TT_ARRAY) backtrace = mrb_unpack_backtrace(mrb, backtrace); + print_backtrace(mrb, mrb->exc, (struct RArray*)backtrace); +} +#else +MRB_API void +mrb_print_backtrace(mrb_state *mrb) +{ +} +#endif diff --git a/mruby/src/cdump.c b/mruby/src/cdump.c index 251b3984..92eb1f86 100644 --- a/mruby/src/cdump.c +++ b/mruby/src/cdump.c @@ -267,8 +267,9 @@ simple_debug_info(mrb_irep_debug_info *info) //adds filenames in init_syms_code block static int cdump_debug(mrb_state *mrb, const char *name, int n, mrb_irep_debug_info *info, - mrb_value init_syms_code, FILE *fp) + mrb_value init_syms_code, FILE *fp) { + int ai = mrb_gc_arena_save(mrb); char buffer[256]; const char *filename; mrb_int file_len; @@ -281,11 +282,10 @@ cdump_debug(mrb_state *mrb, const char *name, int n, mrb_irep_debug_info *info, len = info->files[0]->line_entry_count; filename = mrb_sym_name_len(mrb, info->files[0]->filename_sym, &file_len); - snprintf(buffer, sizeof(buffer), " %s_debug_file_%d.filename_sym = mrb_intern_lit(mrb,\"", - name, n); + snprintf(buffer, sizeof(buffer), " %s_debug_file_%d.filename_sym = mrb_intern_lit(mrb,", name, n); mrb_str_cat_cstr(mrb, init_syms_code, buffer); - mrb_str_cat_cstr(mrb, init_syms_code, filename); - mrb_str_cat_cstr(mrb, init_syms_code, "\");\n"); + mrb_str_cat_str(mrb, init_syms_code, mrb_str_dump(mrb, mrb_str_new_cstr(mrb, filename))); + mrb_str_cat_cstr(mrb, init_syms_code, ");\n"); switch (info->files[0]->line_type) { case mrb_debug_line_ary: @@ -329,6 +329,7 @@ cdump_debug(mrb_state *mrb, const char *name, int n, mrb_irep_debug_info *info, fprintf(fp, "static mrb_irep_debug_info %s_debug_%d = {\n", name, n); fprintf(fp, "%d, %d, &%s_debug_file_%d_};\n", info->pc_count, info->flen, name, n); + mrb_gc_arena_restore(mrb, ai); return MRB_DUMP_OK; } @@ -380,8 +381,7 @@ cdump_irep_struct(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *fp, } /* dump debug */ if (flags & MRB_DUMP_DEBUG_INFO) { - if(cdump_debug(mrb, name, n, irep->debug_info, - init_syms_code, fp) == MRB_DUMP_OK) { + if (cdump_debug(mrb, name, n, irep->debug_info, init_syms_code, fp) == MRB_DUMP_OK) { debug_available = 1; } } @@ -415,7 +415,7 @@ cdump_irep_struct(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *fp, else { fputs( " NULL,\t\t\t\t\t/* lv */\n", fp); } - if(debug_available) { + if (debug_available) { fprintf(fp, " &%s_debug_%d,\n", name, n); } else { diff --git a/mruby/src/class.c b/mruby/src/class.c index 6cd40cfd..6d0385e3 100644 --- a/mruby/src/class.c +++ b/mruby/src/class.c @@ -219,7 +219,6 @@ static struct mt_tbl* mt_copy(mrb_state *mrb, mt_tbl *t) { mt_tbl *t2; - int i; if (t == NULL) return NULL; if (t->alloc == 0) return NULL; @@ -228,7 +227,7 @@ mt_copy(mrb_state *mrb, mt_tbl *t) t2 = mt_new(mrb); mrb_sym *keys = (mrb_sym*)&t->ptr[t->alloc]; union mt_ptr *vals = t->ptr; - for (i=0; ialloc; i++) { + for (int i=0; ialloc; i++) { if (MT_KEY_P(keys[i])) { mt_put(mrb, t2, MT_KEY_SYM(keys[i]), MT_KEY_FLG(keys[i]), vals[i]); } @@ -265,7 +264,6 @@ MRB_API void mrb_mt_foreach(mrb_state *mrb, struct RClass *c, mrb_mt_foreach_func *fn, void *p) { mt_tbl *t = c->mt; - int i; if (t == NULL) return; if (t->alloc == 0) return; @@ -273,7 +271,7 @@ mrb_mt_foreach(mrb_state *mrb, struct RClass *c, mrb_mt_foreach_func *fn, void * mrb_sym *keys = (mrb_sym*)&t->ptr[t->alloc]; union mt_ptr *vals = t->ptr; - for (i=0; ialloc; i++) { + for (int i=0; ialloc; i++) { mrb_sym key = keys[i]; if (MT_KEY_SYM(key)) { if (fn(mrb, MT_KEY_SYM(key), create_method_value(mrb, key, vals[i]), p) != 0) @@ -287,7 +285,6 @@ void mrb_gc_mark_mt(mrb_state *mrb, struct RClass *c) { mt_tbl *t = c->mt; - int i; if (t == NULL) return; if (t->alloc == 0) return; @@ -295,7 +292,7 @@ mrb_gc_mark_mt(mrb_state *mrb, struct RClass *c) mrb_sym *keys = (mrb_sym*)&t->ptr[t->alloc]; union mt_ptr *vals = t->ptr; - for (i=0; ialloc; i++) { + for (int i=0; ialloc; i++) { if (MT_KEY_P(keys[i]) && (keys[i] & MT_FUNC_P) == 0) { /* Proc pointer */ struct RProc *p = vals[i].proc; mrb_gc_mark(mrb, (struct RBasic*)p); @@ -313,6 +310,15 @@ mrb_gc_mark_mt_size(mrb_state *mrb, struct RClass *c) return (size_t)h->size; } +size_t +mrb_class_mt_memsize(mrb_state *mrb, struct RClass *c) +{ + struct mt_tbl *h = c->mt; + + if (!h) return 0; + return sizeof(struct mt_tbl) + (size_t)h->size * sizeof(mrb_method_t); +} + void mrb_gc_free_mt(mrb_state *mrb, struct RClass *c) { @@ -373,8 +379,8 @@ prepare_singleton_class(mrb_state *mrb, struct RBasic *o) if (o->c->tt == MRB_TT_SCLASS) return; sc = MRB_OBJ_ALLOC(mrb, MRB_TT_SCLASS, mrb->class_class); sc->flags |= MRB_FL_CLASS_IS_INHERITED; - sc->mt = mt_new(mrb); - sc->iv = 0; + sc->mt = NULL; + sc->iv = NULL; if (o->tt == MRB_TT_CLASS) { c = (struct RClass*)o; if (!c->super) { @@ -595,7 +601,7 @@ mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id s = mrb_class_ptr(super); } else { - s = 0; + s = NULL; } check_if_class_or_module(mrb, outer); if (mrb_const_defined_at(mrb, outer, id)) { @@ -678,16 +684,16 @@ mrb_exc_get_id(mrb_state *mrb, mrb_sym name) mrb_value c = mrb_const_get(mrb, mrb_obj_value(mrb->object_class), name); if (!mrb_class_p(c)) { - mrb_raise(mrb, mrb->eException_class, "exception corrupted"); + mrb_raise(mrb, E_EXCEPTION, "exception corrupted"); } exc = e = mrb_class_ptr(c); while (e) { - if (e == mrb->eException_class) + if (e == E_EXCEPTION) return exc; e = e->super; } - return mrb->eException_class; + return E_EXCEPTION; } MRB_API struct RClass* @@ -759,7 +765,13 @@ mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_method_ MRB_CLASS_ORIGIN(c); h = c->mt; - mrb_check_frozen(mrb, c); + if (c->tt == MRB_TT_SCLASS && mrb_frozen_p(c)) { + mrb_value v = mrb_iv_get(mrb, mrb_obj_value(c), MRB_SYM(__attached__)); + mrb_check_frozen_value(mrb, v); + } + else { + mrb_check_frozen(mrb, c); + } if (!h) h = c->mt = mt_new(mrb); if (MRB_METHOD_PROC_P(m)) { struct RProc *p = MRB_METHOD_PROC(m); @@ -1014,10 +1026,7 @@ get_args_v(mrb_state *mrb, mrb_args_format format, void** ptr, va_list *ap) if (i < argc) { pickarg = &argv[i++]; if (needmodify && !mrb_nil_p(*pickarg)) { - if (mrb_immediate_p(*pickarg)) { - mrb_raisef(mrb, E_FROZEN_ERROR, "can't modify frozen %t", *pickarg); - } - mrb_check_frozen(mrb, mrb_obj_ptr(*pickarg)); + mrb_check_frozen_value(mrb, *pickarg); } } else { @@ -1072,8 +1081,8 @@ get_args_v(mrb_state *mrb, mrb_args_format format, void** ptr, va_list *ap) break; case 's': { - const char **ps = 0; - mrb_int *pl = 0; + const char **ps = NULL; + mrb_int *pl = NULL; ps = GET_ARG(const char**); pl = GET_ARG(mrb_int*); @@ -1119,7 +1128,7 @@ get_args_v(mrb_state *mrb, mrb_args_format format, void** ptr, va_list *ap) if (needmodify) goto bad_needmodify; if (pickarg) { if (altmode && mrb_nil_p(*pickarg)) { - *pb = 0; + *pb = NULL; *pl = 0; } else { @@ -1181,7 +1190,7 @@ get_args_v(mrb_state *mrb, mrb_args_format format, void** ptr, va_list *ap) type = GET_ARG(struct mrb_data_type const*); if (pickarg) { if (altmode && mrb_nil_p(*pickarg)) { - *datap = 0; + *datap = NULL; } else { *datap = mrb_data_get_ptr(mrb, *pickarg, type); @@ -1442,7 +1451,8 @@ include_module_at(mrb_state *mrb, struct RClass *c, struct RClass *ins_pos, stru } goto skip; } - } else if (p->tt == MRB_TT_CLASS) { + } + else if (p->tt == MRB_TT_CLASS) { if (!search_super) break; superclass_seen = TRUE; } @@ -1521,15 +1531,7 @@ mrb_prepend_module(mrb_state *mrb, struct RClass *c, struct RClass *m) mrb_check_frozen(mrb, c); if (!(c->flags & MRB_FL_CLASS_IS_PREPENDED)) { - struct RClass *c0; - - if (c->tt == MRB_TT_ICLASS) { - c0 = c->c; - } - else { - c0 = c; - } - origin = MRB_OBJ_ALLOC(mrb, MRB_TT_ICLASS, c0); + origin = MRB_OBJ_ALLOC(mrb, MRB_TT_ICLASS, c); origin->flags |= MRB_FL_CLASS_IS_ORIGIN | MRB_FL_CLASS_IS_INHERITED; origin->super = c->super; c->super = origin; @@ -1755,7 +1757,7 @@ mrb_mc_clear_by_class(mrb_state *mrb, struct RClass *c) struct mrb_cache_entry *mc = mrb->cache; for (int i=0; ic == c || mc->c0 == c) mc->c = 0; + if (mc->c == c || mc->c0 == c) mc->c = NULL; } } @@ -1765,7 +1767,7 @@ mc_clear_by_id(mrb_state *mrb, mrb_sym id) struct mrb_cache_entry *mc = mrb->cache; for (int i=0; imid == id) mc->c = 0; + if (mc->mid == id) mc->c = NULL; } } #endif @@ -1839,7 +1841,7 @@ prepare_name_common(mrb_state *mrb, mrb_sym sym, const char *prefix, const char size_t prefix_len = prefix ? strlen(prefix) : 0; size_t suffix_len = suffix ? strlen(suffix) : 0; size_t name_len = sym_len + prefix_len + suffix_len; - char *buf = name_len > sizeof(onstack) ? (char *)mrb_alloca(mrb, name_len) : onstack; + char *buf = name_len > sizeof(onstack) ? (char*)mrb_alloca(mrb, name_len) : onstack; char *p = buf; if (prefix_len > 0) { @@ -1877,12 +1879,12 @@ mod_attr_define(mrb_state *mrb, mrb_value mod, mrb_value (*accessor)(mrb_state * { struct RClass *c = mrb_class_ptr(mod); const mrb_value *argv; - mrb_int argc, i; + mrb_int argc; int ai; mrb_get_args(mrb, "*", &argv, &argc); ai = mrb_gc_arena_save(mrb); - for (i=0; iiv) { + mrb_raise(mrb, E_TYPE_ERROR, "already initialized class"); + } mrb_get_args(mrb, "|C&", &a, &b); if (!mrb_nil_p(b)) { - mrb_yield_with_class(mrb, b, 1, &c, c, mrb_class_ptr(c)); + mrb_yield_with_class(mrb, b, 1, &obj, obj, c); } - return c; + return obj; } static mrb_value @@ -2486,14 +2495,9 @@ mrb_mod_remove_const(mrb_state *mrb, mrb_value mod) return val; } -static mrb_value -mrb_mod_const_missing(mrb_state *mrb, mrb_value mod) +mrb_value +mrb_const_missing(mrb_state *mrb, mrb_value mod, mrb_sym sym) { - mrb_sym sym; - - mrb_get_args(mrb, "n", &sym); - mrb->c->ci->mid = 0; - if (mrb_class_real(mrb_class_ptr(mod)) != mrb->object_class) { mrb_name_error(mrb, sym, "uninitialized constant %v::%n", mod, sym); } @@ -2504,6 +2508,16 @@ mrb_mod_const_missing(mrb_state *mrb, mrb_value mod) return mrb_nil_value(); } +mrb_value +mrb_mod_const_missing(mrb_state *mrb, mrb_value mod) +{ + mrb_sym sym; + + mrb_get_args(mrb, "n", &sym); + mrb->c->ci->mid = 0; + return mrb_const_missing(mrb, mod, sym); +} + /* 15.2.2.4.34 */ /* * call-seq: @@ -2553,7 +2567,10 @@ mrb_method_added(mrb_state *mrb, struct RClass *c, mrb_sym mid) else { added = MRB_SYM(method_added); } - mrb_funcall_id(mrb, recv, added, 1, mrb_symbol_value(mid)); + if (!mrb_func_basic_p(mrb, recv, added, mrb_do_nothing)) { + mrb_value sym = mrb_symbol_value(mid); + mrb_funcall_argv(mrb, recv, added, 1, &sym); + } } mrb_value @@ -2624,7 +2641,7 @@ static mrb_value mrb_mod_module_function(mrb_state *mrb, mrb_value mod) { const mrb_value *argv; - mrb_int argc, i; + mrb_int argc; mrb_sym mid; mrb_method_t m; struct RClass *rclass; @@ -2641,7 +2658,7 @@ mrb_mod_module_function(mrb_state *mrb, mrb_value mod) /* set PRIVATE method visibility if implemented */ /* mrb_mod_dummy_visibility(mrb, mod); */ - for (i=0; isuper->flags |= MRB_FL_CLASS_IS_ORIGIN; } if (sc->mt) { - dc->mt = mt_copy(mrb, sc->mt); - } - else { - dc->mt = mt_new(mrb); + if (sc->tt == MRB_TT_ICLASS && !(sc->flags & MRB_FL_CLASS_IS_ORIGIN)) { + dc->mt = sc->mt; + } + else { + dc->mt = mt_copy(mrb, sc->mt); + } } dc->super = sc->super; - MRB_SET_INSTANCE_TT(dc, MRB_INSTANCE_TT(sc)); + dc->flags = sc->flags; + dc->flags &= ~MRB_FL_OBJ_IS_FROZEN; } /* 15.3.1.3.16 */ @@ -2738,6 +2758,7 @@ mrb_obj_init_copy(mrb_state *mrb, mrb_value self) static void init_copy(mrb_state *mrb, mrb_value dest, mrb_value obj) { + mrb_assert((mrb_type(dest) == mrb_type(obj))); switch (mrb_type(obj)) { case MRB_TT_ICLASS: copy_class(mrb, dest, obj); @@ -2778,7 +2799,7 @@ init_copy(mrb_state *mrb, mrb_value dest, mrb_value obj) break; } if (!mrb_func_basic_p(mrb, dest, MRB_SYM(initialize_copy), mrb_obj_init_copy)) { - mrb_funcall_id(mrb, dest, MRB_SYM(initialize_copy), 1, obj); + mrb_funcall_argv(mrb, dest, MRB_SYM(initialize_copy), 1, &obj); } } @@ -2899,8 +2920,8 @@ mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args) * def romanToInt(str) * # ... * end - * def method_missing(methId) - * str = methId.to_s + * def method_missing(sym) + * str = sym.to_s * romanToInt(str) * end * end diff --git a/mruby/src/codedump.c b/mruby/src/codedump.c index 1d19354f..292527f2 100644 --- a/mruby/src/codedump.c +++ b/mruby/src/codedump.c @@ -99,10 +99,9 @@ codedump(mrb_state *mrb, const mrb_irep *irep, FILE *out) irep->nregs, irep->nlocals, (int)irep->plen, (int)irep->slen, (int)irep->rlen, (int)irep->ilen); if (irep->lv) { - int i; int head = FALSE; - for (i = 1; i < irep->nlocals; i++) { + for (int i = 1; i < irep->nlocals; i++) { char const *s = mrb_sym_dump(mrb, irep->lv[i - 1]); if (s) { if (!head) { @@ -115,10 +114,9 @@ codedump(mrb_state *mrb, const mrb_irep *irep, FILE *out) } if (irep->clen > 0) { - int i = irep->clen; const struct mrb_irep_catch_handler *e = mrb_irep_catch_handler_table(irep); - for (; i > 0; i--,e++) { + for (int i = irep->clen; i > 0; i--,e++) { uint32_t begin = mrb_irep_catch_handler_unpack(e->begin); uint32_t end = mrb_irep_catch_handler_unpack(e->end); uint32_t target = mrb_irep_catch_handler_unpack(e->target); @@ -173,19 +171,19 @@ codedump(mrb_state *mrb, const mrb_irep *irep, FILE *out) switch (irep->pool[b].tt) { #ifndef MRB_NO_FLOAT case IREP_TT_FLOAT: - fprintf(out, "LOADL\t\tR%d\tL(%d)\t; %f", a, b, (double)irep->pool[b].u.f); + fprintf(out, "LOADL\t\tR%d\tL[%d]\t; %f", a, b, (double)irep->pool[b].u.f); break; #endif case IREP_TT_INT32: - fprintf(out, "LOADL\t\tR%d\tL(%d)\t; %" PRId32, a, b, irep->pool[b].u.i32); + fprintf(out, "LOADL\t\tR%d\tL[%d]\t; %" PRId32, a, b, irep->pool[b].u.i32); break; #ifdef MRB_64BIT case IREP_TT_INT64: - fprintf(out, "LOADL\t\tR%d\tL(%d)\t; %" PRId64, a, b, irep->pool[b].u.i64); + fprintf(out, "LOADL\t\tR%d\tL[%d]\t; %" PRId64, a, b, irep->pool[b].u.i64); break; #endif default: - fprintf(out, "LOADL\t\tR%d\tL(%d)\t", a, b); + fprintf(out, "LOADL\t\tR%d\tL[%d]\t", a, b); break; } print_lv_a(mrb, irep, a, out); @@ -403,13 +401,13 @@ codedump(mrb_state *mrb, const mrb_irep *irep, FILE *out) print_lv_a(mrb, irep, a, out); break; CASE(OP_LAMBDA, BB): - fprintf(out, "LAMBDA\tR%d\tI(%d:%p)\n", a, b, (void*)irep->reps[b]); + fprintf(out, "LAMBDA\tR%d\tI[%d]\n", a, b); break; CASE(OP_BLOCK, BB): - fprintf(out, "BLOCK\t\tR%d\tI(%d:%p)\n", a, b, (void*)irep->reps[b]); + fprintf(out, "BLOCK\t\tR%d\tI[%d]\n", a, b); break; CASE(OP_METHOD, BB): - fprintf(out, "METHOD\tR%d\tI(%d:%p)\n", a, b, (void*)irep->reps[b]); + fprintf(out, "METHOD\tR%d\tI[%d]\n", a, b); break; CASE(OP_RANGE_INC, B): fprintf(out, "RANGE_INC\tR%d\n", a); @@ -499,12 +497,12 @@ codedump(mrb_state *mrb, const mrb_irep *irep, FILE *out) break; CASE(OP_SYMBOL, BB): mrb_assert((irep->pool[b].tt&IREP_TT_NFLAG)==0); - fprintf(out, "SYMBOL\tR%d\tL(%d)\t; %s", a, b, irep->pool[b].u.str); + fprintf(out, "SYMBOL\tR%d\tL[%d]\t; %s", a, b, irep->pool[b].u.str); print_lv_a(mrb, irep, a, out); break; CASE(OP_STRING, BB): mrb_assert((irep->pool[b].tt&IREP_TT_NFLAG)==0); - fprintf(out, "STRING\tR%d\tL(%d)\t; %s", a, b, irep->pool[b].u.str); + fprintf(out, "STRING\tR%d\tL[%d]\t; %s", a, b, irep->pool[b].u.str); print_lv_a(mrb, irep, a, out); break; CASE(OP_STRCAT, B): @@ -537,11 +535,11 @@ codedump(mrb_state *mrb, const mrb_irep *irep, FILE *out) print_lv_a(mrb, irep, a, out); break; CASE(OP_EXEC, BB): - fprintf(out, "EXEC\t\tR%d\tI(%d:%p)", a, b, (void*)irep->reps[b]); + fprintf(out, "EXEC\t\tR%d\tI[%d]", a, b); print_lv_a(mrb, irep, a, out); break; CASE(OP_SCLASS, B): - fprintf(out, "SCLASS\t\tR%d\t", a); + fprintf(out, "SCLASS\tR%d\t", a); print_lv_a(mrb, irep, a, out); break; CASE(OP_TCLASS, B): @@ -553,7 +551,7 @@ codedump(mrb_state *mrb, const mrb_irep *irep, FILE *out) fprintf(out, "ERR\t\t%s\n", irep->pool[a].u.str); } else { - fprintf(out, "ERR\tL(%d)\n", a); + fprintf(out, "ERR\tL[%d]\n", a); } break; CASE(OP_EXCEPT, B): @@ -620,11 +618,9 @@ codedump(mrb_state *mrb, const mrb_irep *irep, FILE *out) static void codedump_recur(mrb_state *mrb, const mrb_irep *irep, FILE *out) { - int i; - codedump(mrb, irep, out); if (irep->reps) { - for (i=0; irlen; i++) { + for (int i=0; irlen; i++) { codedump_recur(mrb, irep->reps[i], out); } } @@ -634,6 +630,7 @@ void mrb_codedump_all_file(mrb_state *mrb, struct RProc *proc, FILE *out) { codedump_recur(mrb, proc->body.irep, out); + fflush(out); } #endif diff --git a/mruby/src/debug.c b/mruby/src/debug.c index 11af6fcf..c9c132e7 100644 --- a/mruby/src/debug.c +++ b/mruby/src/debug.c @@ -47,7 +47,7 @@ mrb_packed_int_len(uint32_t num) } size_t -mrb_packed_int_encode(uint32_t num, uint8_t *p, uint8_t *pend) +mrb_packed_int_encode(uint32_t num, uint8_t *p) { size_t llen = 0; @@ -55,7 +55,7 @@ mrb_packed_int_encode(uint32_t num, uint8_t *p, uint8_t *pend) uint8_t byte = num & 0x7f; num >>= 7; if (num != 0) byte |= 0x80; - if (p < pend) *p++ = byte; + *p++ = byte; llen++; } while (num != 0); @@ -77,15 +77,46 @@ mrb_packed_int_decode(const uint8_t *p, const uint8_t **newpos) return n; } +static char const* +debug_get_filename(mrb_state *mrb, mrb_irep_debug_info_file* f) +{ + if (f == NULL) return NULL; + return mrb_sym_name_len(mrb, f->filename_sym, NULL); +} + +static int32_t +debug_get_line(mrb_state *mrb, mrb_irep_debug_info_file* f, uint32_t pc) +{ + if (f == NULL) return -1; + switch (f->line_type) { + case mrb_debug_line_ary: + case mrb_debug_line_flat_map: + default: + break; + + case mrb_debug_line_packed_map: + { + 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); + line_diff = mrb_packed_int_decode(p, &p); + if (pc < pos) break; + line += line_diff; + } + return line; + } + } + return -1; +} + MRB_API char const* mrb_debug_get_filename(mrb_state *mrb, const mrb_irep *irep, uint32_t pc) { if (irep && pc < irep->ilen) { - mrb_irep_debug_info_file* f = NULL; if (!irep->debug_info) return NULL; - else if ((f = get_file(irep->debug_info, pc))) { - return mrb_sym_name_len(mrb, f->filename_sym, NULL); - } + return debug_get_filename(mrb, get_file(irep->debug_info, pc)); } return NULL; } @@ -94,60 +125,27 @@ MRB_API int32_t mrb_debug_get_line(mrb_state *mrb, const mrb_irep *irep, uint32_t pc) { if (irep && pc < irep->ilen) { - mrb_irep_debug_info_file* f = NULL; - if (!irep->debug_info) { - return -1; - } - else if ((f = get_file(irep->debug_info, pc))) { - switch (f->line_type) { - case mrb_debug_line_ary: - mrb_assert(f->start_pos <= pc && pc < (f->start_pos + f->line_entry_count)); - return f->lines.ary[pc - f->start_pos]; - - case mrb_debug_line_flat_map: { - /* get upper bound */ - 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; - const mrb_irep_debug_info_line *it = ret + step; - if (!(pc < it->start_pos)) { - ret = it + 1; - count -= step + 1; - } - else { count = step; } - } - - --ret; - - /* check line entry pointer range */ - mrb_assert(f->lines.flat_map <= ret && ret < (f->lines.flat_map + f->line_entry_count)); - /* check pc range */ - mrb_assert(ret->start_pos <= pc && - pc < (((uint32_t)(ret + 1 - f->lines.flat_map) < f->line_entry_count) - ? (ret+1)->start_pos : irep->debug_info->pc_count)); - - return ret->line; - } - - case mrb_debug_line_packed_map: { - 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); - line_diff = mrb_packed_int_decode(p, &p); - if (pc < pos) break; - line += line_diff; - } - return line; - } - } - } + if (!irep->debug_info) return -1; + return debug_get_line(mrb, get_file(irep->debug_info, pc), pc); } return -1; } +MRB_API mrb_bool +mrb_debug_get_position(mrb_state *mrb, const mrb_irep *irep, uint32_t pc, int32_t *lp, const char **fp) +{ + if (irep && pc < irep->ilen && irep->debug_info) { + mrb_irep_debug_info_file *f = get_file(irep->debug_info, pc); + *lp = debug_get_line(mrb, f, pc); + if (*lp > 0) { + *fp = debug_get_filename(mrb, f); + if (*fp) return TRUE; + } + } + *lp = -1; *fp = NULL; + return FALSE; +} + MRB_API mrb_irep_debug_info* mrb_debug_info_alloc(mrb_state *mrb, mrb_irep *irep) { @@ -155,7 +153,7 @@ mrb_debug_info_alloc(mrb_state *mrb, mrb_irep *irep) mrb_irep_debug_info *ret; mrb_assert(!irep->debug_info); - ret = (mrb_irep_debug_info *)mrb_malloc(mrb, sizeof(*ret)); + ret = (mrb_irep_debug_info*)mrb_malloc(mrb, sizeof(*ret)); *ret = initial; irep->debug_info = ret; return ret; @@ -200,7 +198,7 @@ mrb_debug_info_append_file(mrb_state *mrb, mrb_irep_debug_info *d, uint16_t prev_line = 0; uint32_t prev_pc = 0; size_t packed_size = 0; - uint8_t *p, *pend; + uint8_t *p; for (i = 0; i < file_pc_count; i++) { if (lines[start_pos + i] == prev_line) continue; @@ -210,13 +208,12 @@ mrb_debug_info_append_file(mrb_state *mrb, mrb_irep_debug_info *d, prev_line = lines[start_pos + i]; } 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++) { if (lines[start_pos + i] == prev_line) continue; - p += mrb_packed_int_encode(start_pos+i-prev_pc, p, pend); + p += mrb_packed_int_encode(start_pos+i-prev_pc, p); prev_pc = start_pos + i; - p += mrb_packed_int_encode(lines[start_pos + i]-prev_line, p, pend); + p += mrb_packed_int_encode(lines[start_pos + i]-prev_line, p); prev_line = lines[start_pos + i]; } f->line_entry_count = (uint32_t)packed_size; diff --git a/mruby/src/dump.c b/mruby/src/dump.c index c0ad4b68..093061ba 100644 --- a/mruby/src/dump.c +++ b/mruby/src/dump.c @@ -452,7 +452,7 @@ get_filename_table_size(mrb_state *mrb, const mrb_irep *irep, mrb_sym **fp, uint if (find_filename_index(filenames, *lp, file->filename_sym) == -1) { /* register filename */ *lp += 1; - *fp = filenames = (mrb_sym *)mrb_realloc(mrb, filenames, sizeof(mrb_sym) * (*lp)); + *fp = filenames = (mrb_sym*)mrb_realloc(mrb, filenames, sizeof(mrb_sym) * (*lp)); filenames[*lp - 1] = file->filename_sym; /* filename */ @@ -557,7 +557,7 @@ write_section_debug(mrb_state *mrb, const mrb_irep *irep, uint8_t *cur, mrb_sym return MRB_DUMP_INVALID_ARGUMENT; } - header = (struct rite_section_debug_header *)bin; + header = (struct rite_section_debug_header*)bin; cur += sizeof(struct rite_section_debug_header); section_size += sizeof(struct rite_section_debug_header); @@ -728,7 +728,7 @@ write_section_lv(mrb_state *mrb, const mrb_irep *irep, uint8_t *start, mrb_sym c static int write_rite_binary_header(mrb_state *mrb, size_t binary_size, uint8_t *bin, uint8_t flags) { - struct rite_binary_header *header = (struct rite_binary_header *)bin; + struct rite_binary_header *header = (struct rite_binary_header*)bin; memcpy(header->binary_ident, RITE_BINARY_IDENT, sizeof(header->binary_ident)); memcpy(header->major_version, RITE_BINARY_MAJOR_VER, sizeof(header->major_version)); @@ -767,8 +767,8 @@ lv_defined_p(const mrb_irep *irep) return FALSE; } -static int -dump_irep(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size) +int +mrb_dump_irep(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size) { int result = MRB_DUMP_GENERAL_FAILURE; size_t malloc_size; @@ -855,12 +855,6 @@ dump_irep(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, uint8_t **bin, si return result; } -int -mrb_dump_irep(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size) -{ - return dump_irep(mrb, irep, flags, bin, bin_size); -} - #ifndef MRB_NO_STDIO int @@ -874,7 +868,7 @@ mrb_dump_irep_binary(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE* return MRB_DUMP_INVALID_ARGUMENT; } - result = dump_irep(mrb, irep, flags, &bin, &bin_size); + result = mrb_dump_irep(mrb, irep, flags, &bin, &bin_size); if (result == MRB_DUMP_OK) { if (fwrite(bin, sizeof(bin[0]), bin_size, fp) != bin_size) { result = MRB_DUMP_WRITE_FAULT; @@ -895,7 +889,7 @@ mrb_dump_irep_cfunc(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *f if (fp == NULL || initname == NULL || initname[0] == '\0') { return MRB_DUMP_INVALID_ARGUMENT; } - result = dump_irep(mrb, irep, flags, &bin, &bin_size); + result = mrb_dump_irep(mrb, irep, flags, &bin, &bin_size); if (result == MRB_DUMP_OK) { if (fprintf(fp, "#include \n") < 0) { /* for uint8_t under at least Darwin */ mrb_free(mrb, bin); diff --git a/mruby/src/error.c b/mruby/src/error.c index a0e23fad..7f6d07a6 100644 --- a/mruby/src/error.c +++ b/mruby/src/error.c @@ -208,7 +208,7 @@ mrb_exc_raise(mrb_state *mrb, mrb_value exc) mrb->exc = mrb_obj_ptr(exc); } else { - if (!mrb_obj_is_kind_of(mrb, exc, mrb->eException_class)) { + if (mrb_type(exc) != MRB_TT_EXCEPTION) { mrb_raise(mrb, E_TYPE_ERROR, "exception object expected"); } mrb_exc_set(mrb, exc); @@ -443,69 +443,40 @@ mrb_warn(mrb_state *mrb, const char *fmt, ...) } MRB_API mrb_noreturn void -mrb_bug(mrb_state *mrb, const char *fmt, ...) +mrb_bug(mrb_state *mrb, const char *mesg) { #ifndef MRB_NO_STDIO - va_list ap; - mrb_value str; - - va_start(ap, fmt); - str = mrb_vformat(mrb, fmt, ap); fputs("bug: ", stderr); - fwrite(RSTRING_PTR(str), RSTRING_LEN(str), 1, stderr); - va_end(ap); + fputs(mesg, stderr); + fputs("\n", stderr); #endif exit(EXIT_FAILURE); } -MRB_API mrb_value -mrb_make_exception(mrb_state *mrb, mrb_int argc, const mrb_value *argv) +mrb_value +mrb_make_exception(mrb_state *mrb, mrb_value exc, mrb_value mesg) { - mrb_value mesg; - int n; - - mesg = mrb_nil_value(); - switch (argc) { - case 0: - break; - case 1: - if (mrb_nil_p(argv[0])) - break; - if (mrb_string_p(argv[0])) { - mesg = mrb_exc_new_str(mrb, E_RUNTIME_ERROR, argv[0]); - break; - } - n = 0; - goto exception_call; - - case 2: - case 3: - n = 1; -exception_call: - { - mrb_sym exc = MRB_SYM(exception); - if (mrb_respond_to(mrb, argv[0], exc)) { - mesg = mrb_funcall_argv(mrb, argv[0], exc, n, argv+1); - } - else { - /* undef */ - mrb_raise(mrb, E_TYPE_ERROR, "exception class/object expected"); - } - } + mrb_int n = 1; - break; - default: - mrb_argnum_error(mrb, argc, 0, 3); - break; + if (mrb_nil_p(mesg)) { + n = 0; } - if (argc > 0) { - if (!mrb_obj_is_kind_of(mrb, mesg, mrb->eException_class)) - mrb_raise(mrb, mrb->eException_class, "exception object expected"); - if (argc > 2) - set_backtrace(mrb, mesg, argv[2]); + if (mrb_class_p(exc)) { + exc = mrb_funcall_argv(mrb, exc, MRB_SYM(new), n, &mesg); } - - return mesg; + else if (mrb_exception_p(exc)) { + if (n > 0) { + exc = mrb_obj_clone(mrb, exc); + mrb_exc_mesg_set(mrb, mrb_exc_ptr(exc), mesg); + } + } + else { + mrb_raise(mrb, E_TYPE_ERROR, "exception class/object expected"); + } + if (mrb_type(exc) != MRB_TT_EXCEPTION) { + mrb_raise(mrb, E_EXCEPTION, "exception object expected"); + } + return exc; } MRB_API mrb_noreturn void @@ -542,10 +513,32 @@ mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_value args, char const* fmt, mrb_exc_raise(mrb, exc); } +static mrb_noreturn void +frozen_error(mrb_state *mrb, mrb_value v) +{ + mrb_raisef(mrb, E_FROZEN_ERROR, "can't modify frozen %T", v); +} + MRB_API mrb_noreturn void mrb_frozen_error(mrb_state *mrb, void *frozen_obj) { - mrb_raisef(mrb, E_FROZEN_ERROR, "can't modify frozen %t", mrb_obj_value(frozen_obj)); + frozen_error(mrb, mrb_obj_value(frozen_obj)); +} + +MRB_API void +mrb_check_frozen(mrb_state *mrb, void *o) +{ + if (mrb_frozen_p((struct RBasic*)o)) { + mrb_frozen_error(mrb, o); + } +} + +MRB_API void +mrb_check_frozen_value(mrb_state *mrb, mrb_value v) +{ + if (mrb_immediate_p(v) || mrb_frozen_p(mrb_basic_ptr(v))) { + frozen_error(mrb, v); + } } MRB_API mrb_noreturn void @@ -564,7 +557,7 @@ mrb_argnum_error(mrb_state *mrb, mrb_int argc, int min, int max) void mrb_core_init_printabort(void); int -mrb_core_init_protect(mrb_state *mrb, void (*body)(mrb_state *, void *), void *opaque) +mrb_core_init_protect(mrb_state *mrb, void (*body)(mrb_state*, void*), void *opaque) { struct mrb_jmpbuf *prev_jmp = mrb->jmp; struct mrb_jmpbuf c_jmp; @@ -649,6 +642,24 @@ mrb_print_error(mrb_state *mrb) #endif } +/* clear error status in the mrb_state structure */ +MRB_API void +mrb_clear_error(mrb_state *mrb) +{ + mrb->exc = NULL; +} + +/* returns TRUE if error in the previous call; internally calls mrb_clear_error() */ +MRB_API mrb_bool +mrb_check_error(mrb_state *mrb) +{ + if (mrb->exc) { + mrb_clear_error(mrb); + return TRUE; + } + return FALSE; +} + void mrb_init_exception(mrb_state *mrb) { @@ -665,8 +676,8 @@ mrb_init_exception(mrb_state *mrb) mrb_define_method(mrb, exception, "set_backtrace", exc_set_backtrace, MRB_ARGS_REQ(1)); mrb->eStandardError_class = mrb_define_class(mrb, "StandardError", mrb->eException_class); /* 15.2.23 */ - mrb_define_class(mrb, "RuntimeError", mrb->eStandardError_class); /* 15.2.28 */ - script_error = mrb_define_class(mrb, "ScriptError", mrb->eException_class); /* 15.2.37 */ + mrb_define_class(mrb, "RuntimeError", E_STANDARD_ERROR); /* 15.2.28 */ + script_error = mrb_define_class(mrb, "ScriptError", exception); /* 15.2.37 */ mrb_define_class(mrb, "SyntaxError", script_error); /* 15.2.38 */ stack_error = mrb_define_class(mrb, "SystemStackError", exception); mrb->stack_err = mrb_obj_ptr(mrb_exc_new_lit(mrb, stack_error, "stack level too deep")); diff --git a/mruby/src/etc.c b/mruby/src/etc.c index 83419223..0c266245 100644 --- a/mruby/src/etc.c +++ b/mruby/src/etc.c @@ -71,7 +71,7 @@ mrb_obj_to_sym(mrb_state *mrb, mrb_value name) return 0; /* not reached */ } -#ifndef MRB_NO_FLOAT +#if !defined(MRB_NO_FLOAT) && !defined(MRB_NAN_BOXING) static mrb_int mrb_float_id(mrb_float f) { diff --git a/mruby/src/fmt_fp.c b/mruby/src/fmt_fp.c index 7c5b01a9..3eed1177 100644 --- a/mruby/src/fmt_fp.c +++ b/mruby/src/fmt_fp.c @@ -100,7 +100,8 @@ mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, ch if (signbit(f)) { *s++ = '-'; f = -f; - } else if (sign) { + } + else if (sign) { *s++ = sign; } buf_remaining -= (int)(s - buf); // Adjust for sign @@ -112,7 +113,8 @@ mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, ch *s++ = 'N' ^ uc; *s++ = 'F' ^ uc; goto ret; - } else if (isnan(f)) { + } + else if (isnan(f)) { *s++ = 'N' ^ uc; *s++ = 'A' ^ uc; *s++ = 'N' ^ uc; @@ -142,10 +144,12 @@ mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, ch e = 0; if (fmt == 'e') { e_sign = '+'; - } else if (fmt == 'f') { + } + else if (fmt == 'f') { num_digits = prec + 1; } - } else if (f < 1.0) { // f < 1.0 + } + else if (f < 1.0) { // f < 1.0 char first_dig = '0'; if (f >= FLT_ROUND_TO_ONE) { first_dig = '1'; @@ -165,7 +169,8 @@ mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, ch if (e == 0) { e_sign_char = '+'; } - } else { + } + else { e++; f *= 10.0; } @@ -194,7 +199,8 @@ mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, ch num_digits--; } } - } else { + } + else { // For e & g formats, we'll be printing the exponent, so set the // sign. e_sign = e_sign_char; @@ -207,7 +213,8 @@ mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, ch } } } - } else { + } + else { // Build positive exponent for (e = 0, e1 = FLT_DECEXP; e1; e1 >>= 1, pos_pow++, neg_pow++) { if (*pos_pow <= f) { @@ -223,7 +230,8 @@ mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, ch if (fmt == 'f') { if (e >= buf_remaining) { fmt = 'e'; - } else if ((e + prec + 2) > buf_remaining) { + } + else if ((e + prec + 2) > buf_remaining) { prec = buf_remaining - e - 2; if (prec < 0) { // This means no decimal point, so we can add one back @@ -245,7 +253,8 @@ mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, ch if (fmt == 'f') { dec = e; num_digits = prec + e + 1; - } else { + } + else { e_sign = '+'; } } @@ -267,10 +276,9 @@ mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, ch if (fmt == 'e') { num_digits = prec + 1; - } else if (fmt == 'g') { - if (prec == 0) { - prec = 1; - } + if (prec == 0) prec = 1; + } + else if (fmt == 'g') { num_digits = prec; } @@ -318,7 +326,8 @@ mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, ch rs[1] = '0'; if (e_sign == '-') { e--; - } else { + } + else { e++; } } @@ -356,8 +365,8 @@ mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, ch *s++ = '0' + (e / 10); *s++ = '0' + (e % 10); } - *s = '\0'; + *s = '\0'; return (int)(s - buf); } #endif diff --git a/mruby/src/gc.c b/mruby/src/gc.c index f1b50ad7..3543bb76 100644 --- a/mruby/src/gc.c +++ b/mruby/src/gc.c @@ -138,49 +138,6 @@ typedef struct { } as; } RVALUE; -#ifdef GC_PROFILE -#include -#include - -static double program_invoke_time = 0; -static double gc_time = 0; -static double gc_total_time = 0; - -static double -gettimeofday_time(void) -{ - struct timeval tv; - gettimeofday(&tv, NULL); - return tv.tv_sec + tv.tv_usec * 1e-6; -} - -#define GC_INVOKE_TIME_REPORT(with) do {\ - fprintf(stderr, "%s\n", with);\ - fprintf(stderr, "gc_invoke: %19.3f\n", gettimeofday_time() - program_invoke_time);\ - fprintf(stderr, "is_generational: %d\n", is_generational(gc));\ - fprintf(stderr, "is_major_gc: %d\n", is_major_gc(gc));\ -} while(0) - -#define GC_TIME_START do {\ - gc_time = gettimeofday_time();\ -} while(0) - -#define GC_TIME_STOP_AND_REPORT do {\ - gc_time = gettimeofday_time() - gc_time;\ - gc_total_time += gc_time;\ - fprintf(stderr, "gc_state: %d\n", gc->state);\ - fprintf(stderr, "live: %zu\n", gc->live);\ - fprintf(stderr, "majorgc_old_threshold: %zu\n", gc->majorgc_old_threshold);\ - fprintf(stderr, "gc_threshold: %zu\n", gc->threshold);\ - fprintf(stderr, "gc_time: %30.20f\n", gc_time);\ - fprintf(stderr, "gc_total_time: %30.20f\n\n", gc_total_time);\ -} while(0) -#else -#define GC_INVOKE_TIME_REPORT(s) -#define GC_TIME_START -#define GC_TIME_STOP_AND_REPORT -#endif - #ifdef GC_DEBUG #define DEBUG(x) (x) #else @@ -191,13 +148,22 @@ gettimeofday_time(void) #define MRB_HEAP_PAGE_SIZE 1024 #endif +typedef struct mrb_heap_page { + struct RBasic *freelist; + struct mrb_heap_page *next; + struct mrb_heap_page *free_next; + mrb_bool old:1; + /* Flexible array members are not C++ compatible */ + /* void* objects[]; */ +} mrb_heap_page; + #define GC_STEP_SIZE 1024 /* 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) -#define GC_BLACK (1 << 2) +#define GC_WHITE_B 2 +#define GC_BLACK 4 #define GC_RED MRB_GC_RED #define GC_WHITES (GC_WHITE_A | GC_WHITE_B) #define GC_COLOR_MASK 7 @@ -218,8 +184,8 @@ mrb_static_assert(MRB_GC_RED <= GC_COLOR_MASK); /* We have removed `objects[]` from `mrb_heap_page` since it was not C++ * compatible. Using array index to get pointer after structure instead. */ -/* #define objects(p) ((RVALUE *)p->objects) */ -#define objects(p) ((RVALUE *)&p[1]) +/* #define objects(p) ((RVALUE*)p->objects) */ +#define objects(p) ((RVALUE*)&p[1]) mrb_noreturn void mrb_raise_nomemory(mrb_state *mrb); @@ -330,55 +296,10 @@ mrb_object_dead_p(mrb_state *mrb, struct RBasic *object) return is_dead(gc, object); } -static void -link_heap_page(mrb_gc *gc, mrb_heap_page *page) -{ - page->next = gc->heaps; - if (gc->heaps) - gc->heaps->prev = page; - gc->heaps = page; -} - -static void -unlink_heap_page(mrb_gc *gc, mrb_heap_page *page) -{ - if (page->prev) - page->prev->next = page->next; - if (page->next) - page->next->prev = page->prev; - if (gc->heaps == page) - gc->heaps = page->next; - page->prev = NULL; - page->next = NULL; -} - -static void -link_free_heap_page(mrb_gc *gc, mrb_heap_page *page) -{ - page->free_next = gc->free_heaps; - if (gc->free_heaps) { - gc->free_heaps->free_prev = page; - } - gc->free_heaps = page; -} - -static void -unlink_free_heap_page(mrb_gc *gc, mrb_heap_page *page) -{ - if (page->free_prev) - page->free_prev->free_next = page->free_next; - if (page->free_next) - page->free_next->free_prev = page->free_prev; - if (gc->free_heaps == page) - gc->free_heaps = page->free_next; - page->free_prev = NULL; - page->free_next = NULL; -} - static void add_heap(mrb_state *mrb, mrb_gc *gc) { - mrb_heap_page *page = (mrb_heap_page *)mrb_calloc(mrb, 1, sizeof(mrb_heap_page) + MRB_HEAP_PAGE_SIZE * sizeof(RVALUE)); + mrb_heap_page *page = (mrb_heap_page*)mrb_calloc(mrb, 1, sizeof(mrb_heap_page) + MRB_HEAP_PAGE_SIZE * sizeof(RVALUE)); RVALUE *p, *e; struct RBasic *prev = NULL; @@ -389,8 +310,11 @@ add_heap(mrb_state *mrb, mrb_gc *gc) } page->freelist = prev; - link_heap_page(gc, page); - link_free_heap_page(gc, page); + page->next = gc->heaps; + gc->heaps = page; + + page->free_next = gc->free_heaps; + gc->free_heaps = page; } #define DEFAULT_GC_INTERVAL_RATIO 200 @@ -419,10 +343,6 @@ mrb_gc_init(mrb_state *mrb, mrb_gc *gc) gc->generational = TRUE; gc->full = TRUE; #endif - -#ifdef GC_PROFILE - program_invoke_time = gettimeofday_time(); -#endif } static void obj_free(mrb_state *mrb, struct RBasic *obj, int end); @@ -497,15 +417,13 @@ mrb_gc_protect(mrb_state *mrb, mrb_value obj) MRB_API void mrb_gc_register(mrb_state *mrb, mrb_value obj) { - mrb_sym root; mrb_value table; if (mrb_immediate_p(obj)) return; - root = GC_ROOT_SYM; - table = mrb_gv_get(mrb, root); + table = mrb_gv_get(mrb, GC_ROOT_SYM); if (mrb_nil_p(table) || !mrb_array_p(table)) { table = mrb_ary_new(mrb); - mrb_gv_set(mrb, root, table); + mrb_gv_set(mrb, GC_ROOT_SYM, table); } mrb_ary_push(mrb, table, obj); } @@ -514,22 +432,19 @@ mrb_gc_register(mrb_state *mrb, mrb_value obj) MRB_API void mrb_gc_unregister(mrb_state *mrb, mrb_value obj) { - mrb_sym root; mrb_value table; struct RArray *a; - mrb_int i; if (mrb_immediate_p(obj)) return; - root = GC_ROOT_SYM; - table = mrb_gv_get(mrb, root); + table = mrb_gv_get(mrb, GC_ROOT_SYM); if (mrb_nil_p(table)) return; if (!mrb_array_p(table)) { - mrb_gv_set(mrb, root, mrb_nil_value()); + mrb_gv_set(mrb, GC_ROOT_SYM, mrb_nil_value()); return; } a = mrb_ary_ptr(table); mrb_ary_modify(mrb, a); - for (i = 0; i < ARY_LEN(a); i++) { + for (mrb_int i = 0; i < ARY_LEN(a); i++) { if (mrb_ptr(ARY_PTR(a)[i]) == mrb_ptr(obj)) { mrb_int len = ARY_LEN(a)-1; mrb_value *ptr = ARY_PTR(a); @@ -544,7 +459,6 @@ mrb_gc_unregister(mrb_state *mrb, mrb_value obj) MRB_API struct RBasic* mrb_obj_alloc(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls) { - struct RBasic *p; static const RVALUE RVALUE_zero = { { { NULL, NULL, MRB_TT_FALSE } } }; mrb_gc *gc = &mrb->gc; @@ -562,6 +476,7 @@ mrb_obj_alloc(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls) } tt = MRB_INSTANCE_TT(cls); if (tt != MRB_TT_FALSE && + tt != MRB_TT_UNDEF && ttype != MRB_TT_SCLASS && ttype != MRB_TT_ICLASS && ttype != MRB_TT_ENV && @@ -584,15 +499,15 @@ mrb_obj_alloc(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls) add_heap(mrb, gc); } - p = gc->free_heaps->freelist; + struct RBasic *p = gc->free_heaps->freelist; gc->free_heaps->freelist = ((struct free_obj*)p)->next; if (gc->free_heaps->freelist == NULL) { - unlink_free_heap_page(gc, gc->free_heaps); + gc->free_heaps = gc->free_heaps->free_next; } gc->live++; gc_protect(mrb, gc, p); - *(RVALUE *)p = RVALUE_zero; + *(RVALUE*)p = RVALUE_zero; p->tt = ttype; p->c = cls; paint_partial_white(gc, p); @@ -615,8 +530,7 @@ add_gray_list(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) static void mark_context_stack(mrb_state *mrb, struct mrb_context *c) { - size_t i; - size_t e; + size_t i, e; mrb_value nil; if (c->stbase == NULL) return; @@ -712,13 +626,12 @@ gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) case MRB_TT_ENV: { struct REnv *e = (struct REnv*)obj; - mrb_int i, len; if (MRB_ENV_ONSTACK_P(e) && e->cxt && e->cxt->fib) { mrb_gc_mark(mrb, (struct RBasic*)e->cxt->fib); } - len = MRB_ENV_LEN(e); - for (i=0; istack[i]); } } @@ -736,10 +649,10 @@ gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) case MRB_TT_ARRAY: { struct RArray *a = (struct RArray*)obj; - size_t i, e=ARY_LEN(a); + size_t e=ARY_LEN(a); mrb_value *p = ARY_PTR(a); - for (i=0; icxt; - if (c && c != mrb->root_c) { - if (!end && c->status != MRB_FIBER_TERMINATED) { - mrb_callinfo *ci = c->ci; - mrb_callinfo *ce = c->cibase; - - while (ce <= ci) { - struct REnv *e = ci->u.env; - if (e && !mrb_object_dead_p(mrb, (struct RBasic*)e) && - e->tt == MRB_TT_ENV && MRB_ENV_ONSTACK_P(e)) { - mrb_env_unshare(mrb, e, TRUE); - } - ci--; - } - } + if (c != mrb->root_c) { mrb_free_context(mrb, c); } } @@ -1082,6 +982,7 @@ gc_mark_gray_list(mrb_state *mrb, mrb_gc *gc) { while (gc->gray_list) { struct RBasic *obj = gc->gray_list; gc->gray_list = obj->gcnext; + obj->gcnext = NULL; gc_mark_children(mrb, gc, obj); } } @@ -1094,6 +995,7 @@ incremental_marking_phase(mrb_state *mrb, mrb_gc *gc, size_t limit) while (gc->gray_list && tried_marks < limit) { struct RBasic *obj = gc->gray_list; gc->gray_list = obj->gcnext; + obj->gcnext = NULL; gc_mark_children(mrb, gc, obj); tried_marks += gc_gray_counts(mrb, gc, obj); } @@ -1152,14 +1054,15 @@ prepare_incremental_sweep(mrb_state *mrb, mrb_gc *gc) // mrb_assert(gc->atomic_gray_list == NULL); // mrb_assert(gc->gray_list == NULL); gc->state = MRB_GC_STATE_SWEEP; - gc->sweeps = gc->heaps; + gc->sweeps = NULL; gc->live_after_mark = gc->live; } static size_t incremental_sweep_phase(mrb_state *mrb, mrb_gc *gc, size_t limit) { - mrb_heap_page *page = gc->sweeps; + mrb_heap_page *prev = gc->sweeps; + mrb_heap_page *page = prev ? prev->next : gc->heaps; size_t tried_sweep = 0; while (page && (tried_sweep < limit)) { @@ -1167,7 +1070,6 @@ incremental_sweep_phase(mrb_state *mrb, mrb_gc *gc, size_t limit) RVALUE *e = p + MRB_HEAP_PAGE_SIZE; size_t freed = 0; mrb_bool dead_slot = TRUE; - mrb_bool full = (page->freelist == NULL); if (is_minor_gc(gc) && page->old) { /* skip a slot which doesn't contain any young object */ @@ -1197,29 +1099,39 @@ incremental_sweep_phase(mrb_state *mrb, mrb_gc *gc, size_t limit) } /* free dead slot */ - if (dead_slot && freed < MRB_HEAP_PAGE_SIZE) { + if (dead_slot) { mrb_heap_page *next = page->next; - unlink_heap_page(gc, page); - unlink_free_heap_page(gc, page); + if (prev) prev->next = next; + if (gc->heaps == page) + gc->heaps = page->next; + mrb_free(mrb, page); page = next; } else { - if (full && freed > 0) { - link_free_heap_page(gc, page); - } if (page->freelist == NULL && is_minor_gc(gc)) page->old = TRUE; else page->old = FALSE; + prev = page; page = page->next; } tried_sweep += MRB_HEAP_PAGE_SIZE; gc->live -= freed; gc->live_after_mark -= freed; } - gc->sweeps = page; + gc->sweeps = prev; + + /* rebuild free_heaps link */ + gc->free_heaps = NULL; + for (mrb_heap_page *p = gc->heaps; p; p=p->next) { + if (p->freelist) { + p->free_next = gc->free_heaps; + gc->free_heaps = p; + } + } + return tried_sweep; } @@ -1280,22 +1192,17 @@ incremental_gc_step(mrb_state *mrb, mrb_gc *gc) static void clear_all_old(mrb_state *mrb, mrb_gc *gc) { - mrb_bool origin_mode = gc->generational; - mrb_assert(is_generational(gc)); - if (is_major_gc(gc)) { + if (gc->full) { /* finish the half baked GC */ incremental_gc_finish(mrb, gc); } - else { - /* Sweep the dead objects, then reset all the live objects - * (including all the old objects, of course) to white. */ - gc->generational = FALSE; - prepare_incremental_sweep(mrb, gc); - incremental_gc_finish(mrb, gc); - } - gc->generational = origin_mode; - + /* Sweep the dead objects, then reset all the live objects + * (including all the old objects, of course) to white. */ + gc->generational = FALSE; + prepare_incremental_sweep(mrb, gc); + incremental_gc_finish(mrb, gc); + gc->generational = TRUE; /* The gray objects have already been painted as white */ gc->atomic_gray_list = gc->gray_list = NULL; } @@ -1307,9 +1214,6 @@ mrb_incremental_gc(mrb_state *mrb) if (gc->disabled || gc->iterating) return; - GC_INVOKE_TIME_REPORT("mrb_incremental_gc()"); - GC_TIME_START; - if (is_minor_gc(gc)) { incremental_gc_finish(mrb, gc); } @@ -1329,7 +1233,7 @@ mrb_incremental_gc(mrb_state *mrb) gc->full = FALSE; if (threshold < MAJOR_GC_TOOMANY) { - gc->majorgc_old_threshold = threshold; + gc->oldgen_threshold = threshold; } else { /* too many objects allocated during incremental GC, */ @@ -1337,15 +1241,11 @@ mrb_incremental_gc(mrb_state *mrb) mrb_full_gc(mrb); } } - else if (is_minor_gc(gc)) { - if (gc->live > gc->majorgc_old_threshold) { - clear_all_old(mrb, gc); - gc->full = TRUE; - } + else if (is_minor_gc(gc) && gc->live > gc->oldgen_threshold) { + clear_all_old(mrb, gc); + gc->full = TRUE; } } - - GC_TIME_STOP_AND_REPORT; } /* Perform a full gc cycle */ @@ -1357,9 +1257,6 @@ mrb_full_gc(mrb_state *mrb) if (!mrb->c) return; if (gc->disabled || gc->iterating) return; - GC_INVOKE_TIME_REPORT("mrb_full_gc()"); - GC_TIME_START; - if (is_generational(gc)) { /* clear all the old objects back to young */ clear_all_old(mrb, gc); @@ -1374,14 +1271,13 @@ mrb_full_gc(mrb_state *mrb) gc->threshold = (gc->live_after_mark/100) * gc->interval_ratio; if (is_generational(gc)) { - gc->majorgc_old_threshold = gc->live_after_mark/100 * MAJOR_GC_INC_RATIO; + gc->oldgen_threshold = gc->live_after_mark/100 * MAJOR_GC_INC_RATIO; gc->full = FALSE; } #ifdef MRB_USE_MALLOC_TRIM malloc_trim(0); #endif - GC_TIME_STOP_AND_REPORT; } MRB_API void @@ -1580,7 +1476,7 @@ change_gen_gc_mode(mrb_state *mrb, mrb_gc *gc, mrb_bool enable) } else if (!is_generational(gc) && enable) { incremental_gc_finish(mrb, gc); - gc->majorgc_old_threshold = gc->live_after_mark/100 * MAJOR_GC_INC_RATIO; + gc->oldgen_threshold = gc->live_after_mark/100 * MAJOR_GC_INC_RATIO; gc->full = FALSE; } gc->generational = enable; @@ -1629,10 +1525,9 @@ gc_each_objects(mrb_state *mrb, mrb_gc *gc, mrb_each_object_callback *callback, page = gc->heaps; while (page != NULL) { RVALUE *p; - int i; p = objects(page); - for (i=0; i < MRB_HEAP_PAGE_SIZE; i++) { + for (int i=0; i < MRB_HEAP_PAGE_SIZE; i++) { if ((*callback)(mrb, &p[i].as.basic, data) == MRB_EACH_OBJ_BREAK) return; } @@ -1659,7 +1554,7 @@ mrb_objspace_each_objects(mrb_state *mrb, mrb_each_object_callback *callback, vo gc_each_objects(mrb, &mrb->gc, callback, data); mrb->jmp = prev_jmp; mrb->gc.iterating = iterating; - } MRB_CATCH(&c_jmp) { + } MRB_CATCH(&c_jmp) { mrb->gc.iterating = iterating; mrb->jmp = prev_jmp; MRB_THROW(prev_jmp); diff --git a/mruby/src/hash.c b/mruby/src/hash.c index 40cfacf6..ad92f541 100644 --- a/mruby/src/hash.c +++ b/mruby/src/hash.c @@ -273,7 +273,7 @@ HT_ASSERT_SAFE_READ(ea_capa); } \ code; \ if (flags__ != (h__->flags & mask__) || \ - tbl__ != h__->hsh.ht || \ + tbl__ != h__->hsh.ht || \ ((H_CHECK_MODIFIED_USE_HT_EA_CAPA_FOR_AR || h_ht_p(h__)) && \ ht_ea_capa__ != ht_ea_capa(h__)) || \ ((H_CHECK_MODIFIED_USE_HT_EA_FOR_AR || h_ht_p(h__)) && \ @@ -382,7 +382,7 @@ obj_eql(mrb_state *mrb, mrb_value a, mrb_value b, struct RHash *h) } } -static mrb_bool +static inline mrb_bool entry_deleted_p(const hash_entry* entry) { return mrb_undef_p(entry->key); @@ -1109,7 +1109,11 @@ MRB_API void mrb_hash_foreach(mrb_state *mrb, struct RHash *h, mrb_hash_foreach_func *func, void *data) { h_each(h, entry, { - if (func(mrb, entry->key, entry->val, data) != 0) return; + int n; + h_check_modified(mrb, h, { + n = func(mrb, entry->key, entry->val, data); + }); + if (n != 0) return; }); } @@ -1560,10 +1564,16 @@ mrb_hash_clear(mrb_state *mrb, mrb_value hash) static mrb_value mrb_hash_aset(mrb_state *mrb, mrb_value self) { - mrb_value key, val; + mrb_int argc = mrb_get_argc(mrb); + + if (argc != 2) { + mrb_argnum_error(mrb, argc, 2, 2); + } - mrb_get_args(mrb, "oo", &key, &val); - mrb_hash_set(mrb, self, key, val); + const mrb_value *argv = mrb_get_argv(mrb); + mrb_value val = argv[1]; + + mrb_hash_set(mrb, self, argv[0], argv[1]); return val; } @@ -1742,8 +1752,8 @@ mrb_hash_merge(mrb_state *mrb, mrb_value hash1, mrb_value hash2) if (h_size(h2) == 0) return; h_each(h2, entry, { h_check_modified(mrb, h2, {h_set(mrb, h1, entry->key, entry->val);}); - mrb_field_write_barrier_value(mrb, (struct RBasic *)h1, entry->key); - mrb_field_write_barrier_value(mrb, (struct RBasic *)h1, entry->val); + mrb_field_write_barrier_value(mrb, (struct RBasic*)h1, entry->key); + mrb_field_write_barrier_value(mrb, (struct RBasic*)h1, entry->val); }); } @@ -1787,6 +1797,69 @@ mrb_hash_rehash(mrb_state *mrb, mrb_value self) return self; } +static mrb_value +mrb_hash_compact(mrb_state *mrb, mrb_value hash) +{ + struct RHash *h = mrb_hash_ptr(hash); + mrb_bool ht_p = h_ht_p(h); + uint32_t size = ht_p ? ht_size(h) : ar_size(h); + uint32_t dec = 0; + + mrb_check_frozen(mrb, h); + h_each(h, entry, { + if (mrb_nil_p(entry->val)) { + entry_delete(entry); + dec++; + } + }); + if (dec == 0) return mrb_nil_value(); + size -= dec; + if (ht_p) { + ht_set_size(h, size); + } + else { + ar_set_size(h, size); + } + return hash; +} + +/* + * call-seq: + * hash.to_s -> string + * hash.inspect -> string + * + * Return the contents of this hash as a string. + */ +static mrb_value +mrb_hash_to_s(mrb_state *mrb, mrb_value self) +{ + mrb->c->ci->mid = MRB_SYM(inspect); + mrb_value ret = mrb_str_new_lit(mrb, "{"); + int ai = mrb_gc_arena_save(mrb); + if (mrb_inspect_recursive_p(mrb, self)) { + mrb_str_cat_lit(mrb, ret, "...}"); + return ret; + } + + mrb_int i = 0; + struct RHash *h = mrb_hash_ptr(self); + h_each(h, entry, { + if (i++ > 0) mrb_str_cat_lit(mrb, ret, ", "); + h_check_modified(mrb, h, { + mrb_str_cat_str(mrb, ret, mrb_inspect(mrb, entry->key)); + }); + mrb_gc_arena_restore(mrb, ai); + mrb_str_cat_lit(mrb, ret, "=>"); + h_check_modified(mrb, h, { + mrb_str_cat_str(mrb, ret, mrb_inspect(mrb, entry->val)); + }); + mrb_gc_arena_restore(mrb, ai); + }); + mrb_str_cat_lit(mrb, ret, "}"); + + return ret; +} + void mrb_init_hash(mrb_state *mrb) { @@ -1819,6 +1892,9 @@ mrb_init_hash(mrb_state *mrb) mrb_define_method(mrb, h, "store", mrb_hash_aset, MRB_ARGS_REQ(2)); /* 15.2.13.4.26 */ mrb_define_method(mrb, h, "value?", mrb_hash_has_value, MRB_ARGS_REQ(1)); /* 15.2.13.4.27 */ mrb_define_method(mrb, h, "values", mrb_hash_values, MRB_ARGS_NONE()); /* 15.2.13.4.28 */ + mrb_define_method(mrb, h, "to_s", mrb_hash_to_s, MRB_ARGS_NONE()); + mrb_define_method(mrb, h, "inspect", mrb_hash_to_s, MRB_ARGS_NONE()); mrb_define_method(mrb, h, "rehash", mrb_hash_rehash, MRB_ARGS_NONE()); mrb_define_method(mrb, h, "__merge", mrb_hash_merge_m, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, h, "__compact", mrb_hash_compact, MRB_ARGS_NONE()); /* implementation of Hash#compact! */ } diff --git a/mruby/src/kernel.c b/mruby/src/kernel.c index 250f01d2..59474be8 100644 --- a/mruby/src/kernel.c +++ b/mruby/src/kernel.c @@ -71,7 +71,7 @@ mrb_obj_inspect(mrb_state *mrb, mrb_value obj) * to provide meaningful semantics in case statements. */ static mrb_value -mrb_equal_m(mrb_state *mrb, mrb_value self) +mrb_eqq_m(mrb_state *mrb, mrb_value self) { mrb_value arg = mrb_get_arg1(mrb); @@ -83,11 +83,45 @@ mrb_cmp_m(mrb_state *mrb, mrb_value self) { mrb_value arg = mrb_get_arg1(mrb); + /* recursion check */ + for (mrb_callinfo *ci=&mrb->c->ci[-1]; ci>=mrb->c->cibase; ci--) { + if (ci->mid == MRB_OPSYM(cmp) && + mrb_obj_eq(mrb, self, ci->stack[0]) && + mrb_obj_eq(mrb, arg, ci->stack[1])) { + /* recursive <=> calling returns `nil` */ + return mrb_nil_value(); + } + } + if (mrb_equal(mrb, self, arg)) return mrb_fixnum_value(0); return mrb_nil_value(); } +static mrb_bool +inspect_recursive_p(mrb_state *mrb, mrb_value obj, int n) +{ + for (mrb_callinfo *ci=&mrb->c->ci[-1-n]; ci>=mrb->c->cibase; ci--) { + if (ci->mid == MRB_SYM(inspect) && + mrb_obj_eq(mrb, obj, ci->stack[0])) { + return TRUE; + } + } + return FALSE; +} + +mrb_bool +mrb_inspect_recursive_p(mrb_state *mrb, mrb_value obj) +{ + return inspect_recursive_p(mrb, obj, 0); +} + +static mrb_value +mrb_obj_inspect_recursive_p(mrb_state *mrb, mrb_value obj) +{ + return mrb_bool_value(inspect_recursive_p(mrb, obj, 1)); +} + /* 15.3.1.3.3 */ /* 15.3.1.3.33 */ /* @@ -380,24 +414,26 @@ mrb_false(mrb_state *mrb, mrb_value self) MRB_API mrb_value mrb_f_raise(mrb_state *mrb, mrb_value self) { - mrb_value a[2], exc; + mrb_value exc, mesg; mrb_int argc; - argc = mrb_get_args(mrb, "|oo", &a[0], &a[1]); + argc = mrb_get_args(mrb, "|oo", &exc, &mesg); mrb->c->ci->mid = 0; switch (argc) { case 0: mrb_raise(mrb, E_RUNTIME_ERROR, ""); break; case 1: - if (mrb_string_p(a[0])) { - a[1] = a[0]; - argc = 2; - a[0] = mrb_obj_value(E_RUNTIME_ERROR); + if (mrb_string_p(exc)) { + mesg = exc; + exc = mrb_obj_value(E_RUNTIME_ERROR); + } + else { + mesg = mrb_nil_value(); } /* fall through */ default: - exc = mrb_make_exception(mrb, argc, a); + exc = mrb_make_exception(mrb, exc, mesg); mrb_exc_raise(mrb, exc); break; } @@ -441,12 +477,6 @@ mrb_obj_remove_instance_variable(mrb_state *mrb, mrb_value self) return val; } -static inline mrb_bool -basic_obj_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym id, int pub) -{ - return mrb_respond_to(mrb, obj, id); -} - /* 15.3.1.3.43 */ /* * call-seq: @@ -466,18 +496,16 @@ basic_obj_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym id, int pub) static mrb_value obj_respond_to(mrb_state *mrb, mrb_value self) { - mrb_sym id, rtm_id; + mrb_sym id; mrb_bool priv = FALSE, respond_to_p; mrb_get_args(mrb, "n|b", &id, &priv); - respond_to_p = basic_obj_respond_to(mrb, self, id, !priv); + respond_to_p = mrb_respond_to(mrb, self, id); if (!respond_to_p) { - rtm_id = MRB_SYM_Q(respond_to_missing); - if (basic_obj_respond_to(mrb, self, rtm_id, !priv)) { - mrb_value args[2], v; - args[0] = mrb_symbol_value(id); - args[1] = mrb_bool_value(priv); - v = mrb_funcall_argv(mrb, self, rtm_id, 2, args); + mrb_sym rtm_id = MRB_SYM_Q(respond_to_missing); + if (!mrb_func_basic_p(mrb, self, rtm_id, mrb_false)) { + mrb_value v; + v = mrb_funcall_id(mrb, self, rtm_id, 2, mrb_symbol_value(id), mrb_bool_value(priv)); return mrb_bool_value(mrb_bool(v)); } } @@ -505,7 +533,7 @@ mrb_obj_ceqq(mrb_state *mrb, mrb_value self) return mrb_false_value(); } else { - ary = mrb_funcall_id(mrb, self, MRB_SYM(to_a), 0); + ary = mrb_funcall_argv(mrb, self, MRB_SYM(to_a), 0, NULL); if (mrb_nil_p(ary)) { return mrb_funcall_argv(mrb, self, eqq, 1, &v); } @@ -513,7 +541,7 @@ mrb_obj_ceqq(mrb_state *mrb, mrb_value self) } len = RARRAY_LEN(ary); for (i=0; i", mrb_cmp_m, MRB_ARGS_REQ(1)); mrb_define_method(mrb, krn, "block_given?", mrb_f_block_given_p_m, MRB_ARGS_NONE()); /* 15.3.1.3.6 */ mrb_define_method(mrb, krn, "class", mrb_obj_class_m, MRB_ARGS_NONE()); /* 15.3.1.3.7 */ @@ -569,6 +594,8 @@ mrb_init_kernel(mrb_state *mrb) mrb_define_method(mrb, krn, "__case_eqq", mrb_obj_ceqq, MRB_ARGS_REQ(1)); /* internal */ mrb_define_method(mrb, krn, "__to_int", mrb_ensure_int_type, MRB_ARGS_NONE()); /* internal */ mrb_define_method(mrb, krn, "__ENCODING__", mrb_encoding, MRB_ARGS_NONE()); + mrb_define_method(mrb, krn, "respond_to_missing?", mrb_false, MRB_ARGS_ARG(1,1)); + mrb_define_method(mrb, krn, "__inspect_recursive?", mrb_obj_inspect_recursive_p, MRB_ARGS_NONE()); mrb_include_module(mrb, mrb->object_class, mrb->kernel_module); } diff --git a/mruby/src/load.c b/mruby/src/load.c index 52cb154b..3287da2e 100644 --- a/mruby/src/load.c +++ b/mruby/src/load.c @@ -110,7 +110,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, const uint8_t *end, size_ } else { void *buf = mrb_malloc(mrb, data_len); - irep->iseq = (mrb_code *)buf; + irep->iseq = (mrb_code*)buf; memcpy(buf, src, data_len); } src += data_len; @@ -220,7 +220,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, const uint8_t *end, size_ if (SIZE_ERROR_MUL(irep->slen, sizeof(mrb_sym))) { return FALSE; } - irep->syms = syms = (mrb_sym *)mrb_malloc(mrb, sizeof(mrb_sym) * irep->slen); + irep->syms = syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym) * irep->slen); for (i = 0; i < irep->slen; i++) { snl = bin_to_uint16(src); /* symbol name length */ @@ -233,10 +233,10 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, const uint8_t *end, size_ if (src + snl > end) return FALSE; if (flags & FLAG_SRC_MALLOC) { - syms[i] = mrb_intern(mrb, (char *)src, snl); + syms[i] = mrb_intern(mrb, (char*)src, snl); } else { - syms[i] = mrb_intern_static(mrb, (char *)src, snl); + syms[i] = mrb_intern_static(mrb, (char*)src, snl); } src += snl + 1; mrb_gc_arena_restore(mrb, ai); @@ -331,7 +331,7 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, const uint8_t *end, mrb_ uint16_t filename_idx; if (bin > end) return MRB_DUMP_GENERAL_FAILURE; - file = (mrb_irep_debug_info_file *)mrb_calloc(mrb, 1, sizeof(*file)); + file = (mrb_irep_debug_info_file*)mrb_calloc(mrb, 1, sizeof(*file)); debug->files[f_idx] = file; file->start_pos = bin_to_uint32(bin); @@ -352,7 +352,7 @@ 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; - uint16_t *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++) { ary[l] = bin_to_uint16(bin); bin += sizeof(uint16_t); @@ -427,7 +427,7 @@ read_section_debug(mrb_state *mrb, const uint8_t *start, size_t size, mrb_irep * mrb_value filenames_obj; bin = start; - header = (struct rite_section_debug_header *)bin; + header = (struct rite_section_debug_header*)bin; bin += sizeof(struct rite_section_debug_header); filenames_len = bin_to_uint16(bin); @@ -443,10 +443,10 @@ read_section_debug(mrb_state *mrb, const uint8_t *start, size_t size, mrb_irep * goto debug_exit; } if (flags & FLAG_SRC_MALLOC) { - filenames[i] = mrb_intern(mrb, (const char *)bin, (size_t)f_len); + filenames[i] = mrb_intern(mrb, (const char*)bin, (size_t)f_len); } else { - filenames[i] = mrb_intern_static(mrb, (const char *)bin, (size_t)f_len); + filenames[i] = mrb_intern_static(mrb, (const char*)bin, (size_t)f_len); } bin += f_len; } @@ -558,7 +558,7 @@ read_section_lv(mrb_state *mrb, const uint8_t *start, size_t size, mrb_irep *ire static int read_binary_header(const uint8_t *bin, size_t bufsize, size_t *bin_size, uint8_t *flags) { - const struct rite_binary_header *header = (const struct rite_binary_header *)bin; + const struct rite_binary_header *header = (const struct rite_binary_header*)bin; if (bufsize < sizeof(struct rite_binary_header)) { return MRB_DUMP_READ_FAULT; @@ -607,7 +607,7 @@ read_irep(mrb_state *mrb, const uint8_t *bin, size_t bufsize, uint8_t flags) bin += sizeof(struct rite_binary_header); bin_size -= sizeof(struct rite_binary_header); while (bin_size > sizeof(struct rite_section_header)) { - section_header = (const struct rite_section_header *)bin; + section_header = (const struct rite_section_header*)bin; uint32_t section_size = bin_to_uint32(section_header->section_size); if (bin_size < section_size) return NULL; if (memcmp(section_header->section_ident, RITE_SECTION_IREP_IDENT, sizeof(section_header->section_ident)) == 0) { @@ -654,7 +654,7 @@ DEFINE_READ_IREP_FUNC( static struct RProc* mrb_proc_read_irep_buf(mrb_state *mrb, const void *buf, size_t bufsize) { - return read_irep(mrb, (const uint8_t *)buf, bufsize, FLAG_SRC_MALLOC); + return read_irep(mrb, (const uint8_t*)buf, bufsize, FLAG_SRC_MALLOC); } DEFINE_READ_IREP_FUNC( diff --git a/mruby/src/numeric.c b/mruby/src/numeric.c index a671eeba..ecc7aa59 100644 --- a/mruby/src/numeric.c +++ b/mruby/src/numeric.c @@ -66,7 +66,7 @@ mrb_int_pow(mrb_state *mrb, mrb_value x, mrb_value y) else #endif { - mrb_get_args(mrb, "i", &exp); + exp = mrb_as_int(mrb, y); } if (exp < 0) { #ifndef MRB_NO_FLOAT @@ -130,7 +130,7 @@ mrb_div_int_value(mrb_state *mrb, mrb_int x, mrb_int y) if (y == 0) { mrb_int_zerodiv(mrb); } - else if(x == MRB_INT_MIN && y == -1) { + else if (x == MRB_INT_MIN && y == -1) { #ifdef MRB_USE_BIGINT return mrb_bint_mul_ii(mrb, x, y); #else @@ -208,9 +208,7 @@ int_idiv(mrb_state *mrb, mrb_value x) return mrb_bint_div(mrb, x, mrb_get_arg1(mrb)); } #endif - mrb_int y; - - mrb_get_args(mrb, "i", &y); + mrb_int y = mrb_as_int(mrb, mrb_get_arg1(mrb)); return mrb_div_int_value(mrb, mrb_integer(x), y); } @@ -221,9 +219,8 @@ int_quo(mrb_state *mrb, mrb_value x) #ifdef MRB_NO_FLOAT return int_idiv(mrb, x); #else - mrb_float y; + mrb_float y = mrb_as_float(mrb, mrb_get_arg1(mrb)); - mrb_get_args(mrb, "f", &y); if (y == 0) { mrb_int_zerodiv(mrb); } @@ -293,10 +290,10 @@ flo_pow(mrb_state *mrb, mrb_value x) static mrb_value flo_idiv(mrb_state *mrb, mrb_value xv) { - mrb_int y; - - mrb_get_args(mrb, "i", &y); - return mrb_div_int_value(mrb, (mrb_int)mrb_float(xv), y); + mrb_float x = mrb_float(xv); + mrb_check_num_exact(mrb, x); + mrb_int y = mrb_as_int(mrb, mrb_get_arg1(mrb)); + return mrb_div_int_value(mrb, (mrb_int)x, y); } mrb_float @@ -357,7 +354,8 @@ mrb_float_to_str(mrb_state *mrb, mrb_value flo, const char *fmt) if (*p == '.') goto exit; if (*p == 'e') { memmove(p+2, p, strlen(p)+1); - memcpy(p, ".0", 2); + p[0] = '.'; + p[1] = '0'; goto exit; } } @@ -537,7 +535,7 @@ flo_mod(mrb_state *mrb, mrb_value x) mrb_value y = mrb_get_arg1(mrb); mrb_float mod; - flodivmod(mrb, mrb_float(x), mrb_as_float(mrb, y), 0, &mod); + flodivmod(mrb, mrb_float(x), mrb_as_float(mrb, y), NULL, &mod); return mrb_float_value(mrb, mod); } #endif @@ -709,9 +707,10 @@ flo_shift(mrb_state *mrb, mrb_value x, mrb_int width) val = trunc(val); #else if (val > 0){ - val = floor(val); - } else { - val = ceil(val); + val = floor(val); + } + else { + val = ceil(val); } #endif if (val == 0 && mrb_float(x) < 0) { @@ -731,9 +730,7 @@ flo_shift(mrb_state *mrb, mrb_value x, mrb_int width) static mrb_value flo_rshift(mrb_state *mrb, mrb_value x) { - mrb_int width; - - mrb_get_args(mrb, "i", &width); + mrb_int width = mrb_as_int(mrb, mrb_get_arg1(mrb)); if (width == MRB_INT_MIN) return flo_shift(mrb, x, -MRB_INT_BIT); return flo_shift(mrb, x, -width); } @@ -741,9 +738,7 @@ flo_rshift(mrb_state *mrb, mrb_value x) static mrb_value flo_lshift(mrb_state *mrb, mrb_value x) { - mrb_int width; - - mrb_get_args(mrb, "i", &width); + mrb_int width = mrb_as_int(mrb, mrb_get_arg1(mrb)); return flo_shift(mrb, x, width); } @@ -1204,7 +1199,7 @@ intdivmod(mrb_state *mrb, mrb_int x, mrb_int y, mrb_int *divp, mrb_int *modp) if (y == 0) { mrb_int_zerodiv(mrb); } - else if(x == MRB_INT_MIN && y == -1) { + else if (x == MRB_INT_MIN && y == -1) { mrb_int_overflow(mrb, "division"); } else { @@ -1374,13 +1369,12 @@ int_equal(mrb_state *mrb, mrb_value x) static mrb_value 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); + return mrb_bint_rev(mrb, num); } #endif + mrb_int val = mrb_integer(num); return mrb_int_value(mrb, ~val); } @@ -1521,7 +1515,7 @@ int_lshift(mrb_state *mrb, mrb_value x) { mrb_int width, val; - mrb_get_args(mrb, "i", &width); + width = mrb_as_int(mrb, mrb_get_arg1(mrb)); if (width == 0) { return x; } @@ -1556,7 +1550,7 @@ int_rshift(mrb_state *mrb, mrb_value x) { mrb_int width, val; - mrb_get_args(mrb, "i", &width); + width = mrb_as_int(mrb, mrb_get_arg1(mrb)); if (width == 0) { return x; } @@ -1620,16 +1614,26 @@ int_ceil(mrb_state *mrb, mrb_value x) if (mrb_nil_p(f)) return x; #ifdef MRB_USE_BIGINT if (mrb_bigint_p(x)) { - return mrb_bint_add(mrb, x, mrb_bint_sub(mrb, x, mrb_bint_mod(mrb, x, f))); + x = mrb_bint_add_d(mrb, x, f); + return mrb_bint_sub(mrb, x, mrb_bint_mod(mrb, x, f)); } #endif mrb_int a = mrb_integer(x); mrb_int b = mrb_integer(f); + mrb_int c = a % b; int neg = a < 0; - if (neg) a = -a; - else a += b - 1; - a = a / b * b; - if (neg) a = -a; + a -= c; + if (!neg) { + if (mrb_int_add_overflow(a, b, &c)) { +#ifdef MRB_USE_BIGINT + x = mrb_bint_new_int(mrb, a); + return mrb_bint_add(mrb, x, f); +#else + mrb_int_overflow(mrb, "ceil"); +#endif + } + a = c; + } return mrb_int_value(mrb, a); } @@ -1657,10 +1661,20 @@ int_floor(mrb_state *mrb, mrb_value x) #endif mrb_int a = mrb_integer(x); mrb_int b = mrb_integer(f); + mrb_int c = a % b; int neg = a < 0; - if (neg) a = -a + b - 1; - a = a / b * b; - if (neg) a = -a; + a -= c; + if (neg) { + if (mrb_int_sub_overflow(a, b, &c)) { +#ifdef MRB_USE_BIGINT + x = mrb_bint_new_int(mrb, a); + return mrb_bint_sub(mrb, x, f); +#else + mrb_int_overflow(mrb, "floor"); +#endif + } + a = c; + } return mrb_int_value(mrb, a); } @@ -1686,7 +1700,7 @@ int_round(mrb_state *mrb, mrb_value x) mrb_value r = mrb_bint_mod(mrb, x, f); mrb_value n = mrb_bint_sub(mrb, x, r); mrb_value h = mrb_bigint_p(f) ? mrb_bint_rshift(mrb, f, 1) : mrb_int_value(mrb, mrb_integer(f)>>1); - mrb_int cmp = mrb_bigint_p(r) ? mrb_bint_cmp(mrb, r, h) : (mrb_integer(r) - mrb_integer(h)); + mrb_int cmp = mrb_bigint_p(r) ? mrb_bint_cmp(mrb, r, h) : (mrb_bigint_p(h) ? -mrb_bint_cmp(mrb, h, r) : (mrb_integer(r)-mrb_integer(h))); if ((cmp > 0) || (cmp == 0 && mrb_bint_cmp(mrb, x, mrb_fixnum_value(0)) > 0)) { n = mrb_as_bint(mrb, n); n = mrb_bint_add(mrb, n, f); @@ -1696,10 +1710,35 @@ int_round(mrb_state *mrb, mrb_value x) #endif mrb_int a = mrb_integer(x); mrb_int b = mrb_integer(f); - int neg = a < 0; - if (neg) a = -a; - a = (a + b / 2) / b * b; - if (neg) a = -a; + mrb_int c = a % b; + a -= c; + if (c < 0) { + c = -c; + if (b/2 < c) { + if (mrb_int_sub_overflow(a, b, &c)) { +#ifdef MRB_USE_BIGINT + x = mrb_bint_new_int(mrb, a); + return mrb_bint_sub(mrb, x, f); +#else + mrb_int_overflow(mrb, "round"); +#endif + } + } + a = c; + } + else { + if (b/2 < c) { + if (mrb_int_add_overflow(a, b, &c)) { +#ifdef MRB_USE_BIGINT + x = mrb_bint_new_int(mrb, a); + return mrb_bint_add(mrb, x, f); +#else + mrb_int_overflow(mrb, "round"); +#endif + } + } + a = c; + } return mrb_int_value(mrb, a); } @@ -1723,21 +1762,16 @@ int_truncate(mrb_state *mrb, mrb_value x) #ifdef MRB_USE_BIGINT if (mrb_bigint_p(x)) { mrb_value m = mrb_bint_mod(mrb, x, f); + x = mrb_bint_sub_d(mrb, x, m); if (mrb_bint_cmp(mrb, x, mrb_fixnum_value(0)) < 0) { - return mrb_bint_add(mrb, x, mrb_bint_sub(mrb, x, m)); - } - else { - return mrb_bint_sub(mrb, x, m); + return mrb_bint_add(mrb, x, f); } + return x; } #endif mrb_int a = mrb_integer(x); mrb_int b = mrb_integer(f); - int neg = a < 0; - if (neg) a = -a; - a = a / b * b; - if (neg) a = -a; - return mrb_int_value(mrb, a); + return mrb_int_value(mrb, a - (a % b)); } /* 15.2.8.3.23 */ @@ -2141,7 +2175,7 @@ mrb_cmp(mrb_state *mrb, mrb_value obj1, mrb_value obj2) 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); + v = mrb_funcall_argv(mrb, obj1, MRB_OPSYM(cmp), 1, &obj2); if (mrb_nil_p(v) || !mrb_integer_p(v)) return -2; return mrb_integer(v); @@ -2188,7 +2222,7 @@ mrb_init_numeric(mrb_state *mrb) /* Integer Class */ mrb->integer_class = integer = mrb_define_class(mrb, "Integer", numeric); /* 15.2.8 */ - MRB_SET_INSTANCE_TT(integer, MRB_TT_INTEGER); + MRB_SET_INSTANCE_TT(integer, MRB_TT_UNDEF); mrb_undef_class_method(mrb, integer, "new"); mrb_define_method(mrb, integer, "**", int_pow, MRB_ARGS_REQ(1)); mrb_define_method(mrb, integer, "<=>", num_cmp, MRB_ARGS_REQ(1)); /* 15.2.8.3.1 */ @@ -2233,7 +2267,7 @@ mrb_init_numeric(mrb_state *mrb) #ifndef MRB_NO_FLOAT /* Float Class */ mrb->float_class = fl = mrb_define_class(mrb, "Float", numeric); /* 15.2.9 */ - MRB_SET_INSTANCE_TT(fl, MRB_TT_FLOAT); + MRB_SET_INSTANCE_TT(fl, MRB_TT_UNDEF); mrb_undef_class_method(mrb, fl, "new"); mrb_define_method(mrb, fl, "**", flo_pow, MRB_ARGS_REQ(1)); mrb_define_method(mrb, fl, "/", flo_div, MRB_ARGS_REQ(1)); /* 15.2.9.3.6 */ diff --git a/mruby/src/object.c b/mruby/src/object.c index cc7ec644..91e4a881 100644 --- a/mruby/src/object.c +++ b/mruby/src/object.c @@ -53,32 +53,29 @@ mrb_obj_equal(mrb_state *mrb, mrb_value v1, mrb_value v2) MRB_API mrb_bool mrb_equal(mrb_state *mrb, mrb_value obj1, mrb_value obj2) { - mrb_value result; - if (mrb_obj_eq(mrb, obj1, obj2)) return TRUE; #ifndef MRB_NO_FLOAT /* value mixing with integer and float */ - if (mrb_integer_p(obj1) && mrb_float_p(obj2)) { + else if (mrb_integer_p(obj1) && mrb_float_p(obj2)) { if ((mrb_float)mrb_integer(obj1) == mrb_float(obj2)) return TRUE; - return FALSE; } else if (mrb_float_p(obj1) && mrb_integer_p(obj2)) { if (mrb_float(obj1) == (mrb_float)mrb_integer(obj2)) return TRUE; - return FALSE; } #endif #ifdef MRB_USE_BIGINT - if (mrb_bigint_p(obj1) && + else if (mrb_bigint_p(obj1) && (mrb_integer_p(obj2) || mrb_bigint_p(obj2) || mrb_float_p(obj2))) { if (mrb_bint_cmp(mrb, obj1, obj2) == 0) return TRUE; - return FALSE; } #endif - result = mrb_funcall_id(mrb, obj1, MRB_OPSYM(eq), 1, obj2); - if (mrb_test(result)) return TRUE; + else if (!mrb_func_basic_p(mrb, obj1, MRB_OPSYM(eq), mrb_obj_equal_m)) { + mrb_value result = mrb_funcall_argv(mrb, obj1, MRB_OPSYM(eq), 1, &obj2); + if (mrb_test(result)) return TRUE; + } return FALSE; } @@ -638,7 +635,7 @@ mrb_check_hash_type(mrb_state *mrb, mrb_value hash) MRB_API mrb_value mrb_inspect(mrb_state *mrb, mrb_value obj) { - mrb_value v = mrb_funcall_id(mrb, obj, MRB_SYM(inspect), 0); + mrb_value v = mrb_funcall_argv(mrb, obj, MRB_SYM(inspect), 0, NULL); if (!mrb_string_p(v)) { v = mrb_obj_as_string(mrb, obj); } @@ -649,5 +646,5 @@ MRB_API mrb_bool mrb_eql(mrb_state *mrb, mrb_value obj1, mrb_value obj2) { if (mrb_obj_eq(mrb, obj1, obj2)) return TRUE; - return mrb_test(mrb_funcall_id(mrb, obj1, MRB_SYM_Q(eql), 1, obj2)); + return mrb_test(mrb_funcall_argv(mrb, obj1, MRB_SYM_Q(eql), 1, &obj2)); } diff --git a/mruby/src/pool.c b/mruby/src/pool.c index ab30be1d..26088186 100644 --- a/mruby/src/pool.c +++ b/mruby/src/pool.c @@ -63,7 +63,7 @@ struct mrb_pool { MRB_API mrb_pool* mrb_pool_open(mrb_state *mrb) { - mrb_pool *pool = (mrb_pool *)mrb_malloc_simple(mrb, sizeof(mrb_pool)); + mrb_pool *pool = (mrb_pool*)mrb_malloc_simple(mrb, sizeof(mrb_pool)); if (pool) { pool->mrb = mrb; @@ -95,7 +95,7 @@ page_alloc(mrb_pool *pool, size_t len) if (len < POOL_PAGE_SIZE) len = POOL_PAGE_SIZE; - page = (struct mrb_pool_page *)mrb_malloc_simple(pool->mrb, sizeof(struct mrb_pool_page)+len); + page = (struct mrb_pool_page*)mrb_malloc_simple(pool->mrb, sizeof(struct mrb_pool_page)+len); if (page) { page->offset = 0; page->len = len; diff --git a/mruby/src/proc.c b/mruby/src/proc.c index c27e6ea7..ac601a4b 100644 --- a/mruby/src/proc.c +++ b/mruby/src/proc.c @@ -193,6 +193,29 @@ mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx) return e->stack[idx]; } +mrb_value +mrb_proc_get_self(mrb_state *mrb, struct RProc *p, struct RClass **target_class_p) +{ + if (MRB_PROC_CFUNC_P(p)) { + *target_class_p = mrb->object_class; + return mrb_nil_value(); + } + else { + struct REnv *e = p->e.env; + + if (!e || e->tt != MRB_TT_ENV) { + *target_class_p = mrb->object_class; + return mrb_top_self(mrb); + } + else if (MRB_ENV_LEN(e) < 1) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "self is lost (probably ran out of memory when the block became independent)"); + } + + *target_class_p = e->c; + return e->stack[0]; + } +} + void mrb_proc_copy(mrb_state *mrb, struct RProc *a, struct RProc *b) { @@ -248,13 +271,42 @@ mrb_proc_init_copy(mrb_state *mrb, mrb_value self) return self; } -/* 15.2.17.4.2 */ static mrb_value proc_arity(mrb_state *mrb, mrb_value self) { return mrb_int_value(mrb, mrb_proc_arity(mrb_proc_ptr(self))); } +mrb_bool +mrb_proc_eql(mrb_state *mrb, mrb_value self, mrb_value other) +{ + if (mrb_type(self) != MRB_TT_PROC) return FALSE; + if (mrb_type(other) != MRB_TT_PROC) return FALSE; + + struct RProc *p1 = mrb_proc_ptr(self); + struct RProc *p2 = mrb_proc_ptr(other); + if (MRB_PROC_CFUNC_P(p1)) { + if (!MRB_PROC_CFUNC_P(p1)) return FALSE; + if (p1->body.func != p2->body.func) return FALSE; + } + else if (MRB_PROC_CFUNC_P(p2)) return FALSE; + else if (p1->body.irep != p2->body.irep) return FALSE; + return TRUE; +} + +static mrb_value +proc_eql(mrb_state *mrb, mrb_value self) +{ + return mrb_bool_value(mrb_proc_eql(mrb, self, mrb_get_arg1(mrb))); +} + +static mrb_value +proc_hash(mrb_state *mrb, mrb_value self) +{ + struct RProc *p = mrb_proc_ptr(self); + return mrb_int_value(mrb, (mrb_int)(((intptr_t)p->body.irep)^MRB_TT_PROC)); +} + /* 15.3.1.2.6 */ /* 15.3.1.3.27 */ /* @@ -441,12 +493,14 @@ mrb_init_proc(mrb_state *mrb) mrb_define_class_method(mrb, mrb->proc_class, "new", mrb_proc_s_new, MRB_ARGS_NONE()|MRB_ARGS_BLOCK()); mrb_define_method(mrb, mrb->proc_class, "initialize_copy", mrb_proc_init_copy, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, mrb->proc_class, "arity", proc_arity, MRB_ARGS_NONE()); + mrb_define_method(mrb, mrb->proc_class, "arity", proc_arity, MRB_ARGS_NONE()); /* 15.2.17.4.2 */ + mrb_define_method(mrb, mrb->proc_class, "==", proc_eql, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, mrb->proc_class, "eql?", proc_eql, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, mrb->proc_class, "hash", proc_hash, MRB_ARGS_NONE()); /* 15.2.17.4.2 */ MRB_METHOD_FROM_PROC(m, &call_proc); - mrb_define_method_raw(mrb, mrb->proc_class, MRB_SYM(call), m); - mrb_define_method_raw(mrb, mrb->proc_class, MRB_OPSYM(aref), m); + mrb_define_method_raw(mrb, mrb->proc_class, MRB_SYM(call), m); /* 15.2.17.4.3 */ + mrb_define_method_raw(mrb, mrb->proc_class, MRB_OPSYM(aref), m); /* 15.2.17.4.1 */ - mrb_define_class_method(mrb, mrb->kernel_module, "lambda", proc_lambda, MRB_ARGS_NONE()|MRB_ARGS_BLOCK()); /* 15.3.1.2.6 */ mrb_define_method(mrb, mrb->kernel_module, "lambda", proc_lambda, MRB_ARGS_NONE()|MRB_ARGS_BLOCK()); /* 15.3.1.3.27 */ } diff --git a/mruby/src/range.c b/mruby/src/range.c index a81bcd42..7741e90a 100644 --- a/mruby/src/range.c +++ b/mruby/src/range.c @@ -70,7 +70,7 @@ static void range_ptr_alloc_edges(mrb_state *mrb, struct RRange *r) { #ifndef MRB_RANGE_EMBED - r->edges = (mrb_range_edges *)mrb_malloc(mrb, sizeof(mrb_range_edges)); + r->edges = (mrb_range_edges*)mrb_malloc(mrb, sizeof(mrb_range_edges)); #endif } @@ -311,7 +311,6 @@ range_eql(mrb_state *mrb, mrb_value range) struct RRange *r, *o; if (mrb_obj_equal(mrb, range, obj)) return mrb_true_value(); - if (!mrb_obj_is_kind_of(mrb, obj, mrb->range_class)) return mrb_false_value(); if (!mrb_range_p(obj)) return mrb_false_value(); r = mrb_range_ptr(mrb, range); @@ -370,8 +369,10 @@ range_num_to_a(mrb_state *mrb, mrb_value range) len++; } ary = mrb_ary_new_capa(mrb, len); + mrb_value *ptr = RARRAY_PTR(ary); for (mrb_int i=0; i b) { + return mrb_ary_new_capa(mrb, 0); + } ary = mrb_ary_new_capa(mrb, (mrb_int)(b - a) + 1); + mrb_value *ptr = RARRAY_PTR(ary); + mrb_int i = 0; if (RANGE_EXCL(r)) { while (a < b) { - mrb_ary_push(mrb, ary, mrb_int_value(mrb, (mrb_int)a)); + ptr[i++] = mrb_int_value(mrb, (mrb_int)a); + ARY_SET_LEN(RARRAY(ary), i); a += 1.0; } } else { while (a <= b) { - mrb_ary_push(mrb, ary, mrb_int_value(mrb, (mrb_int)a)); + ptr[i++] = mrb_int_value(mrb, (mrb_int)a); + ARY_SET_LEN(RARRAY(ary), i); a += 1.0; } } diff --git a/mruby/src/readfloat.c b/mruby/src/readfloat.c index a89fcafa..80d438ba 100644 --- a/mruby/src/readfloat.c +++ b/mruby/src/readfloat.c @@ -65,7 +65,7 @@ mrb_read_float(const char *str, char **endp, double *fp) if (ISDIGIT(*p)) { while (*p && ISDIGIT(*p)) { - f += base * (*p - '0') ; + f += base * (*p - '0'); base /= 10.0; p++; n++; diff --git a/mruby/src/state.c b/mruby/src/state.c index a1065a20..3f48756e 100644 --- a/mruby/src/state.c +++ b/mruby/src/state.c @@ -20,7 +20,7 @@ void mrb_init_mrbgems(mrb_state*); void mrb_gc_init(mrb_state*, mrb_gc *gc); void mrb_gc_destroy(mrb_state*, mrb_gc *gc); -int mrb_core_init_protect(mrb_state *mrb, void (*body)(mrb_state *, void *), void *opaque); +int mrb_core_init_protect(mrb_state *mrb, void (*body)(mrb_state*, void*), void *opaque); static void init_gc_and_core(mrb_state *mrb, void *opaque) @@ -42,7 +42,7 @@ mrb_open_core(mrb_allocf f, void *ud) mrb_state *mrb; if (f == NULL) f = mrb_default_allocf; - mrb = (mrb_state *)(f)(NULL, NULL, sizeof(mrb_state), ud); + mrb = (mrb_state*)(f)(NULL, NULL, sizeof(mrb_state), ud); if (mrb == NULL) return NULL; *mrb = mrb_state_zero; @@ -207,7 +207,7 @@ mrb_add_irep(mrb_state *mrb) static const mrb_irep mrb_irep_zero = { 0 }; mrb_irep *irep; - irep = (mrb_irep *)mrb_malloc(mrb, sizeof(mrb_irep)); + irep = (mrb_irep*)mrb_malloc(mrb, sizeof(mrb_irep)); *irep = mrb_irep_zero; irep->refcnt = 1; diff --git a/mruby/src/string.c b/mruby/src/string.c index 3e82b1ca..d3c3b2e1 100644 --- a/mruby/src/string.c +++ b/mruby/src/string.c @@ -33,10 +33,10 @@ const char mrb_digitmap[] = "0123456789abcdefghijklmnopqrstuvwxyz"; #endif static void -str_check_too_big(mrb_state *mrb, mrb_int len) +str_check_length(mrb_state *mrb, mrb_int len) { if (len < 0) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "[BUG] negative string length"); + mrb_raise(mrb, E_ARGUMENT_ERROR, "negative (or overflowed) string size"); } #if MRB_STR_LENGTH_MAX != 0 if (len > MRB_STR_LENGTH_MAX-1) { @@ -49,8 +49,8 @@ static struct RString* str_init_normal_capa(mrb_state *mrb, struct RString *s, const char *p, mrb_int len, mrb_int capa) { - str_check_too_big(mrb, capa); - char *dst = (char *)mrb_malloc(mrb, capa + 1); + str_check_length(mrb, capa); + char *dst = (char*)mrb_malloc(mrb, capa + 1); if (p) memcpy(dst, p, len); dst[len] = '\0'; s->as.heap.ptr = dst; @@ -80,7 +80,7 @@ str_init_embed(struct RString *s, const char *p, mrb_int len) static struct RString* str_init_nofree(struct RString *s, const char *p, mrb_int len) { - s->as.heap.ptr = (char *)p; + s->as.heap.ptr = (char*)p; s->as.heap.len = len; s->as.heap.aux.capa = 0; /* nofree */ RSTR_SET_TYPE_FLAG(s, NOFREE); @@ -94,7 +94,7 @@ str_init_shared(mrb_state *mrb, const struct RString *orig, struct RString *s, m shared->refcnt++; } else { - shared = (mrb_shared_string *)mrb_malloc(mrb, sizeof(mrb_shared_string)); + shared = (mrb_shared_string*)mrb_malloc(mrb, sizeof(mrb_shared_string)); shared->refcnt = 1; shared->ptr = orig->as.heap.ptr; shared->capa = orig->as.heap.aux.capa; @@ -137,6 +137,7 @@ str_new_static(mrb_state *mrb, const char *p, mrb_int len) static struct RString* str_new(mrb_state *mrb, const char *p, mrb_int len) { + str_check_length(mrb, len); if (RSTR_EMBEDDABLE_P(len)) { return str_init_embed(mrb_obj_alloc_string(mrb), p, len); } @@ -169,7 +170,7 @@ resize_capa(mrb_state *mrb, struct RString *s, mrb_int capacity) } } else { - str_check_too_big(mrb, capacity); + str_check_length(mrb, capacity); s->as.heap.ptr = (char*)mrb_realloc(mrb, RSTR_PTR(s), capacity+1); s->as.heap.aux.capa = (mrb_ssize)capacity; } @@ -466,11 +467,10 @@ mrb_memsearch_qs(const unsigned char *xs, mrb_int m, const unsigned char *ys, mr else { const unsigned char *x = xs, *xe = xs + m; const unsigned char *y = ys; - int i; ptrdiff_t qstable[256]; /* Preprocessing */ - for (i = 0; i < 256; i++) + for (int i = 0; i < 256; i++) qstable[i] = m + 1; for (; x < xe; x++) qstable[*x] = xe - x; @@ -486,7 +486,7 @@ mrb_memsearch_qs(const unsigned char *xs, mrb_int m, const unsigned char *ys, mr static mrb_int mrb_memsearch(const void *x0, mrb_int m, const void *y0, mrb_int n) { - const unsigned char *x = (const unsigned char *)x0, *y = (const unsigned char *)y0; + const unsigned char *x = (const unsigned char*)x0, *y = (const unsigned char*)y0; if (m > n) return -1; else if (m == n) { @@ -496,14 +496,14 @@ mrb_memsearch(const void *x0, mrb_int m, const void *y0, mrb_int n) return 0; } else if (m == 1) { - const unsigned char *ys = (const unsigned char *)memchr(y, *x, n); + const unsigned char *ys = (const unsigned char*)memchr(y, *x, n); if (ys) return (mrb_int)(ys - y); else return -1; } - return mrb_memsearch_qs((const unsigned char *)x0, m, (const unsigned char *)y0, n); + return mrb_memsearch_qs((const unsigned char*)x0, m, (const unsigned char*)y0, n); } static void @@ -523,7 +523,7 @@ str_share(mrb_state *mrb, struct RString *orig, struct RString *s) } else { if (orig->as.heap.aux.capa > orig->as.heap.len) { - orig->as.heap.ptr = (char *)mrb_realloc(mrb, orig->as.heap.ptr, len+1); + orig->as.heap.ptr = (char*)mrb_realloc(mrb, orig->as.heap.ptr, len+1); orig->as.heap.aux.capa = (mrb_ssize)len; } str_init_shared(mrb, orig, s, NULL); @@ -769,9 +769,7 @@ mrb_str_resize(mrb_state *mrb, mrb_value str, mrb_int len) mrb_int slen; struct RString *s = mrb_str_ptr(str); - if (len < 0) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "negative (or overflowed) string size"); - } + str_check_length(mrb, len); mrb_str_modify(mrb, s); slen = RSTR_LEN(s); if (len != slen) { @@ -1249,19 +1247,16 @@ str_escape(mrb_state *mrb, mrb_value str, mrb_bool inspect) case 033: cc = 'e'; break; default: cc = 0; break; } + buf[0] = '\\'; if (cc) { - buf[0] = '\\'; buf[1] = (char)cc; mrb_str_cat(mrb, result, buf, 2); - continue; } else { - buf[0] = '\\'; buf[1] = 'x'; buf[3] = mrb_digitmap[c % 16]; c /= 16; buf[2] = mrb_digitmap[c % 16]; mrb_str_cat(mrb, result, buf, 4); - continue; } } mrb_str_cat_lit(mrb, result, "\""); @@ -2369,7 +2364,7 @@ mrb_str_len_to_integer(mrb_state *mrb, const char *str, size_t len, mrb_int base #ifdef MRB_USE_BIGINT p2 = p; #endif - for ( ;p= len2) { + memmove(RSTR_PTR(s)+idx1, RSTRING_PTR(replace)+idx2, len2); + if (len1 > len2) { + memmove(RSTR_PTR(s)+idx1+len2, RSTR_PTR(s)+idx1+len1, RSTR_LEN(s)-(idx1+len1)); + RSTR_SET_LEN(s, RSTR_LEN(s)-(len1-len2)); + } + } + else { /* len1 < len2 */ + mrb_int slen = RSTR_LEN(s); + mrb_str_resize(mrb, str, slen+len2-len1); + memmove(RSTR_PTR(s)+idx1+len2, RSTR_PTR(s)+idx1+len1, slen-(idx1+len1)); + memmove(RSTR_PTR(s)+idx1, RSTRING_PTR(replace)+idx2, len2); + } + return str; +} + +/* + * call-seq: + * bytesplice(index, length, str) -> string + * bytesplice(index, length, str, str_index, str_length) -> string + * bytesplice(range, str) -> string + * bytesplice(range, str, str_range) -> string + * + * Replaces some or all of the content of +self+ with +str+, and returns +self+. + * The portion of the string affected is determined using + * the same criteria as String#byteslice, except that +length+ cannot be omitted. + * If the replacement string is not the same length as the text it is replacing, + * the string will be adjusted accordingly. + * + * If +str_index+ and +str_length+, or +str_range+ are given, the content of +self+ is replaced by str.byteslice(str_index, str_length) or str.byteslice(str_range); however the substring of +str+ is not allocated as a new string. + * + * The form that take an Integer will raise an IndexError if the value is out + * of range; the Range form will raise a RangeError. + * If the beginning or ending offset does not land on character (codepoint) + * boundary, an IndexError will be raised. + */ +static mrb_value +mrb_str_bytesplice(mrb_state *mrb, mrb_value str) +{ + mrb_int idx1, len1, idx2, len2; + mrb_value range1, range2, replace; + switch (mrb_get_argc(mrb)) { + case 3: + mrb_get_args(mrb, "ooo", &range1, &replace, &range2); + if (mrb_integer_p(range1)) { + mrb_get_args(mrb, "iiS", &idx1, &len1, &replace); + return str_bytesplice(mrb, str, idx1, len1, replace, 0, RSTRING_LEN(replace)); + } + mrb_ensure_string_type(mrb, replace); + if (mrb_range_beg_len(mrb, range1, &idx1, &len1, RSTRING_LEN(str), FALSE) != MRB_RANGE_OK) break; + if (mrb_range_beg_len(mrb, range2, &idx2, &len2, RSTRING_LEN(replace), FALSE) != MRB_RANGE_OK) break; + return str_bytesplice(mrb, str, idx1, len1, replace, idx2, len2); + case 5: + mrb_get_args(mrb, "iiSii", &idx1, &len1, &replace, &idx2, &len2); + return str_bytesplice(mrb, str, idx1, len1, replace, idx2, len2); + case 2: + mrb_get_args(mrb, "oS", &range1, &replace); + if (mrb_range_beg_len(mrb, range1, &idx1, &len1, RSTRING_LEN(str), FALSE) == MRB_RANGE_OK) { + return str_bytesplice(mrb, str, idx1, len1, replace, 0, RSTRING_LEN(replace)); + } + default: + break; + } + mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arumgnts"); +} + /* ---------------------------*/ void mrb_init_string(mrb_state *mrb) @@ -3008,6 +3094,7 @@ mrb_init_string(mrb_state *mrb) mrb_define_method(mrb, s, "byteindex", mrb_str_byteindex_m, MRB_ARGS_ARG(1,1)); mrb_define_method(mrb, s, "byterindex", mrb_str_byterindex_m, MRB_ARGS_ARG(1,1)); mrb_define_method(mrb, s, "byteslice", mrb_str_byteslice, MRB_ARGS_ARG(1,1)); + mrb_define_method(mrb, s, "bytesplice", mrb_str_bytesplice, MRB_ARGS_ANY()); mrb_define_method(mrb, s, "__sub_replace", sub_replace, MRB_ARGS_REQ(3)); /* internal */ } diff --git a/mruby/src/symbol.c b/mruby/src/symbol.c index c707a9d9..ffac3437 100644 --- a/mruby/src/symbol.c +++ b/mruby/src/symbol.c @@ -82,12 +82,11 @@ sym_inline_pack(const char *name, size_t len) char c; const char *p; - size_t i; mrb_sym sym = 0; if (len > pack_length_max) return 0; /* too long */ if (len == 0) return 0; /* empty string */ - for (i=0; isymflags[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)) -#define sym_len(mrb, i) (size_t)(sym_lit_p(mrb, i)?strlen(mrb->symtbl[i]):mrb_packed_int_decode(mrb->symtbl[i],NULL)) static mrb_bool sym_check(mrb_state *mrb, const char *name, size_t len, mrb_sym i) @@ -208,15 +206,15 @@ sym_intern(mrb_state *mrb, const char *name, size_t len, mrb_bool lit) mrb->symcapa = symcapa; } sym_flags_clear(mrb, sym); - if ((lit || mrb_ro_data_p(name)) && strlen(name) == len) { + if ((lit || mrb_ro_data_p(name)) && name[len] == 0 && strlen(name) == len) { sym_lit_set(mrb, sym); mrb->symtbl[sym] = name; } else { 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(ulen, (uint8_t*)p, (uint8_t*)p+ilen); + char *p = (char*)mrb_malloc(mrb, len+ilen+1); + mrb_packed_int_encode(ulen, (uint8_t*)p); memcpy(p+ilen, name, len); p[ilen+len] = 0; mrb->symtbl[sym] = p; @@ -353,7 +351,7 @@ mrb_free_symtbl(mrb_state *mrb) { mrb_sym i, lim; - for (i=1, lim=mrb->symidx+1; isymidx+1; isymtbl[i]); } diff --git a/mruby/src/variable.c b/mruby/src/variable.c index be27f0ed..4c51a8a6 100644 --- a/mruby/src/variable.c +++ b/mruby/src/variable.c @@ -47,7 +47,6 @@ iv_rehash(mrb_state *mrb, iv_tbl *t) mrb_value *old_ptr = t->ptr; khash_power2(new_alloc); - if (old_alloc == new_alloc) return; t->ptr = (mrb_value*)mrb_calloc(mrb, sizeof(mrb_value)+sizeof(mrb_sym), new_alloc); t->size = 0; @@ -70,7 +69,6 @@ iv_put(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value val) { int hash, pos, start, dpos = -1; - if (t == NULL) return; if (t->alloc == 0) { iv_rehash(mrb, t); } @@ -177,15 +175,13 @@ iv_del(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp) static void iv_foreach(mrb_state *mrb, iv_tbl *t, mrb_iv_foreach_func *func, void *p) { - int i; - if (t == NULL) return; if (t->alloc == 0) return; if (t->size == 0) return; mrb_sym *keys = (mrb_sym*)&t->ptr[t->alloc]; mrb_value *vals = t->ptr; - for (i=0; ialloc; i++) { + for (int i=0; ialloc; i++) { if (IV_KEY_P(keys[i])) { if ((*func)(mrb, keys[i], vals[i], p) != 0) { return; @@ -209,7 +205,6 @@ static iv_tbl* iv_copy(mrb_state *mrb, iv_tbl *t) { iv_tbl *t2; - int i; if (t == NULL) return NULL; if (t->alloc == 0) return NULL; @@ -218,7 +213,7 @@ iv_copy(mrb_state *mrb, iv_tbl *t) mrb_sym *keys = (mrb_sym*)&t->ptr[t->alloc]; mrb_value *vals = t->ptr; t2 = iv_new(mrb); - for (i=0; ialloc; i++) { + for (int i=0; ialloc; i++) { if (IV_KEY_P(keys[i])) { iv_put(mrb, t2, keys[i], vals[i]); } @@ -327,34 +322,6 @@ mrb_iv_get(mrb_state *mrb, mrb_value obj, mrb_sym sym) return mrb_nil_value(); } -static inline void assign_class_name(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v); - -void -mrb_obj_iv_set_force(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v) -{ - assign_class_name(mrb, obj, sym, v); - if (!obj->iv) { - obj->iv = iv_new(mrb); - } - iv_put(mrb, obj->iv, sym, v); - mrb_field_write_barrier_value(mrb, (struct RBasic*)obj, v); -} - -MRB_API void -mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v) -{ - mrb_check_frozen(mrb, obj); - mrb_obj_iv_set_force(mrb, obj, sym, v); -} - -/* Iterates over the instance variable table. */ -MRB_API void -mrb_iv_foreach(mrb_state *mrb, mrb_value obj, mrb_iv_foreach_func *func, void *p) -{ - if (!obj_iv_p(obj)) return; - iv_foreach(mrb, mrb_obj_ptr(obj)->iv, func, p); -} - static inline mrb_bool namespace_p(enum mrb_vtype tt) { @@ -364,7 +331,7 @@ namespace_p(enum mrb_vtype tt) static inline void assign_class_name(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v) { - if (namespace_p(obj->tt) && namespace_p(mrb_type(v))) { + if (namespace_p(mrb_type(v))) { struct RObject *c = mrb_obj_ptr(v); if (obj != c && ISUPPER(mrb_sym_name_len(mrb, sym, NULL)[0])) { mrb_sym id_classname = MRB_SYM(__classname__); @@ -375,7 +342,7 @@ assign_class_name(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v) o = mrb_obj_iv_get(mrb, c, id_outer); if (mrb_nil_p(o)) { - if ((struct RClass *)obj == mrb->object_class) { + if ((struct RClass*)obj == mrb->object_class) { mrb_obj_iv_set_force(mrb, c, id_classname, mrb_symbol_value(sym)); } else { @@ -387,6 +354,34 @@ assign_class_name(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v) } } +void +mrb_obj_iv_set_force(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v) +{ + if (namespace_p(obj->tt)) { + assign_class_name(mrb, obj, sym, v); + } + if (!obj->iv) { + obj->iv = iv_new(mrb); + } + iv_put(mrb, obj->iv, sym, v); + mrb_field_write_barrier_value(mrb, (struct RBasic*)obj, v); +} + +MRB_API void +mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v) +{ + mrb_check_frozen(mrb, obj); + mrb_obj_iv_set_force(mrb, obj, sym, v); +} + +/* Iterates over the instance variable table. */ +MRB_API void +mrb_iv_foreach(mrb_state *mrb, mrb_value obj, mrb_iv_foreach_func *func, void *p) +{ + if (!obj_iv_p(obj)) return; + iv_foreach(mrb, mrb_obj_ptr(obj)->iv, func, p); +} + MRB_API void mrb_iv_set(mrb_state *mrb, mrb_value obj, mrb_sym sym, mrb_value v) { @@ -472,12 +467,7 @@ inspect_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p) s = mrb_sym_name_len(mrb, sym, &len); mrb_str_cat(mrb, str, s, len); mrb_str_cat_lit(mrb, str, "="); - if (mrb_object_p(v)) { - ins = mrb_any_to_s(mrb, v); - } - else { - ins = mrb_inspect(mrb, v); - } + ins = mrb_inspect(mrb, v); mrb_str_cat_str(mrb, str, ins); return 0; } @@ -497,6 +487,10 @@ mrb_obj_iv_inspect(mrb_state *mrb, struct RObject *obj) mrb_str_cat_lit(mrb, str, ":"); mrb_str_cat_str(mrb, str, mrb_ptr_to_str(mrb, obj)); + if (mrb_inspect_recursive_p(mrb, mrb_obj_value(obj))) { + mrb_str_cat_lit(mrb, str, " ...>"); + return str; + } iv_foreach(mrb, t, inspect_i, &str); mrb_str_cat_lit(mrb, str, ">"); return str; @@ -508,10 +502,11 @@ MRB_API mrb_value mrb_iv_remove(mrb_state *mrb, mrb_value obj, mrb_sym sym) { if (obj_iv_p(obj)) { - iv_tbl *t = mrb_obj_ptr(obj)->iv; + struct RObject *o = mrb_obj_ptr(obj); + iv_tbl *t = o->iv; mrb_value val; - mrb_check_frozen(mrb, mrb_obj_ptr(obj)); + mrb_check_frozen(mrb, o); if (iv_del(mrb, t, sym, &val)) { return val; } @@ -629,7 +624,7 @@ mrb_mod_cv_get(mrb_state *mrb, struct RClass *c, mrb_sym sym) if (cls && cls->tt == MRB_TT_SCLASS) { mrb_value klass; - klass = mrb_obj_iv_get(mrb, (struct RObject *)cls, MRB_SYM(__attached__)); + klass = mrb_obj_iv_get(mrb, (struct RObject*)cls, MRB_SYM(__attached__)); c = mrb_class_ptr(klass); if (c->tt == MRB_TT_CLASS || c->tt == MRB_TT_MODULE) { given = FALSE; @@ -772,26 +767,28 @@ const_get(mrb_state *mrb, struct RClass *base, mrb_sym sym, mrb_bool skip) struct RClass *c = base; mrb_value v; 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) { - if (!MRB_FLAG_TEST(c, MRB_FL_CLASS_IS_PREPENDED) && c->iv) { - if (iv_get(mrb, c->iv, sym, &v)) - return v; + if (!MRB_FLAG_TEST(c, MRB_FL_CLASS_IS_PREPENDED) && c->iv && iv_get(mrb, c->iv, sym, &v)) { + return v; } c = c->super; if (!skip && c == mrb->object_class) break; } - if (!retry && base->tt == MRB_TT_MODULE) { + if (!retry && base->tt == MRB_TT_MODULE && skip) { c = mrb->object_class; retry = TRUE; goto L_RETRY; } - name = mrb_symbol_value(sym); - return mrb_funcall_argv(mrb, mrb_obj_value(base), MRB_SYM(const_missing), 1, &name); + mrb_value mod = mrb_obj_value(base); + if (mrb_func_basic_p(mrb, mod, MRB_SYM(const_missing), mrb_mod_const_missing)) { + return mrb_const_missing(mrb, mod, sym); + } + mrb_value name = mrb_symbol_value(sym); + return mrb_funcall_argv(mrb, mod, MRB_SYM(const_missing), 1, &name); } MRB_API mrb_value @@ -1137,9 +1134,7 @@ mrb_obj_iv_tbl_memsize(mrb_value obj) mrb_bool mrb_ident_p(const char *s, mrb_int len) { - mrb_int i; - - for (i = 0; i < len; i++) { + for (mrb_int i = 0; i < len; i++) { if (!identchar(s[i])) return FALSE; } return TRUE; diff --git a/mruby/src/vm.c b/mruby/src/vm.c index 475f02ab..47457b12 100644 --- a/mruby/src/vm.c +++ b/mruby/src/vm.c @@ -65,7 +65,7 @@ mrb_gc_arena_shrink(mrb_state *mrb, int idx) mrb_gc *gc = &mrb->gc; int capa = gc->arena_capa; - mrb->gc.arena_idx = idx; + gc->arena_idx = idx; if (idx < capa / 4) { capa >>= 2; if (capa < MRB_GC_ARENA_SIZE) { @@ -106,11 +106,11 @@ stack_init(mrb_state *mrb) struct mrb_context *c = mrb->c; /* mrb_assert(mrb->stack == NULL); */ - c->stbase = (mrb_value *)mrb_calloc(mrb, STACK_INIT_SIZE, sizeof(mrb_value)); + c->stbase = (mrb_value*)mrb_calloc(mrb, STACK_INIT_SIZE, sizeof(mrb_value)); c->stend = c->stbase + STACK_INIT_SIZE; /* mrb_assert(ci == NULL); */ - c->cibase = (mrb_callinfo *)mrb_calloc(mrb, CALLINFO_INIT_SIZE, sizeof(mrb_callinfo)); + c->cibase = (mrb_callinfo*)mrb_calloc(mrb, CALLINFO_INIT_SIZE, sizeof(mrb_callinfo)); c->ciend = c->cibase + CALLINFO_INIT_SIZE; c->ci = c->cibase; c->ci->u.target_class = mrb->object_class; @@ -121,36 +121,33 @@ static inline void envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t oldsize) { mrb_callinfo *ci = mrb->c->cibase; + ptrdiff_t delta = newbase - oldbase; - if (newbase == oldbase) return; + if (delta == 0) return; while (ci <= mrb->c->ci) { struct REnv *e = mrb_vm_ci_env(ci); mrb_value *st; if (e && MRB_ENV_ONSTACK_P(e) && - (st = e->stack) && oldbase <= st && st < oldbase+oldsize) { - ptrdiff_t off = e->stack - oldbase; - - e->stack = newbase + off; + (st = e->stack) && (size_t)(st - oldbase) < oldsize) { + e->stack += delta; } if (ci->proc && MRB_PROC_ENV_P(ci->proc) && e != MRB_PROC_ENV(ci->proc)) { e = MRB_PROC_ENV(ci->proc); if (e && MRB_ENV_ONSTACK_P(e) && - (st = e->stack) && oldbase <= st && st < oldbase+oldsize) { - ptrdiff_t off = e->stack - oldbase; - - e->stack = newbase + off; + (st = e->stack) && (size_t)(st - oldbase) < oldsize) { + e->stack += delta; } } - ci->stack = newbase + (ci->stack - oldbase); + ci->stack += delta; ci++; } } -/** def rec ; $deep =+ 1 ; if $deep > 1000 ; return 0 ; end ; rec ; end */ +/** def rec; $deep =+ 1; if $deep > 1000; return 0; end; rec; end **/ static void stack_extend_alloc(mrb_state *mrb, mrb_int room) @@ -177,7 +174,7 @@ stack_extend_alloc(mrb_state *mrb, mrb_int room) size += room; #endif - newstack = (mrb_value *)mrb_realloc(mrb, mrb->c->stbase, sizeof(mrb_value) * size); + newstack = (mrb_value*)mrb_realloc(mrb, mrb->c->stbase, sizeof(mrb_value) * size); stack_clear(&(newstack[oldsize]), size - oldsize); envadjust(mrb, oldbase, newstack, oldsize); mrb->c->stbase = newstack; @@ -190,14 +187,20 @@ stack_extend_alloc(mrb_state *mrb, mrb_int room) } } -MRB_API void -mrb_stack_extend(mrb_state *mrb, mrb_int room) +static inline void +stack_extend(mrb_state *mrb, mrb_int room) { if (!mrb->c->ci->stack || mrb->c->ci->stack + room >= mrb->c->stend) { stack_extend_alloc(mrb, room); } } +MRB_API void +mrb_stack_extend(mrb_state *mrb, mrb_int room) +{ + stack_extend(mrb, room); +} + static void stack_extend_adjust(mrb_state *mrb, mrb_int room, const mrb_value **argp) { @@ -205,10 +208,10 @@ stack_extend_adjust(mrb_state *mrb, mrb_int room, const mrb_value **argp) ptrdiff_t voff = *argp - c->stbase; if (voff < 0 || voff >= c->stend - c->stbase) { - mrb_stack_extend(mrb, room); + stack_extend(mrb, room); } else { - mrb_stack_extend(mrb, room); + stack_extend(mrb, room); *argp = c->stbase + voff; } } @@ -252,7 +255,7 @@ top_proc(mrb_state *mrb, const struct RProc *proc) #define CI_PROC_SET(ci, p) do {\ ci->proc = p;\ - ci->pc = (p && !MRB_PROC_CFUNC_P(p)) ? p->body.irep->iseq : NULL;\ + ci->pc = (p && !MRB_PROC_CFUNC_P(p) && p->body.irep) ? p->body.irep->iseq : NULL;\ } while (0) void @@ -289,8 +292,8 @@ mrb_vm_ci_env(const mrb_callinfo *ci) return CI_ENV(ci); } -void -mrb_vm_ci_env_set(mrb_callinfo *ci, struct REnv *e) +static inline void +ci_env_set(mrb_callinfo *ci, struct REnv *e) { if (ci->u.env) { if (ci->u.env->tt == MRB_TT_ENV) { @@ -302,11 +305,9 @@ mrb_vm_ci_env_set(mrb_callinfo *ci, struct REnv *e) ci->u.target_class = ci->u.env->c; } } - else { - if (e) { - e->c = ci->u.target_class; - ci->u.env = e; - } + else if (e) { + e->c = ci->u.target_class; + ci->u.env = e; } } else { @@ -314,10 +315,26 @@ mrb_vm_ci_env_set(mrb_callinfo *ci, struct REnv *e) } } -#define CINFO_NONE 0 -#define CINFO_SKIP 1 -#define CINFO_DIRECT 2 -#define CINFO_RESUMED 3 +void +mrb_vm_ci_env_set(mrb_callinfo *ci, struct REnv *e) +{ + ci_env_set(ci, e); +} + +MRB_API void +mrb_vm_ci_env_clear(mrb_state *mrb, mrb_callinfo *ci) +{ + struct REnv *e = ci->u.env; + if (e && e->tt == MRB_TT_ENV) { + ci->u.target_class = e->c; + mrb_env_unshare(mrb, e, FALSE); + } +} + +#define CINFO_NONE 0 // called method from mruby VM (without C functions) +#define CINFO_SKIP 1 // ignited mruby VM from C +#define CINFO_DIRECT 2 // called method from C +#define CINFO_RESUMED 3 // resumed by `Fiber.yield` (probably the main call is `mrb_fiber_resume()`) #define BLK_PTR(b) ((mrb_proc_p(b)) ? mrb_proc_ptr(b) : NULL) @@ -334,7 +351,7 @@ cipush(mrb_state *mrb, mrb_int push_stacks, uint8_t cci, struct RClass *target_c if (size > MRB_CALL_LEVEL_MAX) { mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); } - c->cibase = (mrb_callinfo *)mrb_realloc(mrb, c->cibase, sizeof(mrb_callinfo)*size*2); + c->cibase = (mrb_callinfo*)mrb_realloc(mrb, c->cibase, sizeof(mrb_callinfo)*size*2); c->ci = c->cibase + size; c->ciend = c->cibase + size * 2; } @@ -367,8 +384,8 @@ mrb_env_unshare(mrb_state *mrb, struct REnv *e, mrb_bool noraise) } size_t live = mrb->gc.live; - mrb_value *p = (mrb_value *)mrb_malloc_simple(mrb, sizeof(mrb_value)*len); - if (live != mrb->gc.live && mrb_object_dead_p(mrb, (struct RBasic *)e)) { + mrb_value *p = (mrb_value*)mrb_malloc_simple(mrb, sizeof(mrb_value)*len); + if (live != mrb->gc.live && mrb_object_dead_p(mrb, (struct RBasic*)e)) { // The e object is now subject to GC inside mrb_malloc_simple(). // Moreover, if NULL is returned due to mrb_malloc_simple() failure, simply ignore it. mrb_free(mrb, p); @@ -378,7 +395,7 @@ mrb_env_unshare(mrb_state *mrb, struct REnv *e, mrb_bool noraise) stack_copy(p, e->stack, len); e->stack = p; MRB_ENV_CLOSE(e); - mrb_write_barrier(mrb, (struct RBasic *)e); + mrb_write_barrier(mrb, (struct RBasic*)e); return TRUE; } else { @@ -400,7 +417,7 @@ cipop(mrb_state *mrb) mrb_callinfo *ci = c->ci; struct REnv *env = CI_ENV(ci); - mrb_vm_ci_env_set(ci, NULL); // make possible to free by GC if env is not needed + ci_env_set(ci, NULL); // make possible to free env by GC if not needed struct RProc *b = ci->blk; if (b && !mrb_object_dead_p(mrb, (struct RBasic*)b) && b->tt == MRB_TT_PROC && !MRB_PROC_STRICT_P(b) && MRB_PROC_ENV(b) == CI_ENV(&ci[-1])) { @@ -469,7 +486,6 @@ mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, mrb_int argc, ...) { mrb_value argv[MRB_FUNCALL_ARGC_MAX]; va_list ap; - mrb_int i; mrb_sym mid = mrb_intern_cstr(mrb, name); if (argc > MRB_FUNCALL_ARGC_MAX) { @@ -477,7 +493,7 @@ mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, mrb_int argc, ...) } va_start(ap, argc); - for (i = 0; i < argc; i++) { + for (mrb_int i = 0; i < argc; i++) { argv[i] = va_arg(ap, mrb_value); } va_end(ap); @@ -489,14 +505,13 @@ mrb_funcall_id(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc, ...) { mrb_value argv[MRB_FUNCALL_ARGC_MAX]; va_list ap; - mrb_int i; if (argc > MRB_FUNCALL_ARGC_MAX) { mrb_raise(mrb, E_ARGUMENT_ERROR, "Too long arguments. (limit=" MRB_STRINGIZE(MRB_FUNCALL_ARGC_MAX) ")"); } va_start(ap, argc); - for (i = 0; i < argc; i++) { + for (mrb_int i = 0; i < argc; i++) { argv[i] = va_arg(ap, mrb_value); } va_end(ap); @@ -519,10 +534,16 @@ mrb_bidx(uint8_t n, uint8_t k) return n + 1; /* self + args + kargs */ } +static inline mrb_int +ci_bidx(mrb_callinfo *ci) +{ + return mrb_bidx(ci->n, ci->nk); +} + mrb_int mrb_ci_bidx(mrb_callinfo *ci) { - return mrb_bidx(ci->n, ci->nk); + return ci_bidx(ci); } mrb_int @@ -531,7 +552,7 @@ mrb_ci_nregs(mrb_callinfo *ci) const struct RProc *p; if (!ci) return 4; - mrb_int nregs = mrb_ci_bidx(ci) + 1; /* self + args + kargs + blk */ + mrb_int nregs = 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; @@ -564,7 +585,7 @@ prepare_missing(mrb_state *mrb, mrb_callinfo *ci, mrb_value recv, mrb_sym mid, m } m = mrb_vm_find_method(mrb, ci->u.target_class, &ci->u.target_class, missing); if (MRB_METHOD_UNDEF_P(m)) goto method_missing; /* just in case */ - mrb_stack_extend(mrb, 4); + stack_extend(mrb, 4); argv = &ci->stack[1]; /* maybe reallocated */ argv[0] = args; @@ -611,7 +632,7 @@ funcall_args_capture(mrb_state *mrb, int stoff, mrb_int argc, const mrb_value *a } } -static mrb_value +static inline mrb_value ensure_block(mrb_state *mrb, mrb_value blk) { if (!mrb_nil_p(blk) && !mrb_proc_p(blk)) { @@ -635,7 +656,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc mrb->jmp = &c_jmp; /* recursive call */ val = mrb_funcall_with_block(mrb, self, mid, argc, argv, blk); - mrb->jmp = 0; + mrb->jmp = NULL; } MRB_CATCH(&c_jmp) { /* error */ while (nth_ci < (mrb->c->ci - mrb->c->cibase)) { @@ -645,7 +666,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc val = mrb_obj_value(mrb->exc); } MRB_END_EXC(&c_jmp); - mrb->jmp = 0; + mrb->jmp = NULL; } else { mrb_method_t m; @@ -722,12 +743,12 @@ exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p) return MRB_PROC_CFUNC(p)(mrb, self); } nregs = p->body.irep->nregs; - keep = mrb_ci_bidx(ci)+1; + keep = ci_bidx(ci)+1; if (nregs < keep) { - mrb_stack_extend(mrb, keep); + stack_extend(mrb, keep); } else { - mrb_stack_extend(mrb, nregs); + stack_extend(mrb, nregs); stack_clear(ci->stack+keep, nregs-keep); } @@ -754,7 +775,7 @@ mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p) cipop(mrb); } else { - mrb_int keep = mrb_ci_bidx(ci) + 1; /* receiver + block */ + mrb_int keep = ci_bidx(ci) + 1; /* receiver + block */ ret = mrb_top_run(mrb, p, self, keep); } if (mrb->exc && mrb->jmp) { @@ -882,7 +903,7 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c) ci->nk = 0; ci->mid = ci[-1].mid; if (MRB_PROC_CFUNC_P(p)) { - mrb_stack_extend(mrb, 4); + stack_extend(mrb, 4); mrb->c->ci->stack[0] = self; mrb->c->ci->stack[1] = self; mrb->c->ci->stack[2] = mrb_nil_value(); @@ -890,7 +911,7 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c) } nregs = p->body.irep->nregs; if (nregs < 4) nregs = 4; - mrb_stack_extend(mrb, nregs); + stack_extend(mrb, nregs); mrb->c->ci->stack[0] = self; mrb->c->ci->stack[1] = self; stack_clear(mrb->c->ci->stack+2, nregs-2); @@ -956,7 +977,7 @@ MRB_API mrb_value mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value *argv, mrb_value self, struct RClass *c) { struct RProc *p; - mrb_sym mid = mrb->c->ci->mid; + mrb_sym mid; mrb_callinfo *ci; mrb_value val; mrb_int n; @@ -965,10 +986,15 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value ci = mrb->c->ci; n = mrb_ci_nregs(ci); p = mrb_proc_ptr(b); - ci = cipush(mrb, n, CINFO_DIRECT, NULL, NULL, NULL, 0, 0); + if (MRB_PROC_ENV_P(p)) { + mid = p->e.env->mid; + } + else { + mid = ci->mid; + } + ci = cipush(mrb, n, CINFO_DIRECT, NULL, NULL, NULL, mid, 0); funcall_args_capture(mrb, 0, argc, argv, mrb_nil_value(), ci); ci->u.target_class = c; - ci->mid = mid; ci->proc = p; if (MRB_PROC_CFUNC_P(p)) { @@ -987,16 +1013,20 @@ MRB_API mrb_value mrb_yield_argv(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value *argv) { struct RProc *p = mrb_proc_ptr(b); + struct RClass *tc; + mrb_value self = mrb_proc_get_self(mrb, p, &tc); - return mrb_yield_with_class(mrb, b, argc, argv, MRB_PROC_ENV(p)->stack[0], MRB_PROC_TARGET_CLASS(p)); + return mrb_yield_with_class(mrb, b, argc, argv, self, tc); } MRB_API mrb_value mrb_yield(mrb_state *mrb, mrb_value b, mrb_value arg) { struct RProc *p = mrb_proc_ptr(b); + struct RClass *tc; + mrb_value self = mrb_proc_get_self(mrb, p, &tc); - return mrb_yield_with_class(mrb, b, 1, &arg, MRB_PROC_ENV(p)->stack[0], MRB_PROC_TARGET_CLASS(p)); + return mrb_yield_with_class(mrb, b, 1, &arg, self, tc); } mrb_value @@ -1081,7 +1111,7 @@ catch_handler_find(mrb_state *mrb, mrb_callinfo *ci, const mrb_code *pc, uint32_ if (ci->proc == NULL || MRB_PROC_CFUNC_P(ci->proc)) return NULL; irep = ci->proc->body.irep; - if (irep->clen < 1) return NULL; + if (irep == NULL || irep->clen < 1) return NULL; xpc = pc - irep->iseq; /* If it retry at the top level, pc will be 0, so check with -1 as the start position */ mrb_assert(catch_cover_p(xpc, -1, irep->ilen)); @@ -1230,13 +1260,13 @@ prepare_tagged_break(mrb_state *mrb, uint32_t tag, const struct RProc *proc, mrb #define BYTECODE_DECODER(x) (x) #endif -#ifndef MRB_NO_DIRECT_THREADING -#if defined __GNUC__ || defined __clang__ || defined __INTEL_COMPILER -#define DIRECT_THREADED +#ifndef MRB_USE_VM_SWITCH_DISPATCH +#if !defined __GNUC__ && !defined __clang__ && !defined __INTEL_COMPILER +#define MRB_USE_VM_SWITCH_DISPATCH #endif -#endif /* ifndef MRB_NO_DIRECT_THREADING */ +#endif /* ifndef MRB_USE_VM_SWITCH_DISPATCH */ -#ifndef DIRECT_THREADED +#ifdef MRB_USE_VM_SWITCH_DISPATCH #define INIT_DISPATCH for (;;) { insn = BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); switch (insn) { #define CASE(insn,ops) case insn: pc++; FETCH_ ## ops (); mrb->c->ci->pc = pc; L_ ## insn ## _BODY: @@ -1272,11 +1302,11 @@ mrb_vm_run(mrb_state *mrb, const struct RProc *proc, mrb_value self, mrb_int sta else { struct REnv *e = CI_ENV(mrb->c->ci); if (stack_keep == 0 || (e && irep->nlocals < MRB_ENV_LEN(e))) { - mrb_vm_ci_env_set(mrb->c->ci, NULL); + ci_env_set(mrb->c->ci, NULL); mrb_env_unshare(mrb, e, FALSE); } } - mrb_stack_extend(mrb, nregs); + stack_extend(mrb, nregs); stack_clear(c->ci->stack + stack_keep, nregs - stack_keep); c->ci->stack[0] = self; result = mrb_vm_exec(mrb, proc, irep->iseq); @@ -1315,16 +1345,7 @@ hash_new_from_regs(mrb_state *mrb, mrb_int argc, mrb_int idx) return hash; } -static mrb_value -ary_new_from_regs(mrb_state *mrb, mrb_int argc, mrb_int idx) -{ - mrb_value ary = mrb_ary_new_capa(mrb, argc); - while (argc--) { - mrb_ary_push(mrb, ary, regs[idx]); - idx++; - } - return ary; -} +#define ary_new_from_regs(mrb, argc, idx) mrb_ary_new_from_values(mrb, (argc), ®s[idx]); MRB_API mrb_value mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) @@ -1343,7 +1364,7 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) mrb_sym mid; const struct mrb_irep_catch_handler *ch; -#ifdef DIRECT_THREADED +#ifndef MRB_USE_VM_SWITCH_DISPATCH static const void * const optable[] = { #define OPCODE(x,_) &&L_OP_ ## x, #include "mruby/ops.h" @@ -1526,7 +1547,15 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) switch (mrb_type(va)) { case MRB_TT_ARRAY: if (!mrb_integer_p(vb)) goto getidx_fallback; - regs[a] = mrb_ary_entry(va, mrb_integer(vb)); + else { + mrb_int idx = mrb_integer(vb); + if (0 <= idx && idx < RARRAY_LEN(va)) { + regs[a] = RARRAY_PTR(va)[idx]; + } + else { + regs[a] = mrb_ary_entry(va, idx); + } + } break; case MRB_TT_HASH: va = mrb_hash_get(mrb, va, vb); @@ -1582,14 +1611,13 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) } CASE(OP_GETUPVAR, BBB) { - mrb_value *regs_a = regs + a; struct REnv *e = uvenv(mrb, c); if (e && b < MRB_ENV_LEN(e)) { - *regs_a = e->stack[b]; + regs[a] = e->stack[b]; } else { - *regs_a = mrb_nil_value(); + regs[a] = mrb_nil_value(); } NEXT; } @@ -1598,10 +1626,8 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) struct REnv *e = uvenv(mrb, c); if (e) { - mrb_value *regs_a = regs + a; - if (b < MRB_ENV_LEN(e)) { - e->stack[b] = *regs_a; + e->stack[b] = regs[a]; mrb_write_barrier(mrb, (struct RBasic*)e); } } @@ -1742,6 +1768,7 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) int n = c&0xf; int nk = (c>>4)&0xf; mrb_int bidx = a + mrb_bidx(n,nk); + mrb_int new_bidx = bidx; if (nk == CALL_MAXARGS) { mrb_ensure_hash_type(mrb, regs[a+(n==CALL_MAXARGS?1:n)+1]); @@ -1752,10 +1779,10 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) regs[kidx] = kdict; nk = CALL_MAXARGS; c = n | (nk<<4); + new_bidx = a+mrb_bidx(n, nk); } mrb_assert(bidx < irep->nregs); - mrb_int new_bidx = a+mrb_bidx(n, nk); if (insn == OP_SEND) { /* clear block argument */ SET_NIL_VALUE(regs[new_bidx]); @@ -1777,7 +1804,6 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) ci->mid = mid; } ci->cci = CINFO_NONE; - if (!mrb_nil_p(blk)) ci->blk = mrb_proc_ptr(blk); if (MRB_METHOD_CFUNC_P(m)) { if (MRB_METHOD_PROC_P(m)) { @@ -1819,7 +1845,7 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) irep = proc->body.irep; pool = irep->pool; syms = irep->syms; - mrb_stack_extend(mrb, (irep->nregs < 4) ? 4 : irep->nregs); + stack_extend(mrb, (irep->nregs < 4) ? 4 : irep->nregs); pc = irep->iseq; } } @@ -1858,9 +1884,9 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) c = OP_R_NORMAL; goto L_OP_RETURN_BODY; } - mrb_int nargs = mrb_ci_bidx(ci)+1; + mrb_int nargs = ci_bidx(ci)+1; if (nargs < irep->nregs) { - mrb_stack_extend(mrb, irep->nregs); + stack_extend(mrb, irep->nregs); stack_clear(regs+nargs, irep->nregs-nargs); } if (MRB_PROC_ENV_P(m)) { @@ -1968,7 +1994,7 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) /* no other args */ if ((a & ~0x7c0001) == 0 && argc < 15 && MRB_PROC_STRICT_P(proc)) { - if (argc != m1) { + if (argc+(ci->nk==15) != m1) { /* count kdict too */ argnum_error(mrb, m1); goto L_RAISE; } @@ -1990,7 +2016,7 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) mrb_int const len = m1 + o + r + m2; mrb_value * const argv0 = argv; - mrb_value blk = regs[mrb_ci_bidx(ci)]; + mrb_value blk = regs[ci_bidx(ci)]; mrb_value kdict = mrb_nil_value(); /* keyword arguments */ @@ -2019,6 +2045,9 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) else if (MRB_ASPEC_KEY(a) > 0 && !mrb_nil_p(kdict)) { kdict = mrb_hash_dup(mrb, kdict); } + else if (!mrb_nil_p(kdict)) { + mrb_gc_protect(mrb, kdict); + } /* arguments is passed with Array */ if (argc == 15) { @@ -2026,7 +2055,6 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) argv = ARY_PTR(ary); argc = (int)ARY_LEN(ary); mrb_gc_protect(mrb, regs[1]); - if (kd && !mrb_nil_p(kdict)) mrb_gc_protect(mrb, kdict); } /* strict argument check */ @@ -2077,6 +2105,7 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) else { mrb_int rnum = 0; if (argv0 != argv) { + mrb_gc_protect(mrb, blk); value_move(®s[1], argv, m1+o); } if (r) { @@ -2093,11 +2122,12 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) /* need to be update blk first to protect blk from GC */ mrb_int const kw_pos = len + kd; /* where kwhash should be */ mrb_int const blk_pos = kw_pos + 1; /* where block should be */ - regs[blk_pos] = blk; /* move block */ + regs[blk_pos] = blk; /* move block */ if (kd) { - if (mrb_nil_p(kdict)) + if (mrb_nil_p(kdict)) { kdict = mrb_hash_new_capa(mrb, 0); - regs[kw_pos] = kdict; /* set kwhash */ + } + regs[kw_pos] = kdict; /* set kwhash */ ci->nk = 15; } @@ -2192,7 +2222,6 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) } } - if (ch == NULL) goto L_STOP; if (FALSE) { L_CATCH_TAGGED_BREAK: /* from THROW_TAGGED_BREAK() or UNWIND_ENSURE() */ ci = mrb->c->ci; @@ -2201,7 +2230,7 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) irep = proc->body.irep; pool = irep->pool; syms = irep->syms; - mrb_stack_extend(mrb, irep->nregs); + stack_extend(mrb, irep->nregs); pc = irep->iseq + mrb_irep_catch_handler_unpack(ch->target); } else { @@ -2308,13 +2337,10 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) break; case OP_R_BREAK: if (MRB_PROC_STRICT_P(proc)) goto NORMAL_RETURN; - if (MRB_PROC_ORPHAN_P(proc)) { + if (MRB_PROC_ORPHAN_P(proc) || !MRB_PROC_ENV_P(proc) || !MRB_ENV_ONSTACK_P(MRB_PROC_ENV(proc))) { L_BREAK_ERROR: RAISE_LIT(mrb, E_LOCALJUMP_ERROR, "break from proc-closure"); } - if (!MRB_PROC_ENV_P(proc) || !MRB_ENV_ONSTACK_P(MRB_PROC_ENV(proc))) { - goto L_BREAK_ERROR; - } else { struct REnv *e = MRB_PROC_ENV(proc); @@ -2627,13 +2653,13 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) /* need to check if - is overridden */\ switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {\ case TYPES2(MRB_TT_INTEGER,MRB_TT_INTEGER):\ - result = OP_CMP_BODY(op,mrb_fixnum,mrb_fixnum);\ + result = OP_CMP_BODY(op,mrb_integer,mrb_integer);\ break;\ case TYPES2(MRB_TT_INTEGER,MRB_TT_FLOAT):\ - result = OP_CMP_BODY(op,mrb_fixnum,mrb_float);\ + result = OP_CMP_BODY(op,mrb_integer,mrb_float);\ break;\ case TYPES2(MRB_TT_FLOAT,MRB_TT_INTEGER):\ - result = OP_CMP_BODY(op,mrb_float,mrb_fixnum);\ + result = OP_CMP_BODY(op,mrb_float,mrb_integer);\ break;\ case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):\ result = OP_CMP_BODY(op,mrb_float,mrb_float);\ @@ -2824,10 +2850,9 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) CASE(OP_HASH, BB) { mrb_value hash = mrb_hash_new_capa(mrb, b); - int i; int lim = a+b*2; - for (i=a; ibody.irep; pool = irep->pool; syms = irep->syms; - mrb_stack_extend(mrb, irep->nregs); + stack_extend(mrb, irep->nregs); stack_clear(regs+1, irep->nregs-1); pc = irep->iseq; JUMP; @@ -3097,24 +3121,16 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) static mrb_value mrb_run(mrb_state *mrb, const struct RProc *proc, mrb_value self) { - return mrb_vm_run(mrb, proc, self, mrb_ci_bidx(mrb->c->ci) + 1); + return mrb_vm_run(mrb, proc, self, ci_bidx(mrb->c->ci) + 1); } MRB_API mrb_value mrb_top_run(mrb_state *mrb, const struct RProc *proc, mrb_value self, mrb_int stack_keep) { - mrb_value v; - - if (!mrb->c->cibase) { - return mrb_vm_run(mrb, proc, self, stack_keep); - } - if (mrb->c->ci == mrb->c->cibase) { - return mrb_vm_run(mrb, proc, self, stack_keep); + if (mrb->c->cibase && mrb->c->ci > mrb->c->cibase) { + cipush(mrb, 0, CINFO_SKIP, mrb->object_class, NULL, NULL, 0, 0); } - cipush(mrb, 0, CINFO_SKIP, mrb->object_class, NULL, NULL, 0, 0); - v = mrb_vm_run(mrb, proc, self, stack_keep); - - return v; + return mrb_vm_run(mrb, proc, self, stack_keep); } #if defined(MRB_USE_CXX_EXCEPTION) && defined(__cplusplus) diff --git a/mruby/super-linter.report/.keep b/mruby/super-linter.report/.keep deleted file mode 100644 index e69de29b..00000000 diff --git a/mruby/tasks/doc.rake b/mruby/tasks/doc.rake index 50dc3618..11c0bd25 100644 --- a/mruby/tasks/doc.rake +++ b/mruby/tasks/doc.rake @@ -9,7 +9,7 @@ namespace :doc do begin sh "mrbdoc" rescue - puts "ERROR: To generate yard documentation, you should install yard-mruby gem." + puts "ERROR: To generate YARD documentation, you should install yard-mruby gem." puts " $ gem install yard-mruby yard-coderay" puts "https://yardoc.org/" puts "https://rubygems.org/gems/yard-mruby" diff --git a/mruby/tasks/install.rake b/mruby/tasks/install.rake new file mode 100644 index 00000000..234bec8d --- /dev/null +++ b/mruby/tasks/install.rake @@ -0,0 +1,33 @@ +desc "install compiled products (on host)" +task :install => "install:full:host" + +desc "install compiled executable (on host)" +task :install_bin => "install:bin:host" + +desc "install compiled products (all build targets)" +task "install:full" + +desc "install compiled executable (all build targets)" +task "install:bin" + +MRuby.each_target do |build| + next if build.internal? + + prefix = File.join(MRuby::INSTALL_DESTDIR, build.install_prefix) + + task "install:full" => "install:full:#{build.name}" + + task "install:full:#{build.name}" => "install:bin:#{build.name}" do + Dir.glob(File.join(build.build_dir.gsub(/[\[\{\*\?]/, "\\\0"), "{include,lib}/**/*")) do |path| + install_D path, File.join(prefix, path.relative_path_from(build.build_dir)) if File.file? path + end + end + + task "install:bin" => "install:bin:#{build.name}" + + task "install:bin:#{build.name}" => "all" do + Dir.glob(File.join(build.build_dir.gsub(/[\[\{\*\?]/, "\\\0"), "{bin,host-bin}/**/*")) do |path| + install_D path, File.join(prefix, path.relative_path_from(build.build_dir)) if File.file? path + end + end +end diff --git a/mruby/tasks/libmruby.rake b/mruby/tasks/libmruby.rake index 1fb3cbc3..38878b1e 100644 --- a/mruby/tasks/libmruby.rake +++ b/mruby/tasks/libmruby.rake @@ -7,31 +7,86 @@ MRuby.each_target do next unless libmruby_enabled? + copy_headers_task = "expose_header_files:#{name}" file libmruby_static => libmruby_objs.flatten do |t| + Rake::Task[copy_headers_task].invoke archiver.run t.name, t.prerequisites end + task copy_headers_task do |_t| + # Since header files may be generated dynamically and it is hard to know all of them, + # the task is executed depending on when libmruby.a is generated. + + gemsbasedir = File.join(build_dir, 'include/mruby/gems') + dirmap = { + MRUBY_ROOT => build_dir + } + gems.each do |g| + dirmap[g.dir] = File.join(gemsbasedir, g.name) + dirmap[g.build_dir] = File.join(gemsbasedir, g.name) + end + + dirs = each_header_files.to_a + dirs.uniq! + dirs.replace_prefix_by(dirmap).zip(dirs).each do |dest, src| + next unless File.mtime(src).to_i > begin + File.mtime(dest).to_i + rescue StandardError + 0 + end + + mkpath File.dirname(dest) + cp src, dest + end + end + file "#{build_dir}/lib/libmruby.flags.mak" => [__FILE__, libmruby_static] do |t| mkdir_p File.dirname t.name open(t.name, 'w') do |f| - gemincs = gems.map { |g| g.export_include_paths.map { |n| g.filename(n) } }.flatten.uniq - f.puts "MRUBY_CFLAGS = #{cc.all_flags([], gemincs)}" + f.puts <<~FLAGS_MAKE + # GNU make is required to use this file. + MRUBY_PACKAGE_DIR_GNU := $(shell dirname "$(lastword $(MAKEFILE_LIST))") + MRUBY_PACKAGE_DIR != dirname "$(MRUBY_PACKAGE_DIR_GNU)" + FLAGS_MAKE + + [ + [cc, 'MRUBY_CC', 'MRUBY_CFLAGS'], + [cxx, 'MRUBY_CXX', 'MRUBY_CXXFLAGS'], + [asm, 'MRUBY_AS', 'MRUBY_ASFLAGS'], + [objc, 'MRUBY_OBJC', 'MRUBY_OBJCFLAGS'] + ].each do |cc, cmd, flags| + incpaths = cc.include_paths.dup + dirmaps = { + MRUBY_ROOT => '$(MRUBY_PACKAGE_DIR)', + build_dir => '$(MRUBY_PACKAGE_DIR)' + } + gems.each do |g| + incpaths.concat g.export_include_paths + dirmaps[g.dir] = "$(MRUBY_PACKAGE_DIR)/include/mruby/gems/#{g.name}" + dirmaps[g.build_dir] = "$(MRUBY_PACKAGE_DIR)/include/mruby/gems/#{g.name}" + end + modcc = cc.clone + modcc.include_paths = incpaths.replace_prefix_by(dirmaps).uniq + + f.puts "#{cmd} = #{cc.command}" + f.puts "#{flags} = #{modcc.all_flags}" + end - f.puts "MRUBY_CC = #{cc.command}" f.puts "MRUBY_LD = #{linker.command}" - libgems = gems.reject{|g| g.bin?} - gem_flags = libgems.map {|g| g.linker.flags } - gem_library_paths = libgems.map {|g| g.linker.library_paths } - f.puts "MRUBY_LDFLAGS = #{linker.all_flags(gem_library_paths, gem_flags)} #{linker.option_library_path % "#{build_dir}/lib"}" + libgems = gems.reject { |g| g.bin? } + gem_flags = libgems.map { |g| g.linker.flags } + gem_library_paths = libgems.map { |g| g.linker.library_paths } + f.puts "MRUBY_LDFLAGS = #{linker.all_flags(gem_library_paths, gem_flags)} #{linker.option_library_path % '$(MRUBY_PACKAGE_DIR)/lib'}" - gem_flags_before_libraries = libgems.map {|g| g.linker.flags_before_libraries } + gem_flags_before_libraries = libgems.map { |g| g.linker.flags_before_libraries } f.puts "MRUBY_LDFLAGS_BEFORE_LIBS = #{[linker.flags_before_libraries, gem_flags_before_libraries].flatten.join(' ')}" - gem_libraries = libgems.map {|g| g.linker.libraries } - f.puts "MRUBY_LIBS = #{linker.option_library % 'mruby'} #{linker.library_flags(gem_libraries)}" + gem_libraries = libgems.map { |g| g.linker.libraries } + libmruby = toolchains.find { |e| e == 'visualcpp' } ? 'libmruby' : 'mruby' + f.puts "MRUBY_LIBS = #{linker.option_library % libmruby} #{linker.library_flags(gem_libraries)}" - f.puts "MRUBY_LIBMRUBY_PATH = #{libmruby_static}" + f.puts "MRUBY_LIBMRUBY_PATH = #{libmruby_static.replace_prefix_by(build_dir => '$(MRUBY_PACKAGE_DIR)')}" end end diff --git a/mruby/tasks/mrbgems.rake b/mruby/tasks/mrbgems.rake index 1e6b0319..686facb2 100644 --- a/mruby/tasks/mrbgems.rake +++ b/mruby/tasks/mrbgems.rake @@ -13,41 +13,82 @@ MRuby.each_target do mkdir_p "#{build_dir}/mrbgems" open(t.name, 'w') do |f| gem_func_gems = gems.select { |g| g.generate_functions } - gem_func_decls = gem_func_gems.each_with_object('') do |g, s| - s << "void GENERATED_TMP_mrb_#{g.funcname}_gem_init(mrb_state*);\n" \ - "void GENERATED_TMP_mrb_#{g.funcname}_gem_final(mrb_state*);\n" - end - gem_init_calls = gem_func_gems.each_with_object('') do |g, s| - s << " GENERATED_TMP_mrb_#{g.funcname}_gem_init(mrb);\n" - end - gem_final_calls = gem_func_gems.reverse_each.with_object('') do |g, s| - s << " GENERATED_TMP_mrb_#{g.funcname}_gem_final(mrb);\n" + gem_func_decls = '' + gem_funcs = '' + gem_func_gems.each do |g| + init = "GENERATED_TMP_mrb_#{g.funcname}_gem_init" + final = "GENERATED_TMP_mrb_#{g.funcname}_gem_final" + gem_func_decls << "void #{init}(mrb_state*);\n" \ + "void #{final}(mrb_state*);\n" + gem_funcs << " { #{init}, #{final} },\n" end f.puts %Q[/*] f.puts %Q[ * This file contains a list of all] f.puts %Q[ * initializing methods which are] f.puts %Q[ * necessary to bootstrap all gems.] f.puts %Q[ *] + f.puts %Q[ * This file was generated by mruby/#{__FILE__.relative_path_from(MRUBY_ROOT)}.] + f.puts %Q[ *] f.puts %Q[ * IMPORTANT:] f.puts %Q[ * This file was generated!] f.puts %Q[ * All manual changes will get lost.] f.puts %Q[ */] f.puts %Q[] f.puts %Q[#include ] + f.puts %Q[#include ] + f.puts %Q[#include ] f.puts %Q[] - f.write gem_func_decls - unless gem_final_calls.empty? + unless gem_funcs.empty? + f.write gem_func_decls + f.puts %Q[] + f.puts %Q[static const struct {] + f.puts %Q[ void (*init)(mrb_state*);] + f.puts %Q[ void (*final)(mrb_state*);] + f.puts %Q[} gem_funcs[] = {] + f.write gem_funcs + f.puts %Q[};] + f.puts %Q[] + f.puts %Q[#define NUM_GEMS ((int)(sizeof(gem_funcs) / sizeof(gem_funcs[0])))] + f.puts %Q[] + f.puts %Q[struct final_mrbgems {] + f.puts %Q[ int i;] + f.puts %Q[ int ai;] + f.puts %Q[};] + f.puts %Q[] + f.puts %Q[static mrb_value] + f.puts %Q[final_mrbgems_body(mrb_state *mrb, void *ud) {] + f.puts %Q[ struct final_mrbgems *p = (struct final_mrbgems*)ud;] + f.puts %Q[ for (; p->i >= 0; p->i--) {] + f.puts %Q[ gem_funcs[p->i].final(mrb);] + f.puts %Q[ mrb_gc_arena_restore(mrb, p->ai);] + f.puts %Q[ }] + f.puts %Q[ return mrb_nil_value();] + f.puts %Q[}] f.puts %Q[] f.puts %Q[static void] f.puts %Q[mrb_final_mrbgems(mrb_state *mrb) {] - f.write gem_final_calls + f.puts %Q[ struct final_mrbgems a = { NUM_GEMS - 1, mrb_gc_arena_save(mrb) };] + f.puts %Q[ for (; a.i >= 0; a.i--) {] + f.puts %Q[ mrb_protect_error(mrb, final_mrbgems_body, &a, NULL);] + f.puts %Q[ mrb_gc_arena_restore(mrb, a.ai);] + f.puts %Q[ }] f.puts %Q[}] + f.puts %Q[] end - f.puts %Q[] f.puts %Q[void] f.puts %Q[mrb_init_mrbgems(mrb_state *mrb) {] - f.write gem_init_calls - f.puts %Q[ mrb_state_atexit(mrb, mrb_final_mrbgems);] unless gem_final_calls.empty? + unless gem_funcs.empty? + f.puts %Q[ int ai = mrb_gc_arena_save(mrb);] + f.puts %Q[ for (int i = 0; i < NUM_GEMS; i++) {] + f.puts %Q[ gem_funcs[i].init(mrb);] + f.puts %Q[ mrb_gc_arena_restore(mrb, ai);] + f.puts %Q[ mrb_vm_ci_env_clear(mrb, mrb->c->cibase);] + f.puts %Q[ if (mrb->exc) {] + f.puts %Q[ mrb_exc_raise(mrb, mrb_obj_value(mrb->exc));] + f.puts %Q[ }] + f.puts %Q[ }] + f.puts %Q[ mrb_state_atexit(mrb, mrb_final_mrbgems);] + end f.puts %Q[}] end end diff --git a/mruby/tasks/toolchains/android.rake b/mruby/tasks/toolchains/android.rake index 6e4648e6..98e41304 100644 --- a/mruby/tasks/toolchains/android.rake +++ b/mruby/tasks/toolchains/android.rake @@ -2,7 +2,7 @@ require "json" class MRuby::Toolchain::Android - DEFAULT_ARCH = 'armeabi' # TODO : Revise if arch should have a default + DEFAULT_ARCH = 'armeabi-v7a' # TODO : Revise if arch should have a default DEFAULT_TOOLCHAIN = :clang @@ -15,14 +15,14 @@ class MRuby::Toolchain::Android %LOCALAPPDATA%/Android/Sdk/ndk/* ~/Library/Android/sdk/ndk-bundle ~/Library/Android/ndk + /opt/android-ndk } - TOOLCHAINS = [:clang, :gcc] + TOOLCHAINS = [:clang] ARCHITECTURES = %w{ - armeabi armeabi-v7a arm64-v8a + armeabi-v7a arm64-v8a x86 x86_64 - mips mips64 } class AndroidNDKHomeNotFound < StandardError @@ -40,21 +40,6 @@ Set ANDROID_NDK_HOME environment variable or set :ndk_home parameter @params = params end - def bin_gcc(command) - command = command.to_s - - command = case arch - when /armeabi/ then 'arm-linux-androideabi-' - when /arm64-v8a/ then 'aarch64-linux-android-' - when /x86_64/ then 'x86_64-linux-android-' - when /x86/ then 'i686-linux-android-' - when /mips64/ then 'mips64el-linux-android-' - when /mips/ then 'mipsel-linux-android-' - end + command - - gcc_toolchain_path.join('bin', command).to_s - end - def bin(command) command = command.to_s toolchain_path.join('bin', command).to_s @@ -97,38 +82,7 @@ Set ANDROID_NDK_HOME environment variable or set :ndk_home parameter end def toolchain_path - @toolchain_path ||= case toolchain - when :gcc - gcc_toolchain_path - when :clang - home_path.join('toolchains', 'llvm' , 'prebuilt', host_platform) - end - end - - def gcc_toolchain_path - if @gcc_toolchain_path === nil then - prefix = case arch - when /armeabi/ then 'arm-linux-androideabi-' - when /arm64-v8a/ then 'aarch64-linux-android-' - when /x86_64/ then 'x86_64-' - when /x86/ then 'x86-' - when /mips64/ then 'mips64el-linux-android-' - when /mips/ then 'mipsel-linux-android-' - end - - test = case arch - when /armeabi/ then 'arm-linux-androideabi-*' - when /arm64-v8a/ then 'aarch64-linux-android-*' - when /x86_64/ then 'x86_64-*' - when /x86/ then 'x86-*' - when /mips64/ then 'mips64el-linux-android-*' - when /mips/ then 'mipsel-linux-android-*' - end - - gcc_toolchain_version = Dir[home_path.join('toolchains', test)].map{|t| t.match(/-(\d+\.\d+)$/); $1.to_f }.max - @gcc_toolchain_path = home_path.join('toolchains', prefix + gcc_toolchain_version.to_s, 'prebuilt', host_platform) - end - @gcc_toolchain_path + @toolchain_path ||= home_path.join('toolchains', 'llvm' , 'prebuilt', host_platform) end def host_platform @@ -189,15 +143,13 @@ Set ANDROID_NDK_HOME environment variable or set :ndk_home parameter def cc case toolchain - when :gcc then bin_gcc('gcc') when :clang then bin('clang') end end def ar case toolchain - when :gcc then bin_gcc('ar') - when :clang then bin_gcc('ar') + when :clang then bin('llvm-ar') end end @@ -206,38 +158,15 @@ Set ANDROID_NDK_HOME environment variable or set :ndk_home parameter v = sdk_version case toolchain - when :gcc - case arch - when /armeabi-v7a/ then flags += %W(-march=armv7-a) - when /armeabi/ then flags += %W(-march=armv5te) - when /arm64-v8a/ then flags += %W(-march=armv8-a) - when /x86_64/ then flags += %W(-march=x86-64) - when /x86/ then flags += %W(-march=i686) - when /mips64/ then flags += %W(-march=mips64r6) - when /mips/ then flags += %W(-march=mips32) - end when :clang case arch - when /armeabi-v7a/ then flags += %W(-target armv7-none-linux-androideabi#{v}) - when /armeabi/ then flags += %W(-target armv5te-none-linux-androideabi#{v}) - when /arm64-v8a/ then flags += %W(-target aarch64-none-linux-android#{v}) - when /x86_64/ then flags += %W(-target x86_64-none-linux-android#{v}) - when /x86/ then flags += %W(-target i686-none-linux-android#{v}) - when /mips64/ then flags += %W(-target mips64el-none-linux-android#{v}) - when /mips/ then flags += %W(-target mipsel-none-linux-android#{v}) + when /armeabi-v7a/ then flags += %W(-target armv7a-linux-androideabi#{v} -mfpu=#{armeabi_v7a_mfpu} -mfloat-abi=#{armeabi_v7a_mfloat_abi}) + when /arm64-v8a/ then flags += %W(-target aarch64-linux-android#{v}) + when /x86_64/ then flags += %W(-target x86_64-linux-android#{v}) + when /x86/ then flags += %W(-target i686-linux-android#{v}) end end - case arch - when /armeabi-v7a/ then flags += %W(-mfpu=#{armeabi_v7a_mfpu} -mfloat-abi=#{armeabi_v7a_mfloat_abi}) - when /armeabi/ then flags += %W(-mtune=xscale -msoft-float) - when /arm64-v8a/ then flags += %W() - when /x86_64/ then flags += %W() - when /x86/ then flags += %W() - when /mips64/ then flags += %W(-fmessage-length=0) - when /mips/ then flags += %W(-fmessage-length=0) - end - flags end @@ -252,11 +181,6 @@ Set ANDROID_NDK_HOME environment variable or set :ndk_home parameter flags += %W(-MMD -MP -D__android__ -DANDROID) flags += ctarget - case toolchain - when :gcc - when :clang - flags += %W(-gcc-toolchain "#{gcc_toolchain_path}" -Wno-invalid-command-line-argument -Wno-unused-command-line-argument) - end flags += %W(-fpic -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes) flags @@ -273,20 +197,12 @@ Set ANDROID_NDK_HOME environment variable or set :ndk_home parameter v = sdk_version case toolchain - when :gcc - case arch - when /armeabi-v7a/ then flags += %W(-Wl#{no_warn_mismatch}) - end when :clang - flags += %W(-gcc-toolchain "#{gcc_toolchain_path.to_s}") case arch when /armeabi-v7a/ then flags += %W(-target armv7-none-linux-androideabi#{v} -Wl,--fix-cortex-a8#{no_warn_mismatch}) - when /armeabi/ then flags += %W(-target armv5te-none-linux-androideabi#{v}) when /arm64-v8a/ then flags += %W(-target aarch64-none-linux-android#{v}) when /x86_64/ then flags += %W(-target x86_64-none-linux-android#{v}) when /x86/ then flags += %W(-target i686-none-linux-android#{v}) - when /mips64/ then flags += %W(-target mips64el-none-linux-android#{v}) - when /mips/ then flags += %W(-target mipsel-none-linux-android#{v}) end end flags += %W(-no-canonical-prefixes) diff --git a/mruby/tasks/toolchains/gcc.rake b/mruby/tasks/toolchains/gcc.rake index aa1cf777..675c2688 100644 --- a/mruby/tasks/toolchains/gcc.rake +++ b/mruby/tasks/toolchains/gcc.rake @@ -20,6 +20,10 @@ MRuby::Toolchain.new(:gcc) do |conf, params| compiler.cxx_compile_flag = '-x c++ -std=gnu++03' compiler.cxx_exception_flag = '-fexceptions' compiler.cxx_invalid_flags = c_mandatory_flags + cxx_invalid_flags + + def compiler.setup_debug(conf) + self.flags << %w(-g3 -O0) + end end conf.linker do |linker| diff --git a/mruby/test/t/bs_block.rb b/mruby/test/t/bs_block.rb index c37d1b53..08580d58 100644 --- a/mruby/test/t/bs_block.rb +++ b/mruby/test/t/bs_block.rb @@ -313,7 +313,7 @@ def m end assert('BS Block 26') do - def m a + def m(a) yield a end assert_equal(2) do diff --git a/mruby/test/t/class.rb b/mruby/test/t/class.rb index 1b4b8489..f4d99318 100644 --- a/mruby/test/t/class.rb +++ b/mruby/test/t/class.rb @@ -40,7 +40,7 @@ def initialize_copy(obj) end class TestClass - def initialize args, &block + def initialize(args, &block) @result = if not args.nil? and block.nil? # only arguments :only_args diff --git a/mruby/test/t/codegen.rb b/mruby/test/t/codegen.rb index acb9e1bf..0cb86efc 100644 --- a/mruby/test/t/codegen.rb +++ b/mruby/test/t/codegen.rb @@ -56,12 +56,11 @@ def args_to_ary(*args) end end -assert('next in normal loop with 127 arguments') do - assert_raise NameError do - while true - next A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A - end - end +assert('break in normal loop with 127 arguments') do + assert_equal 127, + 1.times{ + break 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 + }.size end assert('negate literal register alignment') do diff --git a/mruby/test/t/float.rb b/mruby/test/t/float.rb index e4c25b34..1a7f6c99 100644 --- a/mruby/test/t/float.rb +++ b/mruby/test/t/float.rb @@ -216,7 +216,7 @@ end assert('Float#divmod') do - def check_floats exp, act + def check_floats(exp, act) assert_float exp[0], act[0] assert_float exp[1], act[1] end diff --git a/mruby/test/t/hash.rb b/mruby/test/t/hash.rb index 9ff066b8..3ce2e14f 100644 --- a/mruby/test/t/hash.rb +++ b/mruby/test/t/hash.rb @@ -880,17 +880,6 @@ def h.default(k); self[k] = 1; end hh[hh] = :recur assert_equal("{#{s}, {...}=>:recur}", hh.__send__(meth)) end - - [ar_entries, ht_entries].each do |entries| - cls = Class.new do - attr_accessor :h - def inspect; @h.replace(@h.dup); to_s; end - end - v = cls.new - h = entries.hash_for({_k: v}) - v.h = h - assert_nothing_raised{h.__send__(meth)} - end end end diff --git a/mruby/test/t/string.rb b/mruby/test/t/string.rb index 11b5cae0..0bb9acfb 100644 --- a/mruby/test/t/string.rb +++ b/mruby/test/t/string.rb @@ -898,3 +898,72 @@ assert_equal("o", str1.byteslice(4.0)) assert_equal("\x82ab", str2.byteslice(2.0, 3.0)) end + +assert('String#bytesplice') do + # range, replace (len1=len2) + a = "0123456789" + assert_equal "0ab3456789", a.bytesplice(1..2, "ab") + + # range, replace (len1>len2) + a = "0123456789" + assert_equal "0ab456789", a.bytesplice(1..3, "ab") + + # range, replace (len1len2) + a = "0123456789" + assert_equal "0ab456789", a.bytesplice(1, 3, "ab") + + # idx, len, replace (len1len2) + a = "0123456789" + assert_equal "0bc456789", a.bytesplice(1..3, b, 1..2) + + # range, replace, range (len1len2) + a = "0123456789" + assert_equal "0bc456789", a.bytesplice(1, 3, b, 1, 2) + + # idx, len, replace, idx, len (len1