mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Compare commits
438 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 045761390d | |||
| 0589749952 | |||
| 4b5dd5683b | |||
| 6b457d2c00 | |||
| c779413df3 | |||
| 9cebddf9fe | |||
| 21e07d6113 | |||
| 5b40bb8d15 | |||
| bec4d05340 | |||
| 8c276f95be | |||
| 82046ff26e | |||
| 3d6adccfbe | |||
| 5069fb15e4 | |||
| 7ca59ecea2 | |||
| 041351fb05 | |||
| 34356974ee | |||
| d2b548de60 | |||
| c80ece2149 | |||
| 356b719fef | |||
| 896338e219 | |||
| bff79112a6 | |||
| f1d02bfc15 | |||
| c1f5fdafb6 | |||
| 5d1d94d911 | |||
| 762556b6e8 | |||
| 618c589162 | |||
| ab2b42d363 | |||
| b9007244bd | |||
| 7932523052 | |||
| 12881ccb05 | |||
| 3ff2757bf7 | |||
| 4dcc1819c9 | |||
| 21ee56d82a | |||
| 55a2ff5faf | |||
| ed97c1779e | |||
| 0d8793047d | |||
| cbb46f6975 | |||
| 0c242e278d | |||
| 932b93fd12 | |||
| a4c5824e59 | |||
| afcf19b727 | |||
| 30424dfa74 | |||
| 9b8e5658ce | |||
| a127ded486 | |||
| fe3c3bb661 | |||
| f9e781d83a | |||
| fc8885f2f4 | |||
| fe1ad37bfb | |||
| 9e842b3a75 | |||
| b81edb0035 | |||
| 86dee45f1d | |||
| 08f61db6ee | |||
| 7f66e50ba2 | |||
| 5592c7413a | |||
| fff0f17b49 | |||
| 2b05cf48d0 | |||
| dae0de4461 | |||
| cfe8b0c81d | |||
| 026726dd49 | |||
| d7986b449d | |||
| 4970e24a1c | |||
| 950e60363a | |||
| 87c7064bad | |||
| 4cf1da9542 | |||
| b01207ea94 | |||
| c2444b8424 | |||
| 8461be11fc | |||
| 260db0f5fb | |||
| 99ef00fe02 | |||
| b9dfd0438f | |||
| d0b5d720ac | |||
| dd1ce5d53e | |||
| 7eaaee5405 | |||
| 471479e723 | |||
| 397b005715 | |||
| bf118b9006 | |||
| 7e3d22f095 | |||
| 01dbbcd553 | |||
| e479a42757 | |||
| 5134031e18 | |||
| befcbd5607 | |||
| 9d613159b5 | |||
| 3e71359d7a | |||
| 2b188ed8a1 | |||
| 59af217779 | |||
| 2bb84f1f1a | |||
| 850e200e84 | |||
| b978231bda | |||
| b7fe929232 | |||
| 20ffc2206a | |||
| caee1f68a2 | |||
| a4302524d0 | |||
| 12d31c33af | |||
| 5a7cbebc8a | |||
| 04fd7af23c | |||
| 2a92fb2516 | |||
| 18e3d39ee2 | |||
| 55163a8a0a | |||
| 867268897a | |||
| 11317de468 | |||
| 857a1d9fc9 | |||
| b44326b561 | |||
| 8bd1bc47b3 | |||
| c45674aff0 | |||
| 80fe9838d2 | |||
| 40d0d8fe0e | |||
| ee544dc881 | |||
| ed32b6fcdc | |||
| c8cf9512cd | |||
| 1835753f9f | |||
| 424afa4446 | |||
| 02e69d1c2c | |||
| 44a07393f4 | |||
| 0b22bf4a89 | |||
| 1520c97e17 | |||
| 8a87549315 | |||
| ef9df5dc7d | |||
| 7dc595f98f | |||
| d4b89ccc61 | |||
| 72d071540c | |||
| dea185e687 | |||
| 968053a35b | |||
| 66114f8332 | |||
| 8813ebec07 | |||
| a93ef815be | |||
| 905d4010bf | |||
| 763b39d00b | |||
| 107c777341 | |||
| 500f721f70 | |||
| cb89e1f0d9 | |||
| 6bc5857125 | |||
| bfb7b491cc | |||
| c1f112c49a | |||
| 0d7b4deccf | |||
| f467b02d45 | |||
| a54a3df32c | |||
| 3ad6bbc40c | |||
| 67d92c48b5 | |||
| 6fbc03b3a8 | |||
| 690cafe274 | |||
| 4e56e0defc | |||
| 53e46be7e2 | |||
| 73e289c54e | |||
| ce372122ed | |||
| a733c6e0ea | |||
| 425b142168 | |||
| f751c28ca4 | |||
| 4281429412 | |||
| 0e50ea90f3 | |||
| 1eb71b008f | |||
| 84a68ca5ae | |||
| 5e9dc72bc5 | |||
| 1eacdae319 | |||
| 59b35250cc | |||
| 2b45d454bc | |||
| ff0e3bcea6 | |||
| 8b3f3c0bf3 | |||
| cf2aabdad6 | |||
| 3d8a38bea4 | |||
| 639946a006 | |||
| fb5e8ab6d5 | |||
| 11955ca1a1 | |||
| 52dd0a8cd7 | |||
| 6db0162ec7 | |||
| dec34d6c7b | |||
| 8f0ac27196 | |||
| fd10c72319 | |||
| ce7508e0d5 | |||
| c29212cf44 | |||
| 6e86e290e4 | |||
| b2398879fa | |||
| e01648b86b | |||
| e0c9b53217 | |||
| ce30a4e04b | |||
| 31877043c4 | |||
| 167a747a41 | |||
| cfc958b01a | |||
| 015f06ed8e | |||
| 95169097fc | |||
| 474545bba2 | |||
| 925cd2ab8f | |||
| 9debf63340 | |||
| 0f978932e2 | |||
| 6488ae855f | |||
| d2f267a13d | |||
| a4a1e01e81 | |||
| ee111dd175 | |||
| f0c1126997 | |||
| b7031e8bc8 | |||
| 52507b1083 | |||
| 7deb41b0e8 | |||
| f1c06eef7c | |||
| 449317a251 | |||
| d428fa0c4a | |||
| daa37be549 | |||
| ad15e59cd9 | |||
| 71eb4b2b22 | |||
| d93b1a48d2 | |||
| 3a64cde61d | |||
| 4684864f04 | |||
| dd8c178a73 | |||
| 029c7c1116 | |||
| a68f005fd7 | |||
| 1adf93aa54 | |||
| 26da07db15 | |||
| 7ab7cadbbb | |||
| 2c1d209fd5 | |||
| 5a3e014e49 | |||
| 744ba80919 | |||
| 0d755e583c | |||
| 92d8012b4e | |||
| cc587e6535 | |||
| 1122124f97 | |||
| 5405977a6e | |||
| f6dcc6dcfc | |||
| 9712379e0f | |||
| b67955b8ca | |||
| 2a366ffba8 | |||
| 8864c30d16 | |||
| 3516a3c012 | |||
| fa6a9f6f13 | |||
| 00f5ddc9ae | |||
| dcd3e5907c | |||
| 80c15ddd15 | |||
| 7fde48b838 | |||
| 509f2bfd93 | |||
| b941e91866 | |||
| 312f54b580 | |||
| 3a162cc33f | |||
| b60809f117 | |||
| 0881e34496 | |||
| 24ad5f35b1 | |||
| 3c222e4e71 | |||
| e2063fc267 | |||
| 68f8d73308 | |||
| 246c76e261 | |||
| 6128ae61a8 | |||
| e3e5596960 | |||
| 1bcf6d9f3c | |||
| 97e3c3a5a3 | |||
| acd5317fb1 | |||
| 8d90c7c0fa | |||
| 5a88904fe8 | |||
| b3db34c2a8 | |||
| 6b7c12f523 | |||
| fa18ffa90c | |||
| 3ec61c0929 | |||
| 10b1a52bb8 | |||
| dcfc2dbf14 | |||
| d70536e0e8 | |||
| fdbfeaf533 | |||
| ea31878b1f | |||
| d33b9dc81f | |||
| d612344e48 | |||
| d7e183bfdf | |||
| d5c010422a | |||
| 5738ed0474 | |||
| 3174061593 | |||
| 76d752c03b | |||
| 33647b904e | |||
| 47f65a93c5 | |||
| a2fbb98fa6 | |||
| 721f934b9b | |||
| d2cab16301 | |||
| eddd324979 | |||
| f221f4e0fa | |||
| a476d71143 | |||
| 1e156974d5 | |||
| 8853b03591 | |||
| f53781bdeb | |||
| afc0d7a6c3 | |||
| c4f75c7de0 | |||
| 9ea7b71868 | |||
| 57611240a9 | |||
| a97f085c52 | |||
| 2bf9fd06d2 | |||
| dffe4bc8ba | |||
| 4375bffee5 | |||
| e440681a06 | |||
| 758f8f4baf | |||
| ea3b02e387 | |||
| 069d9bb4d7 | |||
| 9757616c57 | |||
| e8723a4f3f | |||
| 5bfb70e9db | |||
| 8b65e4b73c | |||
| 4e15832000 | |||
| c27e451931 | |||
| c345fe4321 | |||
| f99c315400 | |||
| e2c628583e | |||
| 705f95c983 | |||
| 6b8664b951 | |||
| f08f3c34be | |||
| 510b9e7abc | |||
| 564372d7b9 | |||
| a66d86cfc1 | |||
| 96bae1d508 | |||
| 77c35e7097 | |||
| 2aa70e9690 | |||
| ae09a219d5 | |||
| c5dc184a6d | |||
| bab7e9f032 | |||
| 3b8df2c285 | |||
| cfaaf7c6d4 | |||
| 5210482c59 | |||
| 5e55b61c44 | |||
| 4695dfdcb6 | |||
| 55482063a7 | |||
| ab5726d4e4 | |||
| 0d54568b4d | |||
| df969b163a | |||
| ad8b36daa1 | |||
| c849b894ed | |||
| d8e060d2d3 | |||
| 9742bce198 | |||
| 7f8d38bbbe | |||
| 0b95c8a1e8 | |||
| 57a798e687 | |||
| 755233ef7d | |||
| 8f99689ba3 | |||
| 1a9bdfcde5 | |||
| 11cc7bed96 | |||
| ef9c68795f | |||
| fde95a7db5 | |||
| cfb799a18e | |||
| 43443d9377 | |||
| faed5054f8 | |||
| 0a505dcfd6 | |||
| 1517d77e93 | |||
| 9571a4c07e | |||
| d96be5c1b2 | |||
| 0983c723c5 | |||
| 425b5f32d6 | |||
| 0c88c71786 | |||
| f868d7d357 | |||
| c69ca2c7f8 | |||
| ccd5f203bf | |||
| 5c2b11d215 | |||
| c9ba761b9e | |||
| 2b588b8566 | |||
| b4f4f5968b | |||
| e7599050dc | |||
| 0e9bd24827 | |||
| b920270508 | |||
| 491aa1bfe5 | |||
| c99bb756c4 | |||
| 097f525817 | |||
| 5533c29833 | |||
| 0bb4d10ca7 | |||
| 914da3d712 | |||
| 670622f45d | |||
| 97f71b5a67 | |||
| 639703cf01 | |||
| 6334949ba6 | |||
| b1847721e8 | |||
| f0afdf7496 | |||
| 0685784119 | |||
| 5f4a27217e | |||
| c9ea39843b | |||
| a6f31ad6ce | |||
| 07b75d927e | |||
| 71254be076 | |||
| 1d2c5c12d3 | |||
| 00337543a5 | |||
| f76defd310 | |||
| d023adcb12 | |||
| 5b2763821e | |||
| 6d073f8d99 | |||
| 667ace2bfe | |||
| ffe8bf6323 | |||
| a79d1ba9ff | |||
| fe1ec9afdd | |||
| 1952004d5a | |||
| e41f1f5139 | |||
| 495c1a377a | |||
| 9f52bcfca9 | |||
| a2b8c08a52 | |||
| f00657ead7 | |||
| 2e56da5a78 | |||
| 60279b2a8e | |||
| c6b8b58e0e | |||
| 7f66cf7d66 | |||
| 9840d6a2e7 | |||
| b5bf9510ee | |||
| 5dc87f77d4 | |||
| f74d370c15 | |||
| 38b0759108 | |||
| 4d32c671a7 | |||
| bfd58a3fb3 | |||
| 1a4089803d | |||
| 4bf050a192 | |||
| 49896a4d28 | |||
| 0e5394638b | |||
| ad44021591 | |||
| 5759256ff8 | |||
| 5184263bdc | |||
| 6f945a09b4 | |||
| e7bd7d0eaf | |||
| 41e3220539 | |||
| e3bb95bb6d | |||
| 5df95e8d7b | |||
| 99bb2154ff | |||
| 28e39419a5 | |||
| 042f98912f | |||
| bb23faae65 | |||
| 308c6c8311 | |||
| 37d6628688 | |||
| 338c8538c9 | |||
| c5fd8cbbe1 | |||
| 8a44903992 | |||
| 3a79d60515 | |||
| 01a8d8498f | |||
| b759746890 | |||
| b3dace6ae3 | |||
| 4d393d5d09 | |||
| 5c7adf0534 | |||
| 4f189b2be9 | |||
| 81fc5ff48a | |||
| 5746958470 | |||
| 97319697c8 | |||
| 612e5d6aad | |||
| ba9f81db8b | |||
| 5b9f7c0b93 | |||
| ce167d70b7 | |||
| 0ed623c442 | |||
| 206f7ce272 | |||
| b59283a03f | |||
| 3cf48713a2 | |||
| 6d5652114e | |||
| b1017b2651 | |||
| b8d896e56a | |||
| db296e9593 | |||
| 9840e5352b | |||
| 0aa5aa1de2 | |||
| 25d9370f97 | |||
| 2bab6e197d | |||
| 893cc2780c |
+30
-30
@@ -5,66 +5,68 @@ on: [push, pull_request]
|
||||
jobs:
|
||||
Ubuntu-1604:
|
||||
runs-on: ubuntu-16.04
|
||||
env:
|
||||
MRUBY_TARGET: travis
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: apt
|
||||
run: sudo apt install ruby gperf
|
||||
- name: build and test
|
||||
run: rake -m -j4 all test
|
||||
env:
|
||||
MRUBY_CONFIG: travis_config.rb
|
||||
run: rake -m -j4 gensym all test
|
||||
|
||||
Ubuntu-1804-gcc:
|
||||
runs-on: ubuntu-18.04
|
||||
env:
|
||||
MRUBY_TARGET: travis
|
||||
CC: gcc
|
||||
CXX: g++
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: apt
|
||||
run: sudo apt install ruby gperf gcc g++
|
||||
- name: build and test
|
||||
run: rake -m -j4 all test
|
||||
env:
|
||||
MRUBY_CONFIG: travis_config.rb
|
||||
CC: gcc
|
||||
CXX: g++
|
||||
run: rake -m -j4 gensym all test
|
||||
|
||||
Ubuntu-1804-clang:
|
||||
runs-on: ubuntu-18.04
|
||||
env:
|
||||
MRUBY_TARGET: travis
|
||||
CC: clang
|
||||
CXX: clang++
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: apt
|
||||
run: sudo apt install ruby gperf
|
||||
- name: build and test
|
||||
run: rake -m -j4 all test
|
||||
env:
|
||||
MRUBY_CONFIG: travis_config.rb
|
||||
CC: clang
|
||||
CXX: clang++
|
||||
run: rake -m -j4 gensym all test
|
||||
|
||||
macOS:
|
||||
runs-on: macos-latest
|
||||
env:
|
||||
MRUBY_TARGET: travis
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: brew
|
||||
run: brew install ruby gperf
|
||||
- name: build and test
|
||||
run: rake -m -j4 all test
|
||||
env:
|
||||
MRUBY_CONFIG: travis_config.rb
|
||||
run: rake -m -j4 gensym all test
|
||||
|
||||
Windows-MinGW:
|
||||
runs-on: windows-latest
|
||||
env:
|
||||
MRUBY_TARGET: travis
|
||||
CFLAGS: -g -O1 -Wall -Wundef
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: chocolatey
|
||||
run: choco install -y ruby gperf
|
||||
- name: build and test
|
||||
run: rake -E '$stdout.sync=true' -j4 test
|
||||
env:
|
||||
MRUBY_CONFIG: travis_config.rb
|
||||
CFLAGS: -g -O1 -Wall -Wundef
|
||||
- name: build
|
||||
run: rake -E 'STDOUT.sync=true' -j4 gensym all test
|
||||
|
||||
Windows-Cygwin:
|
||||
runs-on: windows-latest
|
||||
env:
|
||||
MRUBY_TARGET: travis
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/cache@v1
|
||||
@@ -84,12 +86,15 @@ jobs:
|
||||
echo '::set-env name=PATH::C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin'
|
||||
- name: build and test
|
||||
shell: cmd
|
||||
run: C:\tools\cygwin\bin\ruby.exe /usr/bin/rake -m -j4 -E 'STDOUT.sync=true' test
|
||||
env:
|
||||
MRUBY_CONFIG: travis_config.rb
|
||||
run: C:\tools\cygwin\bin\ruby.exe /usr/bin/rake -E 'STDOUT.sync=true' -m gensym all test
|
||||
|
||||
Windows-VC:
|
||||
runs-on: windows-latest
|
||||
env:
|
||||
MRUBY_TARGET: appveyor
|
||||
# TODO(take-cheeze): Re-enable /O2
|
||||
CFLAGS: "/c /nologo /W3 /we4013 /Zi /MD /D_CRT_SECURE_NO_WARNINGS"
|
||||
CXXFLAGS: "/c /nologo /W3 /Zi /MD /EHs /D_CRT_SECURE_NO_WARNINGS"
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: chocolatey
|
||||
@@ -98,9 +103,4 @@ jobs:
|
||||
shell: cmd
|
||||
run: |
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
|
||||
rake -E "STDOUT.sync=true" -m -j4 test
|
||||
env:
|
||||
MRUBY_CONFIG: appveyor_config.rb
|
||||
# TODO(take-cheeze): Re-enable /O2
|
||||
CFLAGS: "/c /nologo /W3 /we4013 /Zi /MD /D_CRT_SECURE_NO_WARNINGS"
|
||||
CXXFLAGS: "/c /nologo /W3 /Zi /MD /EHs /D_CRT_SECURE_NO_WARNINGS"
|
||||
rake -E "STDOUT.sync=true" gensym all test
|
||||
|
||||
+5
-2
@@ -3,9 +3,12 @@ language: c
|
||||
jobs:
|
||||
- os: linux
|
||||
- os: osx
|
||||
before_install:
|
||||
- HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALL_CLEANUP=1 brew install bison
|
||||
- export PATH="/usr/local/opt/bison/bin:$PATH"
|
||||
|
||||
env:
|
||||
- MRUBY_CONFIG=travis_config.rb
|
||||
- MRUBY_TARGET=travis
|
||||
|
||||
script:
|
||||
- rake -m && rake test
|
||||
- rake gensym && rake -m && rake test
|
||||
|
||||
@@ -43,3 +43,4 @@ of this list.
|
||||
YAMAMOTO Masaya
|
||||
KOBAYASHI Shuji
|
||||
RIZAL Reckordp
|
||||
Rory O'Connell
|
||||
|
||||
+3
-2
@@ -56,7 +56,7 @@ on-demand.
|
||||
|
||||
Use C++ style comments only for temporary comment e.g. commenting out some code lines.
|
||||
|
||||
#### Insert a break after the method return value:
|
||||
#### Insert a break after the function return value:
|
||||
|
||||
int
|
||||
main(void)
|
||||
@@ -72,4 +72,5 @@ language itself. Please note the following hints for your Ruby code:
|
||||
#### Comply with the Ruby standard (ISO/IEC 30170:2012)
|
||||
|
||||
mruby is currently targeting to execute Ruby code which complies to ISO/IEC
|
||||
30170:2012 (http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=59579).
|
||||
30170:2012 (http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=59579),
|
||||
unless there's a clear reason, e.g. the latest Ruby has changed behavior from ISO.
|
||||
|
||||
@@ -17,6 +17,8 @@ of the Ministry of Economy, Trade and Industry of Japan.
|
||||
|
||||
## How to get mruby
|
||||
|
||||
The preview version 3.0.0 of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/archive/3.0.0-preview.zip](https://github.com/mruby/mruby/archive/3.0.0-preview.zip)
|
||||
|
||||
The stable version 2.1.2 of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/archive/2.1.2.zip](https://github.com/mruby/mruby/archive/2.1.2.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)
|
||||
@@ -40,11 +42,13 @@ We don't have a mailing list, but you can use [GitHub issues](https://github.com
|
||||
|
||||
See the [compile.md](https://github.com/mruby/mruby/blob/master/doc/guides/compile.md) file.
|
||||
|
||||
## Running Tests
|
||||
## How to Build
|
||||
|
||||
To run the tests, execute the following from the project's root directory.
|
||||
To build mruby, execute the following from the project's root directory.
|
||||
|
||||
$ rake test
|
||||
$ rake TARGET=<target> test
|
||||
|
||||
The default `TARGET` is `host`. `TARGET` will be loaded from `target` directory.
|
||||
|
||||
Note: `bison` bundled with MacOS is too old to compile `mruby`.
|
||||
Try `brew install bison` and follow the instuction shown to update
|
||||
|
||||
@@ -14,7 +14,13 @@ require "mruby-core-ext"
|
||||
require "mruby/build"
|
||||
|
||||
# load configuration file
|
||||
MRUBY_CONFIG = (ENV['MRUBY_CONFIG'] && ENV['MRUBY_CONFIG'] != '') ? ENV['MRUBY_CONFIG'] : "#{MRUBY_ROOT}/build_config.rb"
|
||||
if ENV['MRUBY_CONFIG']
|
||||
MRUBY_CONFIG = ENV['MRUBY_CONFIG']
|
||||
MRUBY_TARGET = File.basename(MRUBY_CONFIG, ".rb")
|
||||
else
|
||||
MRUBY_TARGET = ENV['MRUBY_TARGET'] || ENV['TARGET'] || "host"
|
||||
MRUBY_CONFIG = "#{MRUBY_ROOT}/target/#{MRUBY_TARGET}.rb"
|
||||
end
|
||||
load MRUBY_CONFIG
|
||||
|
||||
# load basic rules
|
||||
@@ -46,15 +52,19 @@ task :default => :all
|
||||
|
||||
bin_path = ENV['INSTALL_DIR'] || "#{MRUBY_ROOT}/bin"
|
||||
|
||||
depfiles = MRuby.targets['host'].bins.map do |bin|
|
||||
install_path = MRuby.targets['host'].exefile("#{bin_path}/#{bin}")
|
||||
source_path = MRuby.targets['host'].exefile("#{MRuby.targets['host'].build_dir}/bin/#{bin}")
|
||||
if MRuby.targets['host']
|
||||
target = MRuby.targets['host']
|
||||
depfiles = target.bins.map do |bin|
|
||||
install_path = target.exefile("#{bin_path}/#{bin}")
|
||||
source_path = target.exefile("#{target.build_dir}/bin/#{bin}")
|
||||
|
||||
file install_path => source_path do |t|
|
||||
install_D t.prerequisites.first, t.name
|
||||
file install_path => source_path do |t|
|
||||
install_D t.prerequisites.first, t.name
|
||||
end
|
||||
install_path
|
||||
end
|
||||
|
||||
install_path
|
||||
else
|
||||
depfiles = []
|
||||
end
|
||||
|
||||
MRuby.each_target do |target|
|
||||
@@ -87,15 +97,6 @@ MRuby.each_target do |target|
|
||||
install_D t.prerequisites.first, t.name
|
||||
end
|
||||
depfiles += [ install_path ]
|
||||
elsif target == MRuby.targets['host-debug']
|
||||
unless MRuby.targets['host'].gems.map {|g| g.bins}.include?([bin])
|
||||
install_path = MRuby.targets['host-debug'].exefile("#{bin_path}/#{bin}")
|
||||
|
||||
file install_path => exec do |t|
|
||||
install_D t.prerequisites.first, t.name
|
||||
end
|
||||
depfiles += [ install_path ]
|
||||
end
|
||||
else
|
||||
depfiles += [ exec ]
|
||||
end
|
||||
@@ -103,6 +104,143 @@ MRuby.each_target do |target|
|
||||
end
|
||||
end
|
||||
|
||||
mkdir_p "#{MRUBY_ROOT}/build"
|
||||
cfiles = (
|
||||
Dir.glob("#{MRUBY_ROOT}/src/*.c")+
|
||||
Dir.glob("#{MRUBY_ROOT}/mrbgems/**/*.c")+
|
||||
Dir.glob("#{MRUBY_ROOT}/build/repos/**/{src,core}/*.c")
|
||||
).uniq
|
||||
rbfiles = (
|
||||
Dir.glob("#{MRUBY_ROOT}/mrblib/**/*.rb")+
|
||||
Dir.glob("#{MRUBY_ROOT}/mrbgems/*/mrblib/**/*.rb")+
|
||||
Dir.glob("#{MRUBY_ROOT}/build/repos/**/mrblib/**/*.rb")
|
||||
).uniq
|
||||
psfiles = Dir.glob("#{MRUBY_ROOT}/{mrblib,mrbgems,build/repos}/**/presym")
|
||||
symbols = []
|
||||
psfiles.each do |file|
|
||||
symbols += File.readlines(file).grep_v(/^# /)
|
||||
end
|
||||
symbols.each{|x| x.chomp!}
|
||||
presym_file="#{MRUBY_ROOT}/build/presym"
|
||||
op_table = {
|
||||
"!" => "not",
|
||||
"!=" => "neq",
|
||||
"!~" => "nmatch",
|
||||
"%" => "mod",
|
||||
"&" => "and",
|
||||
"&&" => "andand",
|
||||
"*" => "mul",
|
||||
"**" => "pow",
|
||||
"+" => "add",
|
||||
"+@" => "plus",
|
||||
"-" => "sub",
|
||||
"-@" => "minus",
|
||||
"/" => "div",
|
||||
"<" => "lt",
|
||||
"<=" => "le",
|
||||
"<<" => "lshift",
|
||||
"<=>" => "cmp",
|
||||
"==" => "eq",
|
||||
"===" => "eqq",
|
||||
"=~" => "match",
|
||||
">" => "gt",
|
||||
">=" => "ge",
|
||||
">>" => "rshift",
|
||||
"[]" => "aref",
|
||||
"[]=" => "aset",
|
||||
"^" => "xor",
|
||||
"`" => "tick",
|
||||
"|" => "or",
|
||||
"||" => "oror",
|
||||
"~" => "neg",
|
||||
}
|
||||
|
||||
file presym_file => cfiles+rbfiles+psfiles+[__FILE__] do
|
||||
csymbols = cfiles.map do |f|
|
||||
src = File.read(f)
|
||||
src.gsub!(/\/\/.+(\n|$)/, "\n")
|
||||
[src.scan(/intern_lit\([^\n"]*"([^\n "]*)"/),
|
||||
src.scan(/mrb_define_method\([^\n"]*"([^\n"]*)"/),
|
||||
src.scan(/mrb_define_class_method\([^\n"]*"([^\n"]*)"/),
|
||||
src.scan(/mrb_define_class\([^\n"]*"([^\n"]*)"/),
|
||||
src.scan(/mrb_define_module\([^\n"]*"([^\n"]*)"/),
|
||||
src.scan(/mrb_define_module_function\([^\n"]*"([^\n"]*)"/),
|
||||
src.scan(/mrb_define_const\([^\n"]*"([^\n"]*)"/),
|
||||
src.scan(/mrb_define_global_const\([^\n"]*"([^\n"]*)"/),
|
||||
src.scan(/MRB_SYM\((\w+)\)/),
|
||||
src.scan(/MRB_QSYM\((\w+)\)/).map{|x,|
|
||||
x.sub!(/_p$/, "?") || x.sub!(/_b$/, "!") || x.sub!(/_e$/, "=") || x.sub!(/^0_/, "@") || x.sub!(/^00_/, "@@")
|
||||
}.compact]
|
||||
end
|
||||
rbsymbols = rbfiles.map do |f|
|
||||
src = File.read(f)
|
||||
src.force_encoding(Encoding::BINARY)
|
||||
[src.scan(/\bclass +([A-Z]\w*)/),
|
||||
src.scan(/\bmodule +([A-Z]\w*)/),
|
||||
src.scan(/\bdef +(\w+[!?=]?)/),
|
||||
src.scan(/\balias +(\w+[!?]?)/),
|
||||
src.scan(/\b([A-Z]\w*) *=[^=]/),
|
||||
src.scan(/(\$[a-zA-Z_]\w*)/),
|
||||
src.scan(/(\$[$!?0-9]\w*)/),
|
||||
src.scan(/(@@?[a-zA-Z_]\w*)/),
|
||||
src.scan(/[^.]\.([a-zA-Z_]\w*[!?]?)/),
|
||||
src.scan(/\.([a-zA-Z_]\w* *=)/).map{|x|x.map{|s|s.gsub(' ', '')}},
|
||||
src.scan(/\b([a-zA-Z_]\w*):/),
|
||||
src.scan(/:([a-zA-Z_]\w*[!?=]?)/),
|
||||
src.scan(/[\(\[\{ ]:"([^"]+)"/).map{|x|x.map{|s|s.gsub('\#', '#')}},
|
||||
src.scan(/[ \(\[\{]:'([^']+)'/)
|
||||
]
|
||||
end
|
||||
symbols = (symbols+csymbols+rbsymbols+op_table.keys).flatten.compact.uniq.sort.map{|x| x.gsub("\n", '\n')}
|
||||
presyms = File.readlines(presym_file) rescue []
|
||||
presyms.each{|x| x.chomp!}
|
||||
if presyms != symbols
|
||||
File.write(presym_file, symbols.join("\n"))
|
||||
end
|
||||
end
|
||||
|
||||
presym_inc=presym_file+".inc"
|
||||
file presym_inc => presym_file do
|
||||
presyms = File.readlines(presym_file)
|
||||
presyms.each{|x| x.chomp!}
|
||||
File.open(presym_inc, "w") do |f|
|
||||
f.print "/* MRB_PRESYM_CSYM(sym, num) - symbol which is valid C id name */\n"
|
||||
f.print "/* MRB_PRESYM_QSYM(name, sym, num) - symbol with alias name */\n"
|
||||
f.print "/* MRB_PRESYM_SYM(name, num) - symbol which is not valid C id */\n"
|
||||
presyms.each.with_index do |sym,i|
|
||||
if sym.bytes.detect{|x|x>0x80} || /\A\$/ =~ sym
|
||||
f.print "MRB_PRESYM_SYM(\"#{sym}\", #{i+1})\n"
|
||||
elsif /\A\w+\Z/ =~ sym
|
||||
f.print "MRB_PRESYM_CSYM(#{sym}, #{i+1})\n"
|
||||
elsif op_table.key?(sym)
|
||||
f.print "MRB_PRESYM_QSYM(\"#{sym}\", #{op_table[sym]}, #{i+1})\n"
|
||||
elsif /\A[A-Za-z_]\w*\?\Z/ =~ sym
|
||||
s = sym.dup; s[-1] = "_p"
|
||||
f.print "MRB_PRESYM_QSYM(\"#{sym}\", #{s}, #{i+1})\n"
|
||||
elsif /\A[A-Za-z_]\w*\!\Z/ =~ sym
|
||||
s = sym.dup; s[-1] = "_b"
|
||||
f.print "MRB_PRESYM_QSYM(\"#{sym}\", #{s}, #{i+1})\n"
|
||||
elsif /\A[A-Za-z_]\w*\=\Z/ =~ sym
|
||||
s = sym.dup; s[-1] = "_e"
|
||||
f.print "MRB_PRESYM_QSYM(\"#{sym}\", #{s}, #{i+1})\n"
|
||||
elsif /\A@@/ =~ sym
|
||||
s = sym.dup; s[0,2] = "00_"
|
||||
f.print "MRB_PRESYM_QSYM(\"#{sym}\", #{s}, #{i+1})\n"
|
||||
elsif /\A@/ =~ sym
|
||||
s = sym.dup; s[0] = "0_"
|
||||
f.print "MRB_PRESYM_QSYM(\"#{sym}\", #{s}, #{i+1})\n"
|
||||
else
|
||||
f.print "MRB_PRESYM_SYM(\"#{sym}\", #{i+1})\n"
|
||||
end
|
||||
end
|
||||
f.print "#define MRB_PRESYM_MAX #{presyms.size}"
|
||||
end
|
||||
end
|
||||
|
||||
desc "preallocated symbols"
|
||||
task :gensym => presym_inc
|
||||
task :all => :gensym
|
||||
|
||||
depfiles += MRuby.targets.map { |n, t|
|
||||
t.libraries
|
||||
}.flatten
|
||||
@@ -156,5 +294,7 @@ task :deep_clean => ["clean", "clean_doc"] do
|
||||
MRuby.each_target do |t|
|
||||
rm_rf t.gem_clone_dir
|
||||
end
|
||||
rm_f presym_file
|
||||
rm_f presym_inc
|
||||
puts "Cleaned up mrbgems build folder"
|
||||
end
|
||||
|
||||
+30
-23
@@ -1,39 +1,46 @@
|
||||
version: "{build}"
|
||||
|
||||
os: Visual Studio 2017
|
||||
|
||||
shallow_clone: true
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
# Visual Studio 2017 64bit
|
||||
- visualcpp: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat
|
||||
- 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
|
||||
|
||||
# Visual Studio 2017 32bit
|
||||
- visualcpp: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat
|
||||
- job_name: Visual Studio 2019 32bit
|
||||
visualcpp: C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars32.bat
|
||||
appveyor_build_worker_image: Visual Studio 2019
|
||||
|
||||
- job_name: Visual Studio 2017 64bit
|
||||
visualcpp: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat
|
||||
appveyor_build_worker_image: Visual Studio 2017
|
||||
|
||||
- job_name: Visual Studio 2017 32bit
|
||||
visualcpp: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars32.bat
|
||||
appveyor_build_worker_image: Visual Studio 2017
|
||||
|
||||
- job_name: Visual Studio 2015 64bit
|
||||
visualcpp: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat
|
||||
appveyor_build_worker_image: Visual Studio 2015
|
||||
machine: x86_amd64
|
||||
|
||||
- job_name: Visual Studio 2015 32bit
|
||||
visualcpp: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat
|
||||
appveyor_build_worker_image: Visual Studio 2015
|
||||
machine: x86
|
||||
|
||||
# Visual Studio 2015 64bit
|
||||
- visualcpp: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat
|
||||
machine: amd64
|
||||
|
||||
# Visual Studio 2015 32bit
|
||||
- visualcpp: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat
|
||||
machine: x86
|
||||
|
||||
# Visual Studio 2013 64bit
|
||||
- visualcpp: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat
|
||||
machine: amd64
|
||||
|
||||
|
||||
init:
|
||||
- call "%visualcpp%" %machine%
|
||||
# For using Rubyinstaller's Ruby 2.4 64bit
|
||||
- set PATH=C:\Ruby24-x64\bin;%PATH%
|
||||
# For using Rubyins4aller's Ruby 2.6 64bit
|
||||
# 2.6 is the highest supported Ruby version across all historical
|
||||
# Visual Studio AppVeyor images. Ruby 2.7 is only on the 2019 image.
|
||||
- set PATH=C:\Ruby26-x64\bin;%PATH%
|
||||
- ruby --version
|
||||
|
||||
|
||||
build_script:
|
||||
- set MRUBY_CONFIG=appveyor_config.rb
|
||||
- rake -m
|
||||
- set MRUBY_TARGET=appveyor
|
||||
- rake gensym
|
||||
- rake -m all
|
||||
- rake -E $stdout.sync=true test
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
def setup_option(conf)
|
||||
conf.cc.flags[0].delete("/Zi") unless ENV['CFLAGS']
|
||||
conf.cxx.flags[0].delete("/Zi") unless ENV['CFLAGS'] || ENV['CXXFLAGS']
|
||||
conf.linker.flags << "/DEBUG:NONE" unless ENV['LDFLAGS']
|
||||
end
|
||||
|
||||
MRuby::Build.new('full-debug') do |conf|
|
||||
toolchain :visualcpp
|
||||
enable_debug
|
||||
|
||||
# include all core GEMs
|
||||
conf.gembox 'full-core'
|
||||
conf.cc.defines += %w(MRB_GC_STRESS MRB_METHOD_CACHE MRB_ENABLE_DEBUG_HOOK)
|
||||
setup_option(conf)
|
||||
|
||||
conf.enable_test
|
||||
end
|
||||
|
||||
MRuby::Build.new do |conf|
|
||||
toolchain :visualcpp
|
||||
|
||||
# include all core GEMs
|
||||
conf.gembox 'full-core'
|
||||
conf.compilers.each do |c|
|
||||
c.defines += %w(MRB_GC_FIXED_ARENA)
|
||||
end
|
||||
setup_option(conf)
|
||||
conf.enable_bintest
|
||||
conf.enable_test
|
||||
end
|
||||
|
||||
MRuby::Build.new('cxx_abi') do |conf|
|
||||
toolchain :visualcpp
|
||||
|
||||
conf.gembox 'full-core'
|
||||
conf.compilers.each do |c|
|
||||
c.defines += %w(MRB_GC_FIXED_ARENA)
|
||||
end
|
||||
setup_option(conf)
|
||||
conf.enable_bintest
|
||||
conf.enable_test
|
||||
|
||||
enable_cxx_abi
|
||||
|
||||
build_mrbc_exec
|
||||
end
|
||||
+69
-32
@@ -14,37 +14,53 @@ To compile mruby out of the source code you need the following tools:
|
||||
|
||||
Note that `bison` bundled with MacOS is too old to compile `mruby`.
|
||||
Try `brew install bison` and follow the instuction shown to update
|
||||
the `$PATH` to compile `mruby`.
|
||||
the `$PATH` to compile `mruby`. We also encourage to upgrade `ruby`
|
||||
on MacOS in similar manner.
|
||||
|
||||
Optional:
|
||||
* GIT (to update mruby source and integrate mrbgems easier)
|
||||
* git (to update mruby source and integrate mrbgems easier)
|
||||
* C++ compiler (to use GEMs which include \*.cpp, \*.cxx, \*.cc)
|
||||
* Assembler (to use GEMs which include \*.asm)
|
||||
|
||||
## Usage
|
||||
## Build
|
||||
|
||||
To compile `mruby`, just call `rake` inside of the mruby source
|
||||
root. To generate and execute the test tools call `rake test`. To
|
||||
clean all build files call `rake clean`. To see full command line on
|
||||
build, call `rake -v`.
|
||||
|
||||
If you want to compile for the specific configuration, specify
|
||||
`MRUBY_TARGET` or `TARGET` environment variable, e.g
|
||||
|
||||
```sh
|
||||
rake TAGRET=host
|
||||
```
|
||||
|
||||
The default target is `host`. The compilation target desciption files
|
||||
(with `.rb` suffix) are contained in the `target` directory.
|
||||
|
||||
A build description file contains the build configuration of mruby and
|
||||
looks like the following for example:
|
||||
|
||||
Inside of the root directory of the mruby source a file exists
|
||||
called *build_config.rb*. This file contains the build configuration
|
||||
of mruby and looks like this for example:
|
||||
```ruby
|
||||
MRuby::Build.new do |conf|
|
||||
toolchain :gcc
|
||||
end
|
||||
```
|
||||
|
||||
All tools necessary to compile mruby can be set or modified here. In case
|
||||
you want to maintain an additional *build_config.rb* you can define a
|
||||
customized path using the *$MRUBY_CONFIG* environment variable.
|
||||
|
||||
To compile just call `rake` inside of the mruby source root. To
|
||||
generate and execute the test tools call `rake test`. To clean
|
||||
all build files call `rake clean`. To see full command line on
|
||||
build, call `rake -v`.
|
||||
All tools necessary to compile mruby can be set or modified here. In
|
||||
case you want to try different configuration, you can create a new
|
||||
configuration file under `target` and specify the configuration using
|
||||
the `MRUBY_TARGET` environment variable.
|
||||
|
||||
## Build Configuration
|
||||
|
||||
Inside of the *build_config.rb* the following options can be configured
|
||||
based on your environment.
|
||||
To create a new configuration, copy the existing configuration in the
|
||||
`target` directory, and modify it. We wish you submit a pull-request,
|
||||
once you created a new configuration for a new platform.
|
||||
|
||||
Inside of the configuration file, the following options can be
|
||||
configured based on your environment.
|
||||
|
||||
### Toolchains
|
||||
|
||||
@@ -88,15 +104,12 @@ in `ANDROID_STANDALONE_TOOLCHAIN`.
|
||||
### Binaries
|
||||
|
||||
It is possible to select which tools should be compiled during the compilation
|
||||
process. The following tools can be selected:
|
||||
* mruby (mruby interpreter)
|
||||
* mirb (mruby interactive shell)
|
||||
process. For example,
|
||||
|
||||
To select them declare conf.gem as follows:
|
||||
```ruby
|
||||
conf.gem "#{root}/mrbgems/mruby-bin-mruby"
|
||||
conf.gem "#{root}/mrbgems/mruby-bin-mirb"
|
||||
```
|
||||
* `mruby`
|
||||
* `mirb`
|
||||
|
||||
The configuration are done via `mrbgems`. See `Mrbgems` section.
|
||||
|
||||
### File Separator
|
||||
|
||||
@@ -209,17 +222,33 @@ end
|
||||
|
||||
### Mrbgems
|
||||
|
||||
Integrate GEMs in the build process.
|
||||
```ruby
|
||||
# Integrate GEM with additional configuration
|
||||
conf.gem 'path/to/gem' do |g|
|
||||
g.cc.flags << ...
|
||||
end
|
||||
`mruby` comes with the (sort of) packaging system named `mrbgems`. To
|
||||
specify `gem`, you can use `conf.gem` in the configuration file.
|
||||
|
||||
# Integrate GEM without additional configuration
|
||||
conf.gem 'path/to/another/gem'
|
||||
```ruby
|
||||
# Integrate a bundled Gem you see in `mrbgems` directory
|
||||
conf.gem :core => 'mruby-something'
|
||||
|
||||
# Integrate a Gem from GitHub
|
||||
conf.gem :github => 'someone/mruby-another'
|
||||
|
||||
# Integrate a mruby binary Gem
|
||||
conf.gem :core => 'mruby-bin-mruby'
|
||||
|
||||
# Integrate a interactive mruby binary Gem
|
||||
conf.gem :core => 'mruby-bin-mirb'
|
||||
|
||||
# Integrate GemBox (set of Gems)
|
||||
conf.gembox "default"
|
||||
```
|
||||
|
||||
A GemBox is a set of Gems defined in `mrbgems/default.gembox` for example.
|
||||
It's just a set of `mrbgem` configurations.
|
||||
|
||||
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.
|
||||
|
||||
### Mrbtest
|
||||
@@ -327,6 +356,10 @@ root directory. The structure of this directory will look like this:
|
||||
|
||||
+- build
|
||||
|
|
||||
+- presym <- List of preallocated symbolx
|
||||
|
|
||||
+- presym.inc <- C source file for preallocated symbols
|
||||
|
|
||||
+- host
|
||||
|
|
||||
+- bin <- Binaries (mirb, mrbc and mruby)
|
||||
@@ -378,6 +411,10 @@ In case of a cross-compilation to *i386* the *build* directory structure looks
|
||||
like this:
|
||||
|
||||
+- build
|
||||
|
|
||||
+- presym <- List of preallocated symbolx
|
||||
|
|
||||
+- presym.inc <- C source file for preallocated symbols
|
||||
|
|
||||
+- host
|
||||
| |
|
||||
|
||||
@@ -38,7 +38,7 @@ To confirm mrdb was installed properly, run mrdb with the `--version` option:
|
||||
|
||||
```bash
|
||||
$ mrdb --version
|
||||
mruby 2.1.2 (2020-07-10)
|
||||
mruby 2.1.2 (2020-08-06)
|
||||
```
|
||||
|
||||
## 2.2 Basic Operation
|
||||
|
||||
+10
-10
@@ -46,11 +46,11 @@ You can use mrbconfs with following ways:
|
||||
|
||||
## Primitive type configuration.
|
||||
|
||||
`MRB_USE_FLOAT`
|
||||
`MRB_USE_FLOAT32`
|
||||
* When defined single precision floating point type(C type `float`) is used as `mrb_float`.
|
||||
* Else double precision floating point type(C type `double`) is used as `mrb_float`.
|
||||
* Otherwise double precision floating point type(C type `double`) is used as `mrb_float`.
|
||||
|
||||
`MRB_WITHOUT_FLOAT`
|
||||
`MRB_NO_FLOAT`
|
||||
* When defined removes floating point numbers from mruby.
|
||||
* It makes mruby easier to handle in "Microcontroller without FPU" and "Kernel Space".
|
||||
|
||||
@@ -117,7 +117,7 @@ largest value of required alignment.
|
||||
|
||||
`MRB_NAN_BOXING`
|
||||
* If defined represent `mrb_value` in boxed `double`.
|
||||
* Conflicts with `MRB_USE_FLOAT` and `MRB_WITHOUT_FLOAT`.
|
||||
* Conflicts with `MRB_USE_FLOAT32` and `MRB_NO_FLOAT`.
|
||||
|
||||
`MRB_WORD_BOXING`
|
||||
* If defined represent `mrb_value` as a word.
|
||||
@@ -163,17 +163,17 @@ largest value of required alignment.
|
||||
* Default value is `128`.
|
||||
* Specifies initial capacity of `RString` created by `mrb_str_buf_new` function..
|
||||
|
||||
`MRB_METHOD_CACHE`
|
||||
* Improve performance for method dispatch.
|
||||
`MRB_NO_METHOD_CACHE`
|
||||
* Disable method cache to save memory.
|
||||
|
||||
`MRB_METHOD_CACHE_SIZE`
|
||||
* Default value is `128`.
|
||||
* Ignored if `MRB_METHOD_CACHE` is not defined.
|
||||
* Default value is `256`.
|
||||
* Ignored if `MRB_NO_METHOD_CACHE` is defined.
|
||||
* Need to be the power of 2.
|
||||
|
||||
`MRB_METHOD_T_STRUCT`
|
||||
`MRB_USE_METHOD_T_STRUCT`
|
||||
* Use C struct to represent `mrb_method_t`
|
||||
* No `MRB_METHOD_T_STRUCT` requires highest 2 bits of function pointers to be zero
|
||||
* No `MRB_USE_METHOD_T_STRUCT` requires highest 2 bits of function pointers to be zero
|
||||
* Define this macro on machines that use higher bits of pointers
|
||||
|
||||
`MRB_ENABLE_ALL_SYMBOLS`
|
||||
|
||||
+33
-27
@@ -17,7 +17,7 @@ Please help to improve it by submitting your findings.
|
||||
## `1/2` gives `0.5`
|
||||
|
||||
Since mruby does not have `Bignum`, bigger integers are represented
|
||||
by `Float` numbers. To enhance interoperability between `Fixnum`
|
||||
by `Float` numbers. To enhance interoperability between `Integer`
|
||||
and `Float`, mruby provides `Float#upto` and other iterating
|
||||
methods for the `Float` class. As a side effect, `1/2` gives `0.5`
|
||||
not `0`.
|
||||
@@ -38,7 +38,7 @@ puts [1,2,3]
|
||||
3
|
||||
```
|
||||
|
||||
#### mruby [2.1.2 (2020-07-10)]
|
||||
#### mruby [2.1.2 (2020-08-06)]
|
||||
|
||||
```
|
||||
[1, 2, 3]
|
||||
@@ -61,10 +61,17 @@ end
|
||||
|
||||
`ZeroDivisionError` is raised.
|
||||
|
||||
#### mruby [2.1.2 (2020-07-10)]
|
||||
#### mruby [2.1.2 (2020-08-06)]
|
||||
|
||||
No exception is raised.
|
||||
No exception is raised. Instead you have to do:
|
||||
|
||||
```ruby
|
||||
begin
|
||||
1 / 0
|
||||
rescue => e
|
||||
raise e
|
||||
end
|
||||
```
|
||||
## Fiber execution can't cross C function boundary
|
||||
|
||||
mruby's `Fiber` is implemented in a similar way to Lua's co-routine. This
|
||||
@@ -89,7 +96,7 @@ p Liste.new "foobar"
|
||||
|
||||
` [] `
|
||||
|
||||
#### mruby [2.1.2 (2020-07-10)]
|
||||
#### mruby [2.1.2 (2020-08-06)]
|
||||
|
||||
`ArgumentError` is raised.
|
||||
|
||||
@@ -119,7 +126,7 @@ false
|
||||
true
|
||||
```
|
||||
|
||||
#### mruby [2.1.2 (2020-07-10)]
|
||||
#### mruby [2.1.2 (2020-08-06)]
|
||||
|
||||
```
|
||||
true
|
||||
@@ -156,7 +163,7 @@ p 'ok'
|
||||
ok
|
||||
```
|
||||
|
||||
#### mruby [2.1.2 (2020-07-10)]
|
||||
#### mruby [2.1.2 (2020-08-06)]
|
||||
|
||||
```
|
||||
test.rb:8: undefined method 'test_func' (NoMethodError)
|
||||
@@ -178,7 +185,7 @@ defined?(Foo)
|
||||
nil
|
||||
```
|
||||
|
||||
#### mruby [2.1.2 (2020-07-10)]
|
||||
#### mruby [2.1.2 (2020-08-06)]
|
||||
|
||||
`NameError` is raised.
|
||||
|
||||
@@ -195,7 +202,7 @@ alias $a $__a__
|
||||
|
||||
` nil `
|
||||
|
||||
#### mruby [2.1.2 (2020-07-10)]
|
||||
#### mruby [2.1.2 (2020-08-06)]
|
||||
|
||||
Syntax error
|
||||
|
||||
@@ -217,7 +224,7 @@ end
|
||||
`ArgumentError` is raised.
|
||||
The re-defined `+` operator does not accept any arguments.
|
||||
|
||||
#### mruby [2.1.2 (2020-07-10)]
|
||||
#### mruby [2.1.2 (2020-08-06)]
|
||||
|
||||
` 'ab' `
|
||||
Behavior of the operator wasn't changed.
|
||||
@@ -233,7 +240,7 @@ $ ruby -e 'puts Proc.new {}.binding'
|
||||
#<Binding:0x00000e9deabb9950>
|
||||
```
|
||||
|
||||
#### mruby [2.1.2 (2020-07-10)]
|
||||
#### mruby [2.1.2 (2020-08-06)]
|
||||
|
||||
```
|
||||
$ ./bin/mruby -e 'puts Proc.new {}.binding'
|
||||
@@ -245,8 +252,7 @@ trace (most recent call last):
|
||||
## Keyword arguments
|
||||
|
||||
mruby keyword arguments behave slightly different from CRuby 2.5
|
||||
to make the behavior simpler and less confusing. Maybe in the
|
||||
future, the simpler behavior will be adopted to CRuby as well.
|
||||
to make the behavior simpler and less confusing.
|
||||
|
||||
#### Ruby [ruby 2.5.1p57 (2018-03-29 revision 63029)]
|
||||
|
||||
@@ -264,6 +270,20 @@ trace (most recent call last):
|
||||
-e:1: keyword argument hash with non symbol keys (ArgumentError)
|
||||
```
|
||||
|
||||
## `nil?` redefinition in conditional expressions
|
||||
|
||||
Redefinition of `nil?` is ignored in conditional expressions.
|
||||
|
||||
```ruby
|
||||
a = "a"
|
||||
def a.nil?
|
||||
true
|
||||
end
|
||||
puts(a.nil? ? "truthy" : "falsy")
|
||||
```
|
||||
|
||||
Ruby outputs `falsy`. mruby outputs `truthy`.
|
||||
|
||||
## Argument Destructuring
|
||||
|
||||
```ruby
|
||||
@@ -283,17 +303,3 @@ f(1,[2,3])
|
||||
```
|
||||
|
||||
CRuby gives `[1,2,3,nil]`. mruby raises `NoMethodError` for `b`.
|
||||
|
||||
## `nil?` redefinition in conditional expressions
|
||||
|
||||
Redefinition of `nil?` is ignored in conditional expressions.
|
||||
|
||||
```ruby
|
||||
a = "a"
|
||||
def a.nil?
|
||||
true
|
||||
end
|
||||
puts(a.nil? ? "truthy" : "falsy")
|
||||
```
|
||||
|
||||
Ruby outputs `falsy`. mruby outputs `truthy`.
|
||||
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
User visible changes in `mruby3`
|
||||
===
|
||||
|
||||
# Build System
|
||||
|
||||
You can specify `TARGET` option to `rake` via a command line
|
||||
option, or via an environment variable, e.g.
|
||||
|
||||
`rake TARGET=host all`
|
||||
|
||||
or
|
||||
|
||||
`TARGET=host rake all`
|
||||
|
||||
It's much easier to switch multiple targets than the
|
||||
previous `build_config.rb` system.
|
||||
|
||||
## `presym` target
|
||||
|
||||
The first compilation of `mruby` may require generation of a
|
||||
static symbol table named `build/presym`. You can generate
|
||||
the table by `rake gensym`.
|
||||
|
||||
## `target` directory
|
||||
|
||||
Build target specification files are loaded from `target`
|
||||
directory. The default `TARGET` is `host` which is described
|
||||
in `target/host.rb`. There are many other targets for example:
|
||||
|
||||
* `host-gprof`: compiles with `gprof` for performance tuning
|
||||
* `host-m32`: compiles in gcc 32bit mode on 64bit platforms
|
||||
* `boxing`: compiles all three boxing options
|
||||
* `clang-asan`: compiles with `clang`'s Address Sanitizer
|
||||
|
||||
`target/host.rb` comes with comments to help writing a new
|
||||
target description.
|
||||
|
||||
If you want to have your target description out of the
|
||||
source tree, you can specify the path to the description
|
||||
file in `MRUBY_CONFIG`.
|
||||
|
||||
# Build Target Contribution
|
||||
|
||||
When you write a new target description, please
|
||||
contribute. We welcome your contribution as a GitHub
|
||||
pull-request.
|
||||
|
||||
# Languge Changes
|
||||
|
||||
## New Syntax
|
||||
|
||||
We have ported some new syntax from CRuby.
|
||||
|
||||
* R-assignment (`12 => x`)
|
||||
* Numbered block parameter (`x.map{_1 * 2}`)
|
||||
* End-less `def` (`def double(x) = x*2`)
|
||||
|
||||
# Configuration Options Changed
|
||||
|
||||
Some configuration macro names are changed for consistency
|
||||
|
||||
## `MRB_NO_FLOAT`
|
||||
|
||||
Changed from `MRB_WITHOUT_FLOAT` to conform `USE_XXX` naming
|
||||
convention.
|
||||
|
||||
## `MRB_USE_FLOAT32`
|
||||
|
||||
Changed from `MRB_USE_FLOAT` to make sure `float` here means
|
||||
using single precision float, and not the opposite of
|
||||
`MRB_NO_FLOAT`.
|
||||
|
||||
## `MRB_USE_METHOD_T_STRUCT`
|
||||
|
||||
Changed from `MRB_METHOD_T_STRUCT`.
|
||||
|
||||
To use `struct` version of `mrb_method_t`. More portable but consumes more memory.
|
||||
Turned on by default on 32bit platforms.
|
||||
|
||||
## `MRB_NO_BOXING`
|
||||
|
||||
Uses `struct` to represent `mrb_value`. Consumes more memory
|
||||
but easier to inveticate the internal and to debug. It used
|
||||
to be default `mrb_value` representation. Now the default is
|
||||
`MRB_WORD_BOXING`.
|
||||
|
||||
## `MRB_WORD_BOXING`
|
||||
|
||||
Pack `mrb_value` in an `intptr_t` integer. Consumes less
|
||||
memory compared to `MRB_NO_BOXING` especially on 32 bit
|
||||
platforms. `Fixnum` size is 31 bits so some integer values
|
||||
does not fit in `Fixnum` integers.
|
||||
|
||||
## `MRB_NAN_BOXING`
|
||||
|
||||
Pack `mrb_value` in a floating pointer number. Nothing
|
||||
changed from previous versions.
|
||||
|
||||
## `MRB_USE_MALLOC_TRIM`
|
||||
|
||||
Call `malloc_trim(0)` from mrb_full_gc() if this macro is defined.
|
||||
If you are using glibc malloc, this macro could reduce memory consumption.
|
||||
|
||||
# Internal Changes
|
||||
|
||||
## `Random` now use `xoshiro128++`.
|
||||
|
||||
For better and faster random number generation.
|
||||
+93
-107
@@ -20,121 +20,107 @@ sign) of operands.
|
||||
* sS: signed 16bit
|
||||
* W: 24bit
|
||||
|
||||
First two byte operands may be extended to 16bit. When those byte
|
||||
operands are bigger than 256, the instruction will be prefixed by
|
||||
`OP_EXT1` (means 1st operand is 16bit) or `OP_EXT2` (means 2nd operand
|
||||
is 16bit) or `OP_EXT3` (means 1st and 2nd operands are 16bit).
|
||||
|
||||
For instructions marked by `'`, `OP_EXT1` can be prefixed. For those
|
||||
with `"`, either `OP_EXT1` or `OP_EXT2` or `OP_EXT2` can be prefixed.
|
||||
|
||||
## table.1 Instruction Table
|
||||
|
||||
| Instruction Name | Operand type | Semantics |
|
||||
|------------------|--------------|--------------------------------------------------------|
|
||||
| OP_NOP | - | no operation |
|
||||
| OP_MOVE" | BB | R(a) = R(b) |
|
||||
| OP_LOADL" | BB | R(a) = Pool(b) |
|
||||
| OP_LOADI" | BB | R(a) = mrb_int(b) |
|
||||
| OP_LOADINEG" | BB | R(a) = mrb_int(-b) |
|
||||
| OP_LOADI__1' | B | R(a) = mrb_int(-1) |
|
||||
| OP_LOADI_0' | B | R(a) = mrb_int(0) |
|
||||
| OP_LOADI_1' | B | R(a) = mrb_int(1) |
|
||||
| OP_LOADI_2' | B | R(a) = mrb_int(2) |
|
||||
| OP_LOADI_3' | B | R(a) = mrb_int(3) |
|
||||
| OP_LOADI_4' | B | R(a) = mrb_int(4) |
|
||||
| OP_LOADI_5' | B | R(a) = mrb_int(5) |
|
||||
| OP_LOADI_6' | B | R(a) = mrb_int(6) |
|
||||
| OP_LOADI_7' | B | R(a) = mrb_int(7) |
|
||||
| OP_LOADI16' | BsS | R(a) = mrb_int(b) |
|
||||
| OP_LOADSYM" | BB | R(a) = Syms(b) |
|
||||
| OP_LOADNIL' | B | R(a) = nil |
|
||||
| OP_LOADSELF' | B | R(a) = self |
|
||||
| OP_LOADT' | B | R(a) = true |
|
||||
| OP_LOADF' | B | R(a) = false |
|
||||
| OP_GETGV" | BB | R(a) = getglobal(Syms(b)) |
|
||||
| OP_SETGV" | BB | setglobal(Syms(b), R(a)) |
|
||||
| OP_GETSV" | BB | R(a) = Special[Syms(b)] |
|
||||
| OP_SETSV" | BB | Special[Syms(b)] = R(a) |
|
||||
| OP_GETIV" | BB | R(a) = ivget(Syms(b)) |
|
||||
| OP_SETIV" | BB | ivset(Syms(b),R(a)) |
|
||||
| OP_GETCV" | BB | R(a) = cvget(Syms(b)) |
|
||||
| OP_SETCV" | BB | cvset(Syms(b),R(a)) |
|
||||
| OP_GETCONST" | BB | R(a) = constget(Syms(b)) |
|
||||
| OP_SETCONST" | BB | constset(Syms(b),R(a)) |
|
||||
| OP_GETMCNST" | BB | R(a) = R(a)::Syms(b) |
|
||||
| OP_SETMCNST" | BB | R(a+1)::Syms(b) = R(a) |
|
||||
| OP_GETUPVAR" | BBB | R(a) = uvget(b,c) |
|
||||
| OP_SETUPVAR" | BBB | uvset(b,c,R(a)) |
|
||||
| OP_MOVE | BB | R(a) = R(b) |
|
||||
| OP_LOADL | BB | R(a) = Pool(b) |
|
||||
| OP_LOADI | BB | R(a) = mrb_int(b) |
|
||||
| OP_LOADINEG | BB | R(a) = mrb_int(-b) |
|
||||
| OP_LOADI__1 | B | R(a) = mrb_int(-1) |
|
||||
| OP_LOADI_0 | B | R(a) = mrb_int(0) |
|
||||
| OP_LOADI_1 | B | R(a) = mrb_int(1) |
|
||||
| OP_LOADI_2 | B | R(a) = mrb_int(2) |
|
||||
| OP_LOADI_3 | B | R(a) = mrb_int(3) |
|
||||
| OP_LOADI_4 | B | R(a) = mrb_int(4) |
|
||||
| OP_LOADI_5 | B | R(a) = mrb_int(5) |
|
||||
| OP_LOADI_6 | B | R(a) = mrb_int(6) |
|
||||
| OP_LOADI_7 | B | R(a) = mrb_int(7) |
|
||||
| OP_LOADI16 | BsS | R(a) = mrb_int(b) |
|
||||
| OP_LOADSYM | BB | R(a) = Syms(b) |
|
||||
| OP_LOADNIL | B | R(a) = nil |
|
||||
| OP_LOADSELF | B | R(a) = self |
|
||||
| OP_LOADT | B | R(a) = true |
|
||||
| OP_LOADF | B | R(a) = false |
|
||||
| OP_GETGV | BB | R(a) = getglobal(Syms(b)) |
|
||||
| OP_SETGV | BB | setglobal(Syms(b), R(a)) |
|
||||
| OP_GETSV | BB | R(a) = Special[Syms(b)] |
|
||||
| OP_SETSV | BB | Special[Syms(b)] = R(a) |
|
||||
| OP_GETIV | BB | R(a) = ivget(Syms(b)) |
|
||||
| OP_SETIV | BB | ivset(Syms(b),R(a)) |
|
||||
| OP_GETCV | BB | R(a) = cvget(Syms(b)) |
|
||||
| OP_SETCV | BB | cvset(Syms(b),R(a)) |
|
||||
| OP_GETCONST | BB | R(a) = constget(Syms(b)) |
|
||||
| OP_SETCONST | BB | constset(Syms(b),R(a)) |
|
||||
| OP_GETMCNST | BB | R(a) = R(a)::Syms(b) |
|
||||
| OP_SETMCNST | BB | R(a+1)::Syms(b) = R(a) |
|
||||
| OP_GETUPVAR | BBB | R(a) = uvget(b,c) |
|
||||
| OP_SETUPVAR | BBB | uvset(b,c,R(a)) |
|
||||
| OP_JMP | S | pc=a |
|
||||
| OP_JMPIF' | BS | if R(a) pc=b |
|
||||
| OP_JMPNOT' | BS | if !R(a) pc=b |
|
||||
| OP_JMPNIL' | BS | if R(a)==nil pc=b |
|
||||
| OP_ONERR | S | rescue_push(a) |
|
||||
| OP_EXCEPT' | B | R(a) = exc |
|
||||
| OP_RESCUE" | BB | R(b) = R(a).isa?(R(b)) |
|
||||
| OP_POPERR' | B | a.times{rescue_pop()} |
|
||||
| OP_RAISE' | B | raise(R(a)) |
|
||||
| OP_EPUSH' | B | ensure_push(SEQ[a]) |
|
||||
| OP_EPOP' | B | A.times{ensure_pop().call} |
|
||||
| OP_SENDV" | BB | R(a) = call(R(a),Syms(b),*R(a+1)) |
|
||||
| OP_SENDVB" | BB | R(a) = call(R(a),Syms(b),*R(a+1),&R(a+2)) |
|
||||
| OP_SEND" | BBB | R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c)) |
|
||||
| OP_SENDB" | BBB | R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c),&R(a+c+1)) |
|
||||
| OP_JMPIF | BS | if R(a) pc=b |
|
||||
| OP_JMPNOT | BS | if !R(a) pc=b |
|
||||
| OP_JMPNIL | BS | if R(a)==nil pc=b |
|
||||
| OP_JMPUW | S | unwind_and_jump_to(a) |
|
||||
| OP_EXCEPT | B | R(a) = exc |
|
||||
| OP_RESCUE | BB | R(b) = R(a).isa?(R(b)) |
|
||||
| OP_RAISEIF | B | raise(R(a)) if R(a) |
|
||||
| OP_SENDV | BB | R(a) = call(R(a),Syms(b),*R(a+1)) |
|
||||
| OP_SENDVB | BB | R(a) = call(R(a),Syms(b),*R(a+1),&R(a+2)) |
|
||||
| OP_SEND | BBB | R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c)) |
|
||||
| OP_SENDB | BBB | R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c),&R(a+c+1)) |
|
||||
| OP_CALL | - | R(0) = self.call(frame.argc, frame.argv) |
|
||||
| OP_SUPER" | BB | R(a) = super(R(a+1),... ,R(a+b+1)) |
|
||||
| OP_ARGARY' | BS | R(a) = argument array (16=5:1:5:1:4) |
|
||||
| OP_SUPER | BB | R(a) = super(R(a+1),... ,R(a+b+1)) |
|
||||
| OP_ARGARY | BS | R(a) = argument array (16=5:1:5:1:4) |
|
||||
| OP_ENTER | W | arg setup according to flags (23=5:5:1:5:5:1:1) |
|
||||
| OP_KEY_P" | BB | R(a) = kdict.key?(Syms(b)) |
|
||||
| OP_KEY_P | BB | R(a) = kdict.key?(Syms(b)) |
|
||||
| OP_KEYEND | - | raise unless kdict.empty? |
|
||||
| OP_KARG" | BB | R(a) = kdict[Syms(b)]; kdict.delete(Syms(b)) |
|
||||
| OP_RETURN' | B | return R(a) (normal) |
|
||||
| OP_RETURN_BLK' | B | return R(a) (in-block return) |
|
||||
| OP_BREAK' | B | break R(a) |
|
||||
| OP_BLKPUSH' | BS | R(a) = block (16=5:1:5:1:4) |
|
||||
| OP_ADD' | B | R(a) = R(a)+R(a+1) |
|
||||
| OP_ADDI" | BB | R(a) = R(a)+mrb_int(b) |
|
||||
| OP_SUB' | B | R(a) = R(a)-R(a+1) |
|
||||
| OP_SUBI" | BB | R(a) = R(a)-mrb_int(b) |
|
||||
| OP_MUL' | B | R(a) = R(a)*R(a+1) |
|
||||
| OP_DIV' | B | R(a) = R(a)/R(a+1) |
|
||||
| OP_EQ' | B | R(a) = R(a)==R(a+1) |
|
||||
| OP_LT' | B | R(a) = R(a)<R(a+1) |
|
||||
| OP_LE' | B | R(a) = R(a)<=R(a+1) |
|
||||
| OP_GT' | B | R(a) = R(a)>R(a+1) |
|
||||
| OP_GE' | B | R(a) = R(a)>=R(a+1) |
|
||||
| OP_ARRAY" | BB | R(a) = ary_new(R(a),R(a+1)..R(a+b)) |
|
||||
| OP_ARRAY2" | BBB | R(a) = ary_new(R(b),R(b+1)..R(b+c)) |
|
||||
| OP_ARYCAT' | B | ary_cat(R(a),R(a+1)) |
|
||||
| OP_ARYPUSH' | B | ary_push(R(a),R(a+1)) |
|
||||
| OP_ARYDUP' | B | R(a) = ary_dup(R(a)) |
|
||||
| OP_AREF" | BBB | R(a) = R(b)[c] |
|
||||
| OP_ASET" | BBB | R(a)[c] = R(b) |
|
||||
| OP_APOST" | BBB | *R(a),R(a+1)..R(a+c) = R(a)[b..] |
|
||||
| OP_INTERN' | B | R(a) = intern(R(a)) |
|
||||
| OP_STRING" | BB | R(a) = str_dup(Lit(b)) |
|
||||
| OP_STRCAT' | B | str_cat(R(a),R(a+1)) |
|
||||
| OP_HASH" | BB | R(a) = hash_new(R(a),R(a+1)..R(a+b)) |
|
||||
| OP_HASHADD" | BB | R(a) = hash_push(R(a),R(a+1)..R(a+b)) |
|
||||
| OP_HASHCAT' | B | R(a) = hash_cat(R(a),R(a+1)) |
|
||||
| OP_LAMBDA" | BB | R(a) = lambda(SEQ[b],OP_L_LAMBDA) |
|
||||
| OP_BLOCK" | BB | R(a) = lambda(SEQ[b],OP_L_BLOCK) |
|
||||
| OP_METHOD" | BB | R(a) = lambda(SEQ[b],OP_L_METHOD) |
|
||||
| OP_RANGE_INC' | B | R(a) = range_new(R(a),R(a+1),FALSE) |
|
||||
| OP_RANGE_EXC' | B | R(a) = range_new(R(a),R(a+1),TRUE) |
|
||||
| OP_OCLASS' | B | R(a) = ::Object |
|
||||
| OP_CLASS" | BB | R(a) = newclass(R(a),Syms(b),R(a+1)) |
|
||||
| OP_MODULE" | BB | R(a) = newmodule(R(a),Syms(b)) |
|
||||
| OP_EXEC" | BB | R(a) = blockexec(R(a),SEQ[b]) |
|
||||
| OP_DEF" | BB | R(a).newmethod(Syms(b),R(a+1)) |
|
||||
| OP_ALIAS" | BB | alias_method(target_class,Syms(a),Syms(b)) |
|
||||
| OP_UNDEF' | B | undef_method(target_class,Syms(a)) |
|
||||
| OP_SCLASS' | B | R(a) = R(a).singleton_class |
|
||||
| OP_TCLASS' | B | R(a) = target_class |
|
||||
| OP_DEBUG" | BBB | print a,b,c |
|
||||
| OP_ERR' | B | raise(LocalJumpError, Lit(a)) |
|
||||
| OP_EXT1 | - | make 1st operand 16bit |
|
||||
| OP_EXT2 | - | make 2nd operand 16bit |
|
||||
| OP_EXT3 | - | make 1st and 2nd operands 16bit |
|
||||
| OP_KARG | BB | R(a) = kdict[Syms(b)]; kdict.delete(Syms(b)) |
|
||||
| OP_RETURN | B | return R(a) (normal) |
|
||||
| OP_RETURN_BLK | B | return R(a) (in-block return) |
|
||||
| OP_BREAK | B | break R(a) |
|
||||
| OP_BLKPUSH | BS | R(a) = block (16=5:1:5:1:4) |
|
||||
| OP_ADD | B | R(a) = R(a)+R(a+1) |
|
||||
| OP_ADDI | BB | R(a) = R(a)+mrb_int(b) |
|
||||
| OP_SUB | B | R(a) = R(a)-R(a+1) |
|
||||
| OP_SUBI | BB | R(a) = R(a)-mrb_int(b) |
|
||||
| OP_MUL | B | R(a) = R(a)*R(a+1) |
|
||||
| OP_DIV | B | R(a) = R(a)/R(a+1) |
|
||||
| OP_EQ | B | R(a) = R(a)==R(a+1) |
|
||||
| OP_LT | B | R(a) = R(a)<R(a+1) |
|
||||
| OP_LE | B | R(a) = R(a)<=R(a+1) |
|
||||
| OP_GT | B | R(a) = R(a)>R(a+1) |
|
||||
| OP_GE | B | R(a) = R(a)>=R(a+1) |
|
||||
| OP_ARRAY | BB | R(a) = ary_new(R(a),R(a+1)..R(a+b)) |
|
||||
| OP_ARRAY2 | BBB | R(a) = ary_new(R(b),R(b+1)..R(b+c)) |
|
||||
| OP_ARYCAT | B | ary_cat(R(a),R(a+1)) |
|
||||
| OP_ARYPUSH | B | ary_push(R(a),R(a+1)) |
|
||||
| OP_ARYDUP | B | R(a) = ary_dup(R(a)) |
|
||||
| OP_AREF | BBB | R(a) = R(b)[c] |
|
||||
| OP_ASET | BBB | R(a)[c] = R(b) |
|
||||
| OP_APOST | BBB | *R(a),R(a+1)..R(a+c) = R(a)[b..] |
|
||||
| OP_INTERN | B | R(a) = intern(R(a)) |
|
||||
| OP_STRING | BB | R(a) = str_dup(Lit(b)) |
|
||||
| OP_STRCAT | B | str_cat(R(a),R(a+1)) |
|
||||
| OP_HASH | BB | R(a) = hash_new(R(a),R(a+1)..R(a+b)) |
|
||||
| OP_HASHADD | BB | R(a) = hash_push(R(a),R(a+1)..R(a+b)) |
|
||||
| OP_HASHCAT | B | R(a) = hash_cat(R(a),R(a+1)) |
|
||||
| OP_LAMBDA | BB | R(a) = lambda(SEQ[b],OP_L_LAMBDA) |
|
||||
| OP_BLOCK | BB | R(a) = lambda(SEQ[b],OP_L_BLOCK) |
|
||||
| OP_METHOD | BB | R(a) = lambda(SEQ[b],OP_L_METHOD) |
|
||||
| OP_RANGE_INC | B | R(a) = range_new(R(a),R(a+1),FALSE) |
|
||||
| OP_RANGE_EXC | B | R(a) = range_new(R(a),R(a+1),TRUE) |
|
||||
| OP_OCLASS | B | R(a) = ::Object |
|
||||
| OP_CLASS | BB | R(a) = newclass(R(a),Syms(b),R(a+1)) |
|
||||
| OP_MODULE | BB | R(a) = newmodule(R(a),Syms(b)) |
|
||||
| OP_EXEC | BB | R(a) = blockexec(R(a),SEQ[b]) |
|
||||
| OP_DEF | BB | R(a).newmethod(Syms(b),R(a+1)) |
|
||||
| OP_ALIAS | BB | alias_method(target_class,Syms(a),Syms(b)) |
|
||||
| OP_UNDEF | B | undef_method(target_class,Syms(a)) |
|
||||
| OP_SCLASS | B | R(a) = R(a).singleton_class |
|
||||
| OP_TCLASS | B | R(a) = target_class |
|
||||
| OP_DEBUG | BBB | print a,b,c |
|
||||
| OP_ERR | B | raise(LocalJumpError, Lit(a)) |
|
||||
| OP_STOP | - | stop VM |
|
||||
|------------------|--------------|--------------------------------------------------------|
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
module CRubyExtension
|
||||
def CRubyExtension.ruby_method
|
||||
puts "A Ruby Extension"
|
||||
puts "#{self}: A Ruby Extension"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
#include <mruby.h>
|
||||
#include <mruby/string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static mrb_value
|
||||
mrb_c_method(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
puts("A C Extension");
|
||||
mrb_value self_str = mrb_str_to_str(mrb, self);
|
||||
|
||||
printf("%s: A C Extension\n", mrb_str_to_cstr(mrb, self_str));
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
#include <mruby.h>
|
||||
#include <mruby/string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static mrb_value
|
||||
mrb_c_method(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
puts("A C Extension");
|
||||
mrb_value self_str = mrb_str_to_str(mrb, self);
|
||||
|
||||
printf("%s: A C Extension\n", mrb_str_to_cstr(mrb, self_str));
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
class RubyExtension
|
||||
def RubyExtension.ruby_method
|
||||
puts "A Ruby Extension"
|
||||
puts "#{self}: A Ruby Extension"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
MRuby::Build.new do |conf|
|
||||
|
||||
# Gets set by the VS command prompts.
|
||||
if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR']
|
||||
toolchain :visualcpp
|
||||
else
|
||||
toolchain :gcc
|
||||
end
|
||||
|
||||
enable_debug
|
||||
|
||||
# include the default GEMs
|
||||
conf.gembox 'default'
|
||||
end
|
||||
|
||||
# Requires Android NDK r13 or later.
|
||||
MRuby::CrossBuild.new('android-arm64-v8a') do |conf|
|
||||
params = {
|
||||
:arch => 'arm64-v8a',
|
||||
:platform => 'android-24',
|
||||
:toolchain => :clang,
|
||||
}
|
||||
toolchain :android, params
|
||||
|
||||
conf.gembox 'default'
|
||||
end
|
||||
@@ -1,26 +0,0 @@
|
||||
MRuby::Build.new do |conf|
|
||||
|
||||
# Gets set by the VS command prompts.
|
||||
if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR']
|
||||
toolchain :visualcpp
|
||||
else
|
||||
toolchain :gcc
|
||||
end
|
||||
|
||||
enable_debug
|
||||
|
||||
# include the default GEMs
|
||||
conf.gembox 'default'
|
||||
end
|
||||
|
||||
# Requires Android NDK r13 or later.
|
||||
MRuby::CrossBuild.new('android-armeabi') do |conf|
|
||||
params = {
|
||||
:arch => 'armeabi',
|
||||
:platform => 'android-24',
|
||||
:toolchain => :clang,
|
||||
}
|
||||
toolchain :android, params
|
||||
|
||||
conf.gembox 'default'
|
||||
end
|
||||
+53
-32
@@ -25,33 +25,69 @@
|
||||
#endif
|
||||
|
||||
/* configuration options: */
|
||||
/* add -DMRB_USE_FLOAT to use float instead of double for floating point numbers */
|
||||
//#define MRB_USE_FLOAT
|
||||
/* add -DMRB_USE_FLOAT32 to use float instead of double for floating point numbers */
|
||||
//#define MRB_USE_FLOAT32
|
||||
|
||||
/* exclude floating point numbers */
|
||||
//#define MRB_WITHOUT_FLOAT
|
||||
//#define MRB_NO_FLOAT
|
||||
|
||||
/* add -DMRB_METHOD_CACHE to use method cache to improve performance */
|
||||
//#define MRB_METHOD_CACHE
|
||||
/* obsolete configuration */
|
||||
#if defined(MRB_USE_FLOAT)
|
||||
# define MRB_USE_FLOAT32
|
||||
#endif
|
||||
|
||||
/* obsolete configuration */
|
||||
#if defined(MRB_WITHOUT_FLOAT)
|
||||
# define MRB_NO_FLOAT
|
||||
#endif
|
||||
|
||||
#if defined(MRB_USE_FLOAT32) && defined(MRB_NO_FLOAT)
|
||||
#error Cannot define MRB_USE_FLOAT32 and MRB_NO_FLOAT at the same time
|
||||
#endif
|
||||
|
||||
/* add -DMRB_NO_METHOD_CACHE to disable method cache to save memory */
|
||||
//#define MRB_NO_METHOD_CACHE
|
||||
/* size of the method cache (need to be the power of 2) */
|
||||
//#define MRB_METHOD_CACHE_SIZE (1<<7)
|
||||
//#define MRB_METHOD_CACHE_SIZE (1<<8)
|
||||
|
||||
/* add -DMRB_METHOD_T_STRUCT on machines that use higher bits of pointers */
|
||||
/* no MRB_METHOD_T_STRUCT requires highest 2 bits of function pointers to be zero */
|
||||
#ifndef MRB_METHOD_T_STRUCT
|
||||
/* add -DMRB_USE_METHOD_T_STRUCT on machines that use higher bits of function pointers */
|
||||
/* no MRB_USE_METHOD_T_STRUCT requires highest 2 bits of function pointers to be zero */
|
||||
#ifndef MRB_USE_METHOD_T_STRUCT
|
||||
// can't use highest 2 bits of function pointers at least on 32bit
|
||||
// Windows and 32bit Linux.
|
||||
# ifdef MRB_32BIT
|
||||
# define MRB_METHOD_T_STRUCT
|
||||
# define MRB_USE_METHOD_T_STRUCT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* define on big endian machines; used by MRB_NAN_BOXING, etc. */
|
||||
#ifndef MRB_ENDIAN_BIG
|
||||
# if (defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN) || \
|
||||
(defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
|
||||
# define MRB_ENDIAN_BIG
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* represent mrb_value in boxed double; conflict with MRB_USE_FLOAT32 and MRB_NO_FLOAT */
|
||||
//#define MRB_NAN_BOXING
|
||||
|
||||
/* represent mrb_value as a word (natural unit of data for the processor) */
|
||||
//#define MRB_WORD_BOXING
|
||||
|
||||
/* represent mrb_value as a struct; occupies 2 words */
|
||||
//#define MRB_NO_BOXING
|
||||
|
||||
/* if no specific boxing type is chosen */
|
||||
#if !defined(MRB_NAN_BOXING) && !defined(MRB_WORD_BOXING) && !defined(MRB_NO_BOXING)
|
||||
# define MRB_WORD_BOXING
|
||||
#endif
|
||||
|
||||
/* add -DMRB_INT32 to use 32bit integer for mrb_int; conflict with MRB_INT64;
|
||||
Default for 32-bit CPU mode. */
|
||||
//#define MRB_INT32
|
||||
|
||||
/* add -DMRB_INT64 to use 64bit integer for mrb_int; conflict with MRB_INT32;
|
||||
Default for 64-bit CPU mode. */
|
||||
Default for 64-bit CPU mode (unless using MRB_NAN_BOXING). */
|
||||
//#define MRB_INT64
|
||||
|
||||
/* if no specific integer type is chosen */
|
||||
@@ -65,19 +101,8 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* define on big endian machines; used by MRB_NAN_BOXING, etc. */
|
||||
#ifndef MRB_ENDIAN_BIG
|
||||
# if (defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN) || \
|
||||
(defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
|
||||
# define MRB_ENDIAN_BIG
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* represent mrb_value in boxed double; conflict with MRB_USE_FLOAT and MRB_WITHOUT_FLOAT */
|
||||
//#define MRB_NAN_BOXING
|
||||
|
||||
/* represent mrb_value as a word (natural unit of data for the processor) */
|
||||
//#define MRB_WORD_BOXING
|
||||
/* call malloc_trim(0) from mrb_full_gc() */
|
||||
//#define MRB_USE_MALLOC_TRIM
|
||||
|
||||
/* string class to handle UTF-8 encoding */
|
||||
//#define MRB_UTF8_STRING
|
||||
@@ -160,6 +185,10 @@
|
||||
|
||||
/* A profile for micro controllers */
|
||||
#if defined(MRB_CONSTRAINED_BASELINE_PROFILE)
|
||||
# ifndef MRB_NO_METHOD_CACHE
|
||||
# define MRB_NO_METHOD_CACHE
|
||||
# endif
|
||||
|
||||
# ifndef KHASH_DEFAULT_SIZE
|
||||
# define KHASH_DEFAULT_SIZE 16
|
||||
# endif
|
||||
@@ -177,10 +206,6 @@
|
||||
|
||||
/* A profile for desktop computers or workstations; rich memory! */
|
||||
#elif defined(MRB_MAIN_PROFILE)
|
||||
# ifndef MRB_METHOD_CACHE
|
||||
# define MRB_METHOD_CACHE
|
||||
# endif
|
||||
|
||||
# ifndef MRB_METHOD_CACHE_SIZE
|
||||
# define MRB_METHOD_CACHE_SIZE (1<<10)
|
||||
# endif
|
||||
@@ -195,10 +220,6 @@
|
||||
|
||||
/* A profile for server; mruby vm is long life */
|
||||
#elif defined(MRB_HIGH_PROFILE)
|
||||
# ifndef MRB_METHOD_CACHE
|
||||
# define MRB_METHOD_CACHE
|
||||
# endif
|
||||
|
||||
# ifndef MRB_METHOD_CACHE_SIZE
|
||||
# define MRB_METHOD_CACHE_SIZE (1<<12)
|
||||
# endif
|
||||
|
||||
+113
-79
@@ -62,20 +62,37 @@
|
||||
#define mrb_assert_int_fit(t1,n,t2,max) ((void)0)
|
||||
#endif
|
||||
|
||||
#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L
|
||||
#define mrb_static_assert(exp, str) _Static_assert(exp, str)
|
||||
#if (defined __cplusplus && __cplusplus >= 201103L) || \
|
||||
(defined _MSC_VER) || \
|
||||
(defined __GXX_EXPERIMENTAL_CXX0X__) /* for old G++/Clang++ */
|
||||
# define mrb_static_assert(exp, str) static_assert(exp, str)
|
||||
#elif defined __STDC_VERSION__ && \
|
||||
((__STDC_VERSION__ >= 201112L) || \
|
||||
(defined __GNUC__ && __GNUC__ * 100 + __GNUC_MINOR__ >= 406))
|
||||
# define mrb_static_assert(exp, str) _Static_assert(exp, str)
|
||||
#else
|
||||
#define mrb_static_assert(exp, str) mrb_assert(exp)
|
||||
# /* alternative implementation of static_assert() */
|
||||
# define _mrb_static_assert_cat0(a, b) a##b
|
||||
# define _mrb_static_assert_cat(a, b) _mrb_static_assert_cat0(a, b)
|
||||
# ifdef __COUNTER__
|
||||
# define _mrb_static_assert_id(prefix) _mrb_static_assert_cat(prefix, __COUNTER__)
|
||||
# else
|
||||
# define _mrb_static_assert_id(prefix) _mrb_static_assert_cat(prefix, __LINE__)
|
||||
# endif
|
||||
# define mrb_static_assert(exp, str) \
|
||||
struct _mrb_static_assert_id(_mrb_static_assert_) { char x[(exp) ? 1 : -1]; }
|
||||
#endif
|
||||
#define mrb_static_assert1(exp) mrb_static_assert(exp, #exp)
|
||||
|
||||
#include "mrbconf.h"
|
||||
|
||||
#include <mruby/common.h>
|
||||
#include <mruby/value.h>
|
||||
#include <mruby/gc.h>
|
||||
#include <mruby/presym.h>
|
||||
#include <mruby/version.h>
|
||||
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
#include <float.h>
|
||||
#ifndef FLT_EPSILON
|
||||
#define FLT_EPSILON (1.19209290e-07f)
|
||||
@@ -87,7 +104,7 @@
|
||||
#define LDBL_EPSILON (1.08420217248550443401e-19L)
|
||||
#endif
|
||||
|
||||
#ifdef MRB_USE_FLOAT
|
||||
#ifdef MRB_USE_FLOAT32
|
||||
#define MRB_FLOAT_EPSILON FLT_EPSILON
|
||||
#else
|
||||
#define MRB_FLOAT_EPSILON DBL_EPSILON
|
||||
@@ -130,15 +147,13 @@ typedef void* (*mrb_allocf) (struct mrb_state *mrb, void*, size_t, void *ud);
|
||||
|
||||
typedef struct {
|
||||
mrb_sym mid;
|
||||
struct RProc *proc;
|
||||
const struct RProc *proc;
|
||||
mrb_value *stackent;
|
||||
uint16_t ridx;
|
||||
uint16_t epos;
|
||||
struct REnv *env;
|
||||
const mrb_code *pc; /* return address */
|
||||
const mrb_code *err; /* error position */
|
||||
int argc;
|
||||
int acc;
|
||||
mrb_int argc;
|
||||
mrb_int acc;
|
||||
struct RClass *target_class;
|
||||
} mrb_callinfo;
|
||||
|
||||
@@ -160,22 +175,17 @@ struct mrb_context {
|
||||
mrb_callinfo *ci;
|
||||
mrb_callinfo *cibase, *ciend;
|
||||
|
||||
uint16_t *rescue; /* exception handler stack */
|
||||
uint16_t rsize;
|
||||
struct RProc **ensure; /* ensure handler stack */
|
||||
uint16_t esize, eidx;
|
||||
|
||||
enum mrb_fiber_state status : 4;
|
||||
mrb_bool vmexec : 1;
|
||||
struct RFiber *fib;
|
||||
};
|
||||
|
||||
#ifdef MRB_METHOD_CACHE_SIZE
|
||||
# define MRB_METHOD_CACHE
|
||||
# undef MRB_NO_METHOD_CACHE
|
||||
#else
|
||||
/* default method cache size: 128 */
|
||||
/* default method cache size: 256 */
|
||||
/* cache size needs to be power of 2 */
|
||||
# define MRB_METHOD_CACHE_SIZE (1<<7)
|
||||
# define MRB_METHOD_CACHE_SIZE (1<<8)
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -189,7 +199,7 @@ struct mrb_context {
|
||||
*/
|
||||
typedef mrb_value (*mrb_func_t)(struct mrb_state *mrb, mrb_value self);
|
||||
|
||||
#ifndef MRB_METHOD_T_STRUCT
|
||||
#ifndef MRB_USE_METHOD_T_STRUCT
|
||||
typedef uintptr_t mrb_method_t;
|
||||
#else
|
||||
typedef struct {
|
||||
@@ -201,7 +211,7 @@ typedef struct {
|
||||
} mrb_method_t;
|
||||
#endif
|
||||
|
||||
#ifdef MRB_METHOD_CACHE
|
||||
#ifndef MRB_NO_METHOD_CACHE
|
||||
struct mrb_cache_entry {
|
||||
struct RClass *c, *c0;
|
||||
mrb_sym mid;
|
||||
@@ -235,10 +245,10 @@ typedef struct mrb_state {
|
||||
struct RClass *hash_class;
|
||||
struct RClass *range_class;
|
||||
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
struct RClass *float_class;
|
||||
#endif
|
||||
struct RClass *fixnum_class;
|
||||
struct RClass *integer_class;
|
||||
struct RClass *true_class;
|
||||
struct RClass *false_class;
|
||||
struct RClass *nil_class;
|
||||
@@ -247,7 +257,7 @@ typedef struct mrb_state {
|
||||
|
||||
mrb_gc gc;
|
||||
|
||||
#ifdef MRB_METHOD_CACHE
|
||||
#ifndef MRB_NO_METHOD_CACHE
|
||||
struct mrb_cache_entry cache[MRB_METHOD_CACHE_SIZE];
|
||||
#endif
|
||||
|
||||
@@ -260,8 +270,8 @@ typedef struct mrb_state {
|
||||
#endif
|
||||
|
||||
#ifdef MRB_ENABLE_DEBUG_HOOK
|
||||
void (*code_fetch_hook)(struct mrb_state* mrb, struct mrb_irep *irep, const mrb_code *pc, mrb_value *regs);
|
||||
void (*debug_op_hook)(struct mrb_state* mrb, struct mrb_irep *irep, const mrb_code *pc, mrb_value *regs);
|
||||
void (*code_fetch_hook)(struct mrb_state* mrb, const struct mrb_irep *irep, const mrb_code *pc, mrb_value *regs);
|
||||
void (*debug_op_hook)(struct mrb_state* mrb, const struct mrb_irep *irep, const mrb_code *pc, mrb_value *regs);
|
||||
#endif
|
||||
|
||||
#ifdef MRB_BYTECODE_DECODE_OPTION
|
||||
@@ -284,7 +294,6 @@ typedef struct mrb_state {
|
||||
mrb_atexit_func *atexit_stack;
|
||||
#endif
|
||||
uint16_t atexit_stack_len;
|
||||
uint16_t ecall_nest; /* prevent infinite recursive ecall() */
|
||||
} mrb_state;
|
||||
|
||||
/**
|
||||
@@ -309,6 +318,7 @@ typedef struct mrb_state {
|
||||
* @see mrb_define_class_under
|
||||
*/
|
||||
MRB_API struct RClass *mrb_define_class(mrb_state *mrb, const char *name, struct RClass *super);
|
||||
MRB_API struct RClass *mrb_define_class_id(mrb_state *mrb, mrb_sym name, struct RClass *super);
|
||||
|
||||
/**
|
||||
* Defines a new module.
|
||||
@@ -318,6 +328,7 @@ MRB_API struct RClass *mrb_define_class(mrb_state *mrb, const char *name, struct
|
||||
* @return [struct RClass *] Reference to the newly defined module.
|
||||
*/
|
||||
MRB_API struct RClass *mrb_define_module(mrb_state *mrb, const char *name);
|
||||
MRB_API struct RClass *mrb_define_module_id(mrb_state *mrb, mrb_sym name);
|
||||
|
||||
MRB_API mrb_value mrb_singleton_class(mrb_state *mrb, mrb_value val);
|
||||
MRB_API struct RClass *mrb_singleton_class_ptr(mrb_state *mrb, mrb_value val);
|
||||
@@ -373,6 +384,7 @@ MRB_API void mrb_prepend_module(mrb_state *mrb, struct RClass *cla, struct RClas
|
||||
* @param aspec The method parameters declaration.
|
||||
*/
|
||||
MRB_API void mrb_define_method(mrb_state *mrb, struct RClass *cla, const char *name, mrb_func_t func, mrb_aspec aspec);
|
||||
MRB_API void mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, mrb_aspec aspec);
|
||||
|
||||
/**
|
||||
* Defines a class method.
|
||||
@@ -400,6 +412,7 @@ MRB_API void mrb_define_method(mrb_state *mrb, struct RClass *cla, const char *n
|
||||
* @param aspec The method parameters declaration.
|
||||
*/
|
||||
MRB_API void mrb_define_class_method(mrb_state *mrb, struct RClass *cla, const char *name, mrb_func_t fun, mrb_aspec aspec);
|
||||
MRB_API void mrb_define_class_method_id(mrb_state *mrb, struct RClass *cla, mrb_sym name, mrb_func_t fun, mrb_aspec aspec);
|
||||
|
||||
/**
|
||||
* Defines a singleton method
|
||||
@@ -407,6 +420,7 @@ MRB_API void mrb_define_class_method(mrb_state *mrb, struct RClass *cla, const c
|
||||
* @see mrb_define_class_method
|
||||
*/
|
||||
MRB_API void mrb_define_singleton_method(mrb_state *mrb, struct RObject *cla, const char *name, mrb_func_t fun, mrb_aspec aspec);
|
||||
MRB_API void mrb_define_singleton_method_id(mrb_state *mrb, struct RObject *cla, mrb_sym name, mrb_func_t fun, mrb_aspec aspec);
|
||||
|
||||
/**
|
||||
* Defines a module function.
|
||||
@@ -434,6 +448,7 @@ MRB_API void mrb_define_singleton_method(mrb_state *mrb, struct RObject *cla, co
|
||||
* @param aspec The method parameters declaration.
|
||||
*/
|
||||
MRB_API void mrb_define_module_function(mrb_state *mrb, struct RClass *cla, const char *name, mrb_func_t fun, mrb_aspec aspec);
|
||||
MRB_API void mrb_define_module_function_id(mrb_state *mrb, struct RClass *cla, mrb_sym name, mrb_func_t fun, mrb_aspec aspec);
|
||||
|
||||
/**
|
||||
* Defines a constant.
|
||||
@@ -462,6 +477,7 @@ MRB_API void mrb_define_module_function(mrb_state *mrb, struct RClass *cla, cons
|
||||
* @param val The value for the constant.
|
||||
*/
|
||||
MRB_API void mrb_define_const(mrb_state* mrb, struct RClass* cla, const char *name, mrb_value val);
|
||||
MRB_API void mrb_define_const_id(mrb_state* mrb, struct RClass* cla, mrb_sym name, mrb_value val);
|
||||
|
||||
/**
|
||||
* Undefines a method.
|
||||
@@ -552,6 +568,7 @@ MRB_API void mrb_undef_method_id(mrb_state*, struct RClass*, mrb_sym);
|
||||
* @param name The name of the class method to be undefined.
|
||||
*/
|
||||
MRB_API void mrb_undef_class_method(mrb_state *mrb, struct RClass *cls, const char *name);
|
||||
MRB_API void mrb_undef_class_method_id(mrb_state *mrb, struct RClass *cls, mrb_sym name);
|
||||
|
||||
/**
|
||||
* Initialize a new object instance of c class.
|
||||
@@ -653,6 +670,7 @@ MRB_API struct RClass * mrb_module_new(mrb_state *mrb);
|
||||
* @return [mrb_bool] A boolean value.
|
||||
*/
|
||||
MRB_API mrb_bool mrb_class_defined(mrb_state *mrb, const char *name);
|
||||
MRB_API mrb_bool mrb_class_defined_id(mrb_state *mrb, mrb_sym name);
|
||||
|
||||
/**
|
||||
* Gets a class.
|
||||
@@ -660,7 +678,8 @@ MRB_API mrb_bool mrb_class_defined(mrb_state *mrb, const char *name);
|
||||
* @param name The name of the class.
|
||||
* @return [struct RClass *] A reference to the class.
|
||||
*/
|
||||
MRB_API struct RClass * mrb_class_get(mrb_state *mrb, const char *name);
|
||||
MRB_API struct RClass* mrb_class_get(mrb_state *mrb, const char *name);
|
||||
MRB_API struct RClass* mrb_class_get_id(mrb_state *mrb, mrb_sym name);
|
||||
|
||||
/**
|
||||
* Gets a exception class.
|
||||
@@ -668,7 +687,8 @@ MRB_API struct RClass * mrb_class_get(mrb_state *mrb, const char *name);
|
||||
* @param name The name of the class.
|
||||
* @return [struct RClass *] A reference to the class.
|
||||
*/
|
||||
MRB_API struct RClass * mrb_exc_get(mrb_state *mrb, const char *name);
|
||||
MRB_API struct RClass* mrb_exc_get_id(mrb_state *mrb, mrb_sym name);
|
||||
#define mrb_exc_get(mrb, name) mrb_exc_get_id(mrb, mrb_intern_cstr(mrb, name))
|
||||
|
||||
/**
|
||||
* Returns an mrb_bool. True if inner class was defined, and false if the inner class was not defined.
|
||||
@@ -700,6 +720,7 @@ MRB_API struct RClass * mrb_exc_get(mrb_state *mrb, const char *name);
|
||||
* @return [mrb_bool] A boolean value.
|
||||
*/
|
||||
MRB_API mrb_bool mrb_class_defined_under(mrb_state *mrb, struct RClass *outer, const char *name);
|
||||
MRB_API mrb_bool mrb_class_defined_under_id(mrb_state *mrb, struct RClass *outer, mrb_sym name);
|
||||
|
||||
/**
|
||||
* Gets a child class.
|
||||
@@ -709,6 +730,7 @@ MRB_API mrb_bool mrb_class_defined_under(mrb_state *mrb, struct RClass *outer, c
|
||||
* @return [struct RClass *] A reference to the class.
|
||||
*/
|
||||
MRB_API struct RClass * mrb_class_get_under(mrb_state *mrb, struct RClass *outer, const char *name);
|
||||
MRB_API struct RClass * mrb_class_get_under_id(mrb_state *mrb, struct RClass *outer, mrb_sym name);
|
||||
|
||||
/**
|
||||
* Gets a module.
|
||||
@@ -717,6 +739,7 @@ MRB_API struct RClass * mrb_class_get_under(mrb_state *mrb, struct RClass *outer
|
||||
* @return [struct RClass *] A reference to the module.
|
||||
*/
|
||||
MRB_API struct RClass * mrb_module_get(mrb_state *mrb, const char *name);
|
||||
MRB_API struct RClass * mrb_module_get_id(mrb_state *mrb, mrb_sym name);
|
||||
|
||||
/**
|
||||
* Gets a module defined under another module.
|
||||
@@ -726,6 +749,8 @@ MRB_API struct RClass * mrb_module_get(mrb_state *mrb, const char *name);
|
||||
* @return [struct RClass *] A reference to the module.
|
||||
*/
|
||||
MRB_API struct RClass * mrb_module_get_under(mrb_state *mrb, struct RClass *outer, const char *name);
|
||||
MRB_API struct RClass * mrb_module_get_under_id(mrb_state *mrb, struct RClass *outer, mrb_sym name);
|
||||
|
||||
/* a function to raise NotImplementedError with current method name */
|
||||
MRB_API void mrb_notimplement(mrb_state*);
|
||||
/* a function to be replacement of unimplemented method */
|
||||
@@ -794,9 +819,11 @@ MRB_API mrb_bool mrb_obj_respond_to(mrb_state *mrb, struct RClass* c, mrb_sym mi
|
||||
* @return [struct RClass *] Reference to the newly defined class
|
||||
* @see mrb_define_class
|
||||
*/
|
||||
MRB_API struct RClass * mrb_define_class_under(mrb_state *mrb, struct RClass *outer, const char *name, struct RClass *super);
|
||||
MRB_API struct RClass* mrb_define_class_under(mrb_state *mrb, struct RClass *outer, const char *name, struct RClass *super);
|
||||
MRB_API struct RClass* mrb_define_class_under_id(mrb_state *mrb, struct RClass *outer, mrb_sym name, struct RClass *super);
|
||||
|
||||
MRB_API struct RClass * mrb_define_module_under(mrb_state *mrb, struct RClass *outer, const char *name);
|
||||
MRB_API struct RClass* mrb_define_module_under(mrb_state *mrb, struct RClass *outer, const char *name);
|
||||
MRB_API struct RClass* mrb_define_module_under_id(mrb_state *mrb, struct RClass *outer, mrb_sym name);
|
||||
|
||||
/**
|
||||
* Function requires n arguments.
|
||||
@@ -860,11 +887,11 @@ MRB_API struct RClass * mrb_define_module_under(mrb_state *mrb, struct RClass *o
|
||||
* | `S` | {String} | {mrb_value} | when `!` follows, the value may be `nil` |
|
||||
* | `A` | {Array} | {mrb_value} | when `!` follows, the value may be `nil` |
|
||||
* | `H` | {Hash} | {mrb_value} | when `!` follows, the value may be `nil` |
|
||||
* | `s` | {String} | char *, {mrb_int} | Receive two arguments; `s!` gives (`NULL`,`0`) for `nil` |
|
||||
* | `z` | {String} | char * | `NULL` terminated string; `z!` gives `NULL` for `nil` |
|
||||
* | `s` | {String} | const char *, {mrb_int} | Receive two arguments; `s!` gives (`NULL`,`0`) for `nil` |
|
||||
* | `z` | {String} | const char * | `NULL` terminated string; `z!` gives `NULL` for `nil` |
|
||||
* | `a` | {Array} | {mrb_value} *, {mrb_int} | Receive two arguments; `a!` gives (`NULL`,`0`) for `nil` |
|
||||
* | `f` | {Fixnum}/{Float} | {mrb_float} | |
|
||||
* | `i` | {Fixnum}/{Float} | {mrb_int} | |
|
||||
* | `f` | {Integer}/{Float} | {mrb_float} | |
|
||||
* | `i` | {Integer}/{Float} | {mrb_int} | |
|
||||
* | `b` | boolean | {mrb_bool} | |
|
||||
* | `n` | {String}/{Symbol} | {mrb_sym} | |
|
||||
* | `d` | data | void *, {mrb_data_type} const | 2nd argument will be used to check data type so it won't be modified; when `!` follows, the value may be `nil` |
|
||||
@@ -902,7 +929,7 @@ typedef const char *mrb_args_format;
|
||||
* const char *kw_names[kw_num] = { "a", "b" };
|
||||
* uint32_t kw_required = 0;
|
||||
* mrb_value kw_values[kw_num];
|
||||
* const mrb_kwargs kwargs = { kw_num, kw_values, kw_names, kw_required, NULL };
|
||||
* const mrb_kwargs kwargs = { kw_num, kw_required, kw_names, kw_values, NULL };
|
||||
*
|
||||
* mrb_get_args(mrb, ":", &kwargs);
|
||||
* if (mrb_undef_p(kw_values[0])) { kw_values[0] = mrb_fixnum_value(1); }
|
||||
@@ -913,10 +940,10 @@ typedef const char *mrb_args_format;
|
||||
*
|
||||
* mrb_value str, kw_rest;
|
||||
* uint32_t kw_num = 3;
|
||||
* const char *kw_names[kw_num] = { "x", "y", "z" };
|
||||
* const mrb_sym kw_names[kw_num] = { MRB_SYM(x), MRB_SYM(y), MRB_SYM(z) };
|
||||
* uint32_t kw_required = 1;
|
||||
* mrb_value kw_values[kw_num];
|
||||
* const mrb_kwargs kwargs = { kw_num, kw_values, kw_names, kw_required, &kw_rest };
|
||||
* const mrb_kwargs kwargs = { kw_num, kw_required, kw_names, kw_values, &kw_rest };
|
||||
*
|
||||
* mrb_get_args(mrb, "S:", &str, &kwargs);
|
||||
* // or: mrb_get_args(mrb, ":S", &kwargs, &str);
|
||||
@@ -927,11 +954,11 @@ typedef struct mrb_kwargs mrb_kwargs;
|
||||
|
||||
struct mrb_kwargs
|
||||
{
|
||||
uint32_t num;
|
||||
mrb_value *values;
|
||||
const char *const *table;
|
||||
uint32_t required;
|
||||
mrb_value *rest;
|
||||
uint32_t num; /* number of keyword arguments */
|
||||
uint32_t required; /* number of required keyword arguments */
|
||||
const mrb_sym *table; /* C array of symbols for keyword names */
|
||||
mrb_value *values; /* keyword argument values */
|
||||
mrb_value *rest; /* keyword rest (dict) */
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1001,6 +1028,7 @@ MRB_API mrb_value mrb_get_arg1(mrb_state *mrb);
|
||||
* FILE *fp = fopen("test.rb","r");
|
||||
* mrb_value obj = mrb_load_file(mrb,fp);
|
||||
* mrb_funcall(mrb, obj, "method_name", 1, mrb_fixnum_value(i));
|
||||
* mrb_funcall_id(mrb, obj, MRB_SYM(method_name), 1, mrb_fixnum_value(i));
|
||||
* fclose(fp);
|
||||
* mrb_close(mrb);
|
||||
* }
|
||||
@@ -1013,6 +1041,7 @@ MRB_API mrb_value mrb_get_arg1(mrb_state *mrb);
|
||||
* @return [mrb_value] mruby function value.
|
||||
*/
|
||||
MRB_API mrb_value mrb_funcall(mrb_state *mrb, mrb_value val, const char *name, mrb_int argc, ...);
|
||||
MRB_API mrb_value mrb_funcall_id(mrb_state *mrb, mrb_value val, mrb_sym mid, mrb_int argc, ...);
|
||||
/**
|
||||
* Call existing ruby functions. This is basically the type safe version of mrb_funcall.
|
||||
*
|
||||
@@ -1022,15 +1051,14 @@ MRB_API mrb_value mrb_funcall(mrb_state *mrb, mrb_value val, const char *name, m
|
||||
* int
|
||||
* main()
|
||||
* {
|
||||
* mrb_int i = 99;
|
||||
* mrb_state *mrb = mrb_open();
|
||||
* mrb_value obj = mrb_fixnum_value(1);
|
||||
*
|
||||
* if (!mrb) { }
|
||||
* mrb_sym m_sym = mrb_intern_lit(mrb, "method_name"); // Symbol for method.
|
||||
*
|
||||
* FILE *fp = fopen("test.rb","r");
|
||||
* mrb_value obj = mrb_load_file(mrb,fp);
|
||||
* mrb_funcall_argv(mrb, obj, m_sym, 1, &obj); // Calling ruby function from test.rb.
|
||||
* mrb_funcall_argv(mrb, obj, MRB_SYM(method_name), 1, &obj); // Calling ruby function from test.rb.
|
||||
* fclose(fp);
|
||||
* mrb_close(mrb);
|
||||
* }
|
||||
@@ -1048,7 +1076,7 @@ MRB_API mrb_value mrb_funcall_argv(mrb_state *mrb, mrb_value val, mrb_sym name,
|
||||
*/
|
||||
MRB_API mrb_value mrb_funcall_with_block(mrb_state *mrb, mrb_value val, mrb_sym name, mrb_int argc, const mrb_value *argv, mrb_value block);
|
||||
/**
|
||||
* Create a symbol
|
||||
* Create a symbol from C string. But usually it's better to use MRB_SYM(sym) and MRB_QSYM(qsym).
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
@@ -1056,7 +1084,9 @@ MRB_API mrb_value mrb_funcall_with_block(mrb_state *mrb, mrb_value val, mrb_sym
|
||||
* :pizza # => :pizza
|
||||
*
|
||||
* // C style:
|
||||
* mrb_sym m_sym = mrb_intern_lit(mrb, "pizza"); // => :pizza
|
||||
* mrb_sym sym1 = mrb_intern_lit(mrb, "pizza"); // => :pizza
|
||||
* mrb_sym sym2 = MRB_SYM(pizza); // => :pizza
|
||||
* mrb_sym sym3 = MRB_SYM(pizza_p); // => :pizza?
|
||||
*
|
||||
* @param mrb The current mruby state.
|
||||
* @param str The string to be symbolized
|
||||
@@ -1065,8 +1095,14 @@ MRB_API mrb_value mrb_funcall_with_block(mrb_state *mrb, mrb_value val, mrb_sym
|
||||
MRB_API mrb_sym mrb_intern_cstr(mrb_state *mrb, const char* str);
|
||||
MRB_API mrb_sym mrb_intern(mrb_state*,const char*,size_t);
|
||||
MRB_API mrb_sym mrb_intern_static(mrb_state*,const char*,size_t);
|
||||
#define mrb_intern_lit(mrb, lit) mrb_intern_static(mrb, lit, mrb_strlen_lit(lit))
|
||||
#define mrb_intern_lit(mrb, lit) mrb_intern_static(mrb, (lit ""), mrb_strlen_lit(lit))
|
||||
MRB_API mrb_sym mrb_intern_str(mrb_state*,mrb_value);
|
||||
/* mrb_intern_check series functions returns 0 if the symbol is not defined */
|
||||
MRB_API mrb_sym mrb_intern_check_cstr(mrb_state*,const char*);
|
||||
MRB_API mrb_sym mrb_intern_check(mrb_state*,const char*,size_t);
|
||||
MRB_API mrb_sym mrb_intern_check_str(mrb_state*,mrb_value);
|
||||
/* mrb_check_intern series functions returns nil if the symbol is not defined */
|
||||
/* otherwise returns mrb_value */
|
||||
MRB_API mrb_value mrb_check_intern_cstr(mrb_state*,const char*);
|
||||
MRB_API mrb_value mrb_check_intern(mrb_state*,const char*,size_t);
|
||||
MRB_API mrb_value mrb_check_intern_str(mrb_state*,mrb_value);
|
||||
@@ -1164,9 +1200,9 @@ MRB_API void mrb_close(mrb_state *mrb);
|
||||
MRB_API void* mrb_default_allocf(mrb_state*, void*, size_t, void*);
|
||||
|
||||
MRB_API mrb_value mrb_top_self(mrb_state *mrb);
|
||||
MRB_API mrb_value mrb_top_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep);
|
||||
MRB_API mrb_value mrb_vm_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep);
|
||||
MRB_API mrb_value mrb_vm_exec(mrb_state *mrb, struct RProc *proc, const mrb_code *iseq);
|
||||
MRB_API mrb_value mrb_top_run(mrb_state *mrb, const struct RProc *proc, mrb_value self, mrb_int stack_keep);
|
||||
MRB_API mrb_value mrb_vm_run(mrb_state *mrb, const struct RProc *proc, mrb_value self, mrb_int stack_keep);
|
||||
MRB_API mrb_value mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *iseq);
|
||||
/* compatibility macros */
|
||||
#define mrb_toplevel_run_keep(m,p,k) mrb_top_run((m),(p),mrb_top_self(m),(k))
|
||||
#define mrb_toplevel_run(m,p) mrb_toplevel_run_keep((m),(p),0)
|
||||
@@ -1181,7 +1217,7 @@ MRB_API mrb_bool mrb_obj_equal(mrb_state *mrb, mrb_value a, mrb_value b);
|
||||
MRB_API mrb_bool mrb_equal(mrb_state *mrb, mrb_value obj1, mrb_value obj2);
|
||||
MRB_API mrb_value mrb_convert_to_integer(mrb_state *mrb, mrb_value val, mrb_int base);
|
||||
MRB_API mrb_value mrb_Integer(mrb_state *mrb, mrb_value val);
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
MRB_API mrb_value mrb_Float(mrb_state *mrb, mrb_value val);
|
||||
#endif
|
||||
MRB_API mrb_value mrb_inspect(mrb_state *mrb, mrb_value obj);
|
||||
@@ -1214,12 +1250,15 @@ MRB_API void mrb_field_write_barrier(mrb_state *, struct RBasic*, struct RBasic*
|
||||
} while (0)
|
||||
MRB_API void mrb_write_barrier(mrb_state *, struct RBasic*);
|
||||
|
||||
MRB_API mrb_value mrb_check_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const char *tname, const char *method);
|
||||
MRB_API mrb_value mrb_type_convert(mrb_state *mrb, mrb_value val, enum mrb_vtype type, mrb_sym method);
|
||||
#define mrb_convert_type(mrb, val, type, tname, method) mrb_type_convert(mrb, val, type, mrb_intern_lit(mrb, method))
|
||||
MRB_API mrb_value mrb_type_convert_check(mrb_state *mrb, mrb_value val, enum mrb_vtype type, mrb_sym method);
|
||||
#define mrb_check_convert_type(mrb, val, type, tname, method) mrb_type_convert_check(mrb, val, type, mrb_intern_lit(mrb, method))
|
||||
|
||||
MRB_API mrb_value mrb_any_to_s(mrb_state *mrb, mrb_value obj);
|
||||
MRB_API const char * mrb_obj_classname(mrb_state *mrb, mrb_value obj);
|
||||
MRB_API struct RClass* mrb_obj_class(mrb_state *mrb, mrb_value obj);
|
||||
MRB_API mrb_value mrb_class_path(mrb_state *mrb, struct RClass *c);
|
||||
MRB_API mrb_value mrb_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const char *tname, const char *method);
|
||||
MRB_API mrb_bool mrb_obj_is_kind_of(mrb_state *mrb, mrb_value obj, struct RClass *c);
|
||||
MRB_API mrb_value mrb_obj_inspect(mrb_state *mrb, mrb_value self);
|
||||
MRB_API mrb_value mrb_obj_clone(mrb_state *mrb, mrb_value self);
|
||||
@@ -1260,25 +1299,26 @@ MRB_API mrb_value mrb_vformat(mrb_state *mrb, const char *format, va_list ap);
|
||||
+ those E_* macros requires mrb_state* variable named mrb.
|
||||
+ exception objects obtained from those macros are local to mrb
|
||||
*/
|
||||
#define E_RUNTIME_ERROR (mrb_exc_get(mrb, "RuntimeError"))
|
||||
#define E_TYPE_ERROR (mrb_exc_get(mrb, "TypeError"))
|
||||
#define E_ARGUMENT_ERROR (mrb_exc_get(mrb, "ArgumentError"))
|
||||
#define E_INDEX_ERROR (mrb_exc_get(mrb, "IndexError"))
|
||||
#define E_RANGE_ERROR (mrb_exc_get(mrb, "RangeError"))
|
||||
#define E_NAME_ERROR (mrb_exc_get(mrb, "NameError"))
|
||||
#define E_NOMETHOD_ERROR (mrb_exc_get(mrb, "NoMethodError"))
|
||||
#define E_SCRIPT_ERROR (mrb_exc_get(mrb, "ScriptError"))
|
||||
#define E_SYNTAX_ERROR (mrb_exc_get(mrb, "SyntaxError"))
|
||||
#define E_LOCALJUMP_ERROR (mrb_exc_get(mrb, "LocalJumpError"))
|
||||
#define E_REGEXP_ERROR (mrb_exc_get(mrb, "RegexpError"))
|
||||
#define E_FROZEN_ERROR (mrb_exc_get(mrb, "FrozenError"))
|
||||
#define E_RUNTIME_ERROR (mrb_exc_get_id(mrb, MRB_SYM(RuntimeError)))
|
||||
#define E_TYPE_ERROR (mrb_exc_get_id(mrb, MRB_SYM(TypeError)))
|
||||
#define E_ZERODIV_ERROR (mrb_exc_get_id(mrb, MRB_SYM(ZeroDivisionError)))
|
||||
#define E_ARGUMENT_ERROR (mrb_exc_get_id(mrb, MRB_SYM(ArgumentError)))
|
||||
#define E_INDEX_ERROR (mrb_exc_get_id(mrb, MRB_SYM(IndexError)))
|
||||
#define E_RANGE_ERROR (mrb_exc_get_id(mrb, MRB_SYM(RangeError)))
|
||||
#define E_NAME_ERROR (mrb_exc_get_id(mrb, MRB_SYM(NameError)))
|
||||
#define E_NOMETHOD_ERROR (mrb_exc_get_id(mrb, MRB_SYM(NoMethodError)))
|
||||
#define E_SCRIPT_ERROR (mrb_exc_get_id(mrb, MRB_SYM(ScriptError)))
|
||||
#define E_SYNTAX_ERROR (mrb_exc_get_id(mrb, MRB_SYM(SyntaxError)))
|
||||
#define E_LOCALJUMP_ERROR (mrb_exc_get_id(mrb, MRB_SYM(LocalJumpError)))
|
||||
#define E_REGEXP_ERROR (mrb_exc_get_id(mrb, MRB_SYM(RegexpError)))
|
||||
#define E_FROZEN_ERROR (mrb_exc_get_id(mrb, MRB_SYM(FrozenError)))
|
||||
|
||||
#define E_NOTIMP_ERROR (mrb_exc_get(mrb, "NotImplementedError"))
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#define E_FLOATDOMAIN_ERROR (mrb_exc_get(mrb, "FloatDomainError"))
|
||||
#define E_NOTIMP_ERROR (mrb_exc_get_id(mrb, MRB_SYM(NotImplementedError)))
|
||||
#ifndef MRB_NO_FLOAT
|
||||
#define E_FLOATDOMAIN_ERROR (mrb_exc_get_id(mrb, MRB_SYM(FloatDomainError)))
|
||||
#endif
|
||||
|
||||
#define E_KEY_ERROR (mrb_exc_get(mrb, "KeyError"))
|
||||
#define E_KEY_ERROR (mrb_exc_get_id(mrb, MRB_SYM(KeyError)))
|
||||
|
||||
MRB_API mrb_value mrb_yield(mrb_state *mrb, mrb_value b, mrb_value arg);
|
||||
MRB_API mrb_value mrb_yield_argv(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value *argv);
|
||||
@@ -1297,7 +1337,7 @@ MRB_API void mrb_gc_register(mrb_state *mrb, mrb_value obj);
|
||||
MRB_API void mrb_gc_unregister(mrb_state *mrb, mrb_value obj);
|
||||
|
||||
MRB_API mrb_value mrb_to_int(mrb_state *mrb, mrb_value val);
|
||||
#define mrb_int(mrb, val) mrb_fixnum(mrb_to_int(mrb, val))
|
||||
#define mrb_int(mrb, val) mrb_integer(mrb_to_int(mrb, val))
|
||||
/* string type checking (contrary to the name, it doesn't convert) */
|
||||
MRB_API mrb_value mrb_to_str(mrb_state *mrb, mrb_value val);
|
||||
MRB_API void mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t);
|
||||
@@ -1307,14 +1347,8 @@ MRB_INLINE void mrb_check_frozen(mrb_state *mrb, void *o)
|
||||
if (mrb_frozen_p((struct RBasic*)o)) mrb_frozen_error(mrb, o);
|
||||
}
|
||||
|
||||
typedef enum call_type {
|
||||
CALL_PUBLIC,
|
||||
CALL_FCALL,
|
||||
CALL_VCALL,
|
||||
CALL_TYPE_MAX
|
||||
} call_type;
|
||||
|
||||
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);
|
||||
MRB_API void mrb_define_global_const(mrb_state *mrb, const char *name, mrb_value val);
|
||||
|
||||
@@ -1351,7 +1385,7 @@ MRB_API mrb_value mrb_fiber_alive_p(mrb_state *mrb, mrb_value fib);
|
||||
*
|
||||
* Implemented in mruby-fiber
|
||||
*/
|
||||
#define E_FIBER_ERROR (mrb_exc_get(mrb, "FiberError"))
|
||||
#define E_FIBER_ERROR (mrb_exc_get_id(mrb, MRB_SYM(FiberError)))
|
||||
MRB_API void mrb_stack_extend(mrb_state*, mrb_int);
|
||||
|
||||
/* memory pool implementation */
|
||||
|
||||
+21
-4
@@ -21,7 +21,14 @@ typedef struct mrb_shared_array {
|
||||
mrb_value *ptr;
|
||||
} mrb_shared_array;
|
||||
|
||||
#define MRB_ARY_EMBED_LEN_MAX ((mrb_int)(sizeof(void*)*3/sizeof(mrb_value)))
|
||||
#if defined(MRB_32BIT) && defined(MRB_NO_BOXING)
|
||||
# define MRB_ARY_NO_EMBED
|
||||
# define MRB_ARY_EMBED_LEN_MAX 0
|
||||
#else
|
||||
# define MRB_ARY_EMBED_LEN_MAX ((mrb_int)(sizeof(void*)*3/sizeof(mrb_value)))
|
||||
mrb_static_assert(MRB_ARY_EMBED_LEN_MAX > 0, "MRB_ARY_EMBED_LEN_MAX > 0");
|
||||
#endif
|
||||
|
||||
struct RArray {
|
||||
MRB_OBJECT_HEADER;
|
||||
union {
|
||||
@@ -33,7 +40,9 @@ struct RArray {
|
||||
} aux;
|
||||
mrb_value *ptr;
|
||||
} heap;
|
||||
void *ary[3];
|
||||
#ifndef MRB_ARY_NO_EMBED
|
||||
mrb_value ary[MRB_ARY_EMBED_LEN_MAX];
|
||||
#endif
|
||||
} as;
|
||||
};
|
||||
|
||||
@@ -41,13 +50,21 @@ struct RArray {
|
||||
#define mrb_ary_value(p) mrb_obj_value((void*)(p))
|
||||
#define RARRAY(v) ((struct RArray*)(mrb_ptr(v)))
|
||||
|
||||
#ifdef MRB_ARY_NO_EMBED
|
||||
#define ARY_EMBED_P(a) 0
|
||||
#define ARY_UNSET_EMBED_FLAG(a) (void)0
|
||||
#define ARY_EMBED_LEN(a) 0
|
||||
#define ARY_SET_EMBED_LEN(a,len) (void)0
|
||||
#define ARY_EMBED_PTR(a) 0
|
||||
#else
|
||||
#define MRB_ARY_EMBED_MASK 7
|
||||
#define ARY_EMBED_P(a) ((a)->flags & MRB_ARY_EMBED_MASK)
|
||||
#define ARY_UNSET_EMBED_FLAG(a) ((a)->flags &= ~(MRB_ARY_EMBED_MASK))
|
||||
#define ARY_EMBED_LEN(a) ((mrb_int)(((a)->flags & MRB_ARY_EMBED_MASK) - 1))
|
||||
#define ARY_SET_EMBED_LEN(a,len) ((a)->flags = ((a)->flags&~MRB_ARY_EMBED_MASK) | ((uint32_t)(len) + 1))
|
||||
#define ARY_EMBED_PTR(a) ((mrb_value*)(&(a)->as.ary))
|
||||
|
||||
#define ARY_EMBED_PTR(a) ((a)->as.ary)
|
||||
#endif
|
||||
|
||||
#define ARY_LEN(a) (ARY_EMBED_P(a)?ARY_EMBED_LEN(a):(a)->as.heap.len)
|
||||
#define ARY_PTR(a) (ARY_EMBED_P(a)?ARY_EMBED_PTR(a):(a)->as.heap.ptr)
|
||||
#define RARRAY_LEN(a) ARY_LEN(RARRAY(a))
|
||||
|
||||
+63
-48
@@ -7,12 +7,12 @@
|
||||
#ifndef MRUBY_BOXING_NAN_H
|
||||
#define MRUBY_BOXING_NAN_H
|
||||
|
||||
#ifdef MRB_USE_FLOAT
|
||||
# error ---->> MRB_NAN_BOXING and MRB_USE_FLOAT conflict <<----
|
||||
#ifdef MRB_USE_FLOAT32
|
||||
# error ---->> MRB_NAN_BOXING and MRB_USE_FLOAT32 conflict <<----
|
||||
#endif
|
||||
|
||||
#ifdef MRB_WITHOUT_FLOAT
|
||||
# error ---->> MRB_NAN_BOXING and MRB_WITHOUT_FLOAT conflict <<----
|
||||
#ifdef MRB_NO_FLOAT
|
||||
# error ---->> MRB_NAN_BOXING and MRB_NO_FLOAT conflict <<----
|
||||
#endif
|
||||
|
||||
#ifdef MRB_INT64
|
||||
@@ -30,76 +30,91 @@
|
||||
* In order to get enough bit size to save TT, all pointers are shifted 2 bits
|
||||
* in the right direction. Also, TTTTTT is the mrb_vtype + 1;
|
||||
*/
|
||||
typedef struct mrb_value {
|
||||
union {
|
||||
mrb_float f;
|
||||
union {
|
||||
void *p;
|
||||
struct {
|
||||
MRB_ENDIAN_LOHI(
|
||||
uint32_t ttt;
|
||||
,union {
|
||||
mrb_int i;
|
||||
mrb_sym sym;
|
||||
};
|
||||
)
|
||||
};
|
||||
typedef uint64_t mrb_value;
|
||||
|
||||
union mrb_value_ {
|
||||
mrb_float f;
|
||||
uint64_t u;
|
||||
#ifdef MRB_64BIT
|
||||
struct RCptr *vp;
|
||||
void *p;
|
||||
#endif
|
||||
} value;
|
||||
struct {
|
||||
MRB_ENDIAN_LOHI(
|
||||
uint32_t ttt;
|
||||
,uint32_t i;
|
||||
)
|
||||
};
|
||||
} mrb_value;
|
||||
};
|
||||
|
||||
#define mrb_float_pool(mrb,f) mrb_float_value(mrb,f)
|
||||
static inline union mrb_value_
|
||||
mrb_val_union(mrb_value v)
|
||||
{
|
||||
union mrb_value_ x;
|
||||
x.u = v;
|
||||
return x;
|
||||
}
|
||||
|
||||
#define mrb_tt(o) ((enum mrb_vtype)(((o).value.ttt & 0xfc000)>>14)-1)
|
||||
#define mrb_type(o) (enum mrb_vtype)((uint32_t)0xfff00000 < (o).value.ttt ? mrb_tt(o) : MRB_TT_FLOAT)
|
||||
#define mrb_ptr(o) ((void*)((((uintptr_t)0x3fffffffffff)&((uintptr_t)((o).value.p)))<<2))
|
||||
#define mrb_float(o) (o).f
|
||||
#define mrb_fixnum(o) (o).value.i
|
||||
#define mrb_symbol(o) (o).value.sym
|
||||
#define mrb_tt(o) ((enum mrb_vtype)((mrb_val_union(o).ttt & 0xfc000)>>14)-1)
|
||||
#define mrb_type(o) (enum mrb_vtype)((uint32_t)0xfff00000 < mrb_val_union(o).ttt ? mrb_tt(o) : MRB_TT_FLOAT)
|
||||
#define mrb_float(o) mrb_val_union(o).f
|
||||
#define mrb_fixnum(o) ((mrb_int)mrb_val_union(o).i)
|
||||
#define mrb_integer(o) mrb_fixnum(o)
|
||||
#define mrb_symbol(o) ((mrb_sym)mrb_val_union(o).i)
|
||||
|
||||
#ifdef MRB_64BIT
|
||||
MRB_API mrb_value mrb_nan_boxing_cptr_value(struct mrb_state*, void*);
|
||||
#define mrb_ptr(o) ((void*)((((uintptr_t)0x3fffffffffff)&((uintptr_t)(mrb_val_union(o).p)))<<2))
|
||||
#define mrb_cptr(o) (((struct RCptr*)mrb_ptr(o))->p)
|
||||
#define BOXNAN_SHIFT_LONG_POINTER(v) (((uintptr_t)(v)>>34)&0x3fff)
|
||||
#else
|
||||
#define mrb_cptr(o) ((o).value.p)
|
||||
#define mrb_ptr(o) ((void*)mrb_val_union(o).i)
|
||||
#define mrb_cptr(o) mrb_ptr(o)
|
||||
#define BOXNAN_SHIFT_LONG_POINTER(v) 0
|
||||
#endif
|
||||
|
||||
#define BOXNAN_SET_VALUE(o, tt, attr, v) do {\
|
||||
(o).attr = (v);\
|
||||
(o).value.ttt = 0xfff00000 | (((tt)+1)<<14);\
|
||||
#define BOXNAN_SET_VALUE(o, tt, attr, v) do { \
|
||||
union mrb_value_ mrb_value_union_variable; \
|
||||
mrb_value_union_variable.attr = (v);\
|
||||
mrb_value_union_variable.ttt = 0xfff00000 | (((tt)+1)<<14);\
|
||||
o = mrb_value_union_variable.u;\
|
||||
} while (0)
|
||||
|
||||
#ifdef MRB_64BIT
|
||||
#define BOXNAN_SET_OBJ_VALUE(o, tt, v) do {\
|
||||
(o).value.p = (void*)((uintptr_t)(v)>>2);\
|
||||
(o).value.ttt = (0xfff00000|(((tt)+1)<<14)|BOXNAN_SHIFT_LONG_POINTER(v));\
|
||||
union mrb_value_ mrb_value_union_variable;\
|
||||
mrb_value_union_variable.p = (void*)((uintptr_t)(v)>>2);\
|
||||
mrb_value_union_variable.ttt = (0xfff00000|(((tt)+1)<<14)|BOXNAN_SHIFT_LONG_POINTER(v));\
|
||||
o = mrb_value_union_variable.u;\
|
||||
} while (0)
|
||||
#else
|
||||
#define BOXNAN_SET_OBJ_VALUE(o, tt, v) BOXNAN_SET_VALUE(o, tt, i, (uint32_t)v)
|
||||
#endif
|
||||
|
||||
#define SET_FLOAT_VALUE(mrb,r,v) do { \
|
||||
if ((v) != (v)) { \
|
||||
(r).value.ttt = 0x7ff80000; \
|
||||
(r).value.i = 0; \
|
||||
union mrb_value_ mrb_value_union_variable; \
|
||||
if ((v) != (v)) { /* NaN */ \
|
||||
mrb_value_union_variable.ttt = 0x7ff80000; \
|
||||
mrb_value_union_variable.i = 0; \
|
||||
} \
|
||||
else { \
|
||||
(r).f = v; \
|
||||
}} while(0)
|
||||
mrb_value_union_variable.f = (v); \
|
||||
} \
|
||||
r = mrb_value_union_variable.u; \
|
||||
} while(0)
|
||||
|
||||
#define SET_NIL_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_FALSE, value.i, 0)
|
||||
#define SET_FALSE_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_FALSE, value.i, 1)
|
||||
#define SET_TRUE_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_TRUE, value.i, 1)
|
||||
#define SET_BOOL_VALUE(r,b) BOXNAN_SET_VALUE(r, b ? MRB_TT_TRUE : MRB_TT_FALSE, value.i, 1)
|
||||
#define SET_INT_VALUE(r,n) BOXNAN_SET_VALUE(r, MRB_TT_FIXNUM, value.i, (n))
|
||||
#define SET_SYM_VALUE(r,v) BOXNAN_SET_VALUE(r, MRB_TT_SYMBOL, value.sym, (v))
|
||||
#define SET_NIL_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_FALSE, i, 0)
|
||||
#define SET_FALSE_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_FALSE, i, 1)
|
||||
#define SET_TRUE_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_TRUE, i, 1)
|
||||
#define SET_BOOL_VALUE(r,b) BOXNAN_SET_VALUE(r, b ? MRB_TT_TRUE : MRB_TT_FALSE, i, 1)
|
||||
#define SET_INT_VALUE(mrb, r,n) BOXNAN_SET_VALUE(r, MRB_TT_INTEGER, i, (uint32_t)(n))
|
||||
#define SET_FIXNUM_VALUE(r,n) BOXNAN_SET_VALUE(r, MRB_TT_INTEGER, i, (uint32_t)(n))
|
||||
#define SET_SYM_VALUE(r,v) BOXNAN_SET_VALUE(r, MRB_TT_SYMBOL, i, (uint32_t)(v))
|
||||
#define SET_OBJ_VALUE(r,v) BOXNAN_SET_OBJ_VALUE(r, (((struct RObject*)(v))->tt), (v))
|
||||
#ifdef MRB_64BIT
|
||||
MRB_API mrb_value mrb_nan_boxing_cptr_value(struct mrb_state*, void*);
|
||||
#define SET_CPTR_VALUE(mrb,r,v) ((r) = mrb_nan_boxing_cptr_value(mrb, v))
|
||||
#else
|
||||
#define SET_CPTR_VALUE(mrb,r,v) BOXNAN_SET_VALUE(r, MRB_TT_CPTR, value.p, v)
|
||||
#define SET_CPTR_VALUE(mrb,r,v) BOXNAN_SET_VALUE(r, MRB_TT_CPTR, p, v)
|
||||
#endif
|
||||
#define SET_UNDEF_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_UNDEF, value.i, 0)
|
||||
#define SET_UNDEF_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_UNDEF, i, 0)
|
||||
|
||||
#endif /* MRUBY_BOXING_NAN_H */
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#define MRB_SYMBOL_SHIFT 0
|
||||
|
||||
union mrb_value_union {
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
mrb_float f;
|
||||
#endif
|
||||
void *p;
|
||||
@@ -24,16 +24,13 @@ typedef struct mrb_value {
|
||||
enum mrb_vtype tt;
|
||||
} mrb_value;
|
||||
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#define mrb_float_pool(mrb,f) mrb_float_value(mrb,f)
|
||||
#endif
|
||||
|
||||
#define mrb_ptr(o) (o).value.p
|
||||
#define mrb_cptr(o) mrb_ptr(o)
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
#define mrb_float(o) (o).value.f
|
||||
#endif
|
||||
#define mrb_fixnum(o) (o).value.i
|
||||
#define mrb_integer(o) mrb_fixnum(o)
|
||||
#define mrb_symbol(o) (o).value.sym
|
||||
#define mrb_type(o) (o).tt
|
||||
|
||||
@@ -46,8 +43,9 @@ typedef struct mrb_value {
|
||||
#define SET_FALSE_VALUE(r) BOXNIX_SET_VALUE(r, MRB_TT_FALSE, value.i, 1)
|
||||
#define SET_TRUE_VALUE(r) BOXNIX_SET_VALUE(r, MRB_TT_TRUE, value.i, 1)
|
||||
#define SET_BOOL_VALUE(r,b) BOXNIX_SET_VALUE(r, b ? MRB_TT_TRUE : MRB_TT_FALSE, value.i, 1)
|
||||
#define SET_INT_VALUE(r,n) BOXNIX_SET_VALUE(r, MRB_TT_FIXNUM, value.i, (n))
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#define SET_INT_VALUE(mrb,r,n) BOXNIX_SET_VALUE(r, MRB_TT_INTEGER, value.i, (n))
|
||||
#define SET_FIXNUM_VALUE(r,n) BOXNIX_SET_VALUE(r, MRB_TT_INTEGER, value.i, (n))
|
||||
#ifndef MRB_NO_FLOAT
|
||||
#define SET_FLOAT_VALUE(mrb,r,v) BOXNIX_SET_VALUE(r, MRB_TT_FLOAT, value.f, (v))
|
||||
#endif
|
||||
#define SET_SYM_VALUE(r,v) BOXNIX_SET_VALUE(r, MRB_TT_SYMBOL, value.sym, (v))
|
||||
|
||||
+73
-50
@@ -11,13 +11,18 @@
|
||||
#error MRB_INT64 cannot be used with MRB_WORD_BOXING in 32-bit mode.
|
||||
#endif
|
||||
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
struct RFloat {
|
||||
MRB_OBJECT_HEADER;
|
||||
mrb_float f;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct RInteger {
|
||||
MRB_OBJECT_HEADER;
|
||||
mrb_int i;
|
||||
};
|
||||
|
||||
enum mrb_special_consts {
|
||||
MRB_Qnil = 0,
|
||||
MRB_Qfalse = 4,
|
||||
@@ -47,13 +52,13 @@ enum mrb_special_consts {
|
||||
#define BOXWORD_IMMEDIATE_MASK 0x07
|
||||
|
||||
#define BOXWORD_SHIFT_VALUE(o,n,t) \
|
||||
(t)(((long)(o).w) >> BOXWORD_##n##_SHIFT)
|
||||
(t)(((intptr_t)(o)) >> BOXWORD_##n##_SHIFT)
|
||||
#define BOXWORD_SET_SHIFT_VALUE(o,n,v) \
|
||||
((o).w = (((unsigned long)(v)) << BOXWORD_##n##_SHIFT) | BOXWORD_##n##_FLAG)
|
||||
((o) = (((uintptr_t)(v)) << BOXWORD_##n##_SHIFT) | BOXWORD_##n##_FLAG)
|
||||
#define BOXWORD_SHIFT_VALUE_P(o,n) \
|
||||
(((o).w & BOXWORD_##n##_MASK) == BOXWORD_##n##_FLAG)
|
||||
(((o) & BOXWORD_##n##_MASK) == BOXWORD_##n##_FLAG)
|
||||
#define BOXWORD_OBJ_TYPE_P(o,n) \
|
||||
(!mrb_immediate_p(o) && (o).value.bp->tt == MRB_TT_##n)
|
||||
(!mrb_immediate_p(o) && mrb_val_union(o).bp->tt == MRB_TT_##n)
|
||||
|
||||
/*
|
||||
* mrb_value representation:
|
||||
@@ -66,62 +71,74 @@ enum mrb_special_consts {
|
||||
* symbol: ...SSSS SS10 (use only upper 32-bit as symbol value on 64-bit CPU)
|
||||
* object: ...PPPP P000 (any bits are 1)
|
||||
*/
|
||||
typedef union mrb_value {
|
||||
union {
|
||||
void *p;
|
||||
typedef uintptr_t mrb_value;
|
||||
union mrb_value_ {
|
||||
void *p;
|
||||
#ifdef MRB_64BIT
|
||||
/* use struct to avoid bit shift. */
|
||||
struct {
|
||||
MRB_ENDIAN_LOHI(
|
||||
mrb_sym sym;
|
||||
,uint32_t sym_flag;
|
||||
)
|
||||
};
|
||||
/* use struct to avoid bit shift. */
|
||||
struct {
|
||||
MRB_ENDIAN_LOHI(
|
||||
mrb_sym sym;
|
||||
,uint32_t sym_flag;
|
||||
)
|
||||
};
|
||||
#endif
|
||||
struct RBasic *bp;
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
struct RFloat *fp;
|
||||
struct RBasic *bp;
|
||||
#ifndef MRB_NO_FLOAT
|
||||
struct RFloat *fp;
|
||||
#endif
|
||||
struct RCptr *vp;
|
||||
} value;
|
||||
unsigned long w;
|
||||
} mrb_value;
|
||||
struct RInteger *ip;
|
||||
struct RCptr *vp;
|
||||
uintptr_t w;
|
||||
};
|
||||
|
||||
static inline union mrb_value_
|
||||
mrb_val_union(mrb_value v)
|
||||
{
|
||||
union mrb_value_ x;
|
||||
x.w = v;
|
||||
return x;
|
||||
}
|
||||
|
||||
MRB_API mrb_value mrb_word_boxing_cptr_value(struct mrb_state*, void*);
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
MRB_API mrb_value mrb_word_boxing_float_value(struct mrb_state*, mrb_float);
|
||||
MRB_API mrb_value mrb_word_boxing_float_pool(struct mrb_state*, mrb_float);
|
||||
#endif
|
||||
MRB_API mrb_value mrb_word_boxing_int_value(struct mrb_state*, mrb_int);
|
||||
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#define mrb_float_pool(mrb,f) mrb_word_boxing_float_pool(mrb,f)
|
||||
#endif
|
||||
#define mrb_immediate_p(o) ((o) & BOXWORD_IMMEDIATE_MASK || (o) == MRB_Qnil)
|
||||
|
||||
#define mrb_ptr(o) (o).value.p
|
||||
#define mrb_cptr(o) (o).value.vp->p
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#define mrb_float(o) (o).value.fp->f
|
||||
#define mrb_ptr(o) mrb_val_union(o).p
|
||||
#define mrb_cptr(o) mrb_val_union(o).vp->p
|
||||
#ifndef MRB_NO_FLOAT
|
||||
#define mrb_float(o) mrb_val_union(o).fp->f
|
||||
#endif
|
||||
#define mrb_fixnum(o) BOXWORD_SHIFT_VALUE(o, FIXNUM, mrb_int)
|
||||
MRB_INLINE mrb_int
|
||||
mrb_integer_func(mrb_value o) {
|
||||
if (mrb_immediate_p(o)) return mrb_fixnum(o);
|
||||
return mrb_val_union(o).ip->i;
|
||||
}
|
||||
#define mrb_integer(o) mrb_integer_func(o)
|
||||
#ifdef MRB_64BIT
|
||||
#define mrb_symbol(o) (o).value.sym
|
||||
#define mrb_symbol(o) mrb_val_union(o).sym
|
||||
#else
|
||||
#define mrb_symbol(o) BOXWORD_SHIFT_VALUE(o, SYMBOL, mrb_sym)
|
||||
#endif
|
||||
#define mrb_bool(o) (((o).w & ~(unsigned long)MRB_Qfalse) != 0)
|
||||
#define mrb_bool(o) (((o) & ~(unsigned long)MRB_Qfalse) != 0)
|
||||
|
||||
#define mrb_immediate_p(o) ((o).w & BOXWORD_IMMEDIATE_MASK || (o).w == MRB_Qnil)
|
||||
#define mrb_fixnum_p(o) BOXWORD_SHIFT_VALUE_P(o, FIXNUM)
|
||||
#define mrb_integer_p(o) (BOXWORD_SHIFT_VALUE_P(o, FIXNUM)||BOXWORD_OBJ_TYPE_P(o, INTEGER))
|
||||
#ifdef MRB_64BIT
|
||||
#define mrb_symbol_p(o) ((o).value.sym_flag == BOXWORD_SYMBOL_FLAG)
|
||||
#define mrb_symbol_p(o) (mrb_val_union(o).sym_flag == BOXWORD_SYMBOL_FLAG)
|
||||
#else
|
||||
#define mrb_symbol_p(o) BOXWORD_SHIFT_VALUE_P(o, SYMBOL)
|
||||
#endif
|
||||
#define mrb_undef_p(o) ((o).w == MRB_Qundef)
|
||||
#define mrb_nil_p(o) ((o).w == MRB_Qnil)
|
||||
#define mrb_false_p(o) ((o).w == MRB_Qfalse)
|
||||
#define mrb_true_p(o) ((o).w == MRB_Qtrue)
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#define mrb_undef_p(o) ((o) == MRB_Qundef)
|
||||
#define mrb_nil_p(o) ((o) == MRB_Qnil)
|
||||
#define mrb_false_p(o) ((o) == MRB_Qfalse)
|
||||
#define mrb_true_p(o) ((o) == MRB_Qtrue)
|
||||
#ifndef MRB_NO_FLOAT
|
||||
#define mrb_float_p(o) BOXWORD_OBJ_TYPE_P(o, FLOAT)
|
||||
#endif
|
||||
#define mrb_array_p(o) BOXWORD_OBJ_TYPE_P(o, ARRAY)
|
||||
@@ -143,32 +160,38 @@ MRB_API mrb_value mrb_word_boxing_float_pool(struct mrb_state*, mrb_float);
|
||||
#define mrb_istruct_p(o) BOXWORD_OBJ_TYPE_P(o, ISTRUCT)
|
||||
#define mrb_break_p(o) BOXWORD_OBJ_TYPE_P(o, BREAK)
|
||||
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
#define SET_FLOAT_VALUE(mrb,r,v) ((r) = mrb_word_boxing_float_value(mrb, v))
|
||||
#endif
|
||||
#define SET_CPTR_VALUE(mrb,r,v) ((r) = mrb_word_boxing_cptr_value(mrb, v))
|
||||
#define SET_UNDEF_VALUE(r) ((r).w = MRB_Qundef)
|
||||
#define SET_NIL_VALUE(r) ((r).w = MRB_Qnil)
|
||||
#define SET_FALSE_VALUE(r) ((r).w = MRB_Qfalse)
|
||||
#define SET_TRUE_VALUE(r) ((r).w = MRB_Qtrue)
|
||||
#define SET_UNDEF_VALUE(r) ((r) = MRB_Qundef)
|
||||
#define SET_NIL_VALUE(r) ((r) = MRB_Qnil)
|
||||
#define SET_FALSE_VALUE(r) ((r) = MRB_Qfalse)
|
||||
#define SET_TRUE_VALUE(r) ((r) = MRB_Qtrue)
|
||||
#define SET_BOOL_VALUE(r,b) ((b) ? SET_TRUE_VALUE(r) : SET_FALSE_VALUE(r))
|
||||
#define SET_INT_VALUE(r,n) BOXWORD_SET_SHIFT_VALUE(r, FIXNUM, n)
|
||||
#define SET_INT_VALUE(mrb,r,n) ((r) = mrb_word_boxing_int_value(mrb, n))
|
||||
#define SET_FIXNUM_VALUE(r,n) BOXWORD_SET_SHIFT_VALUE(r, FIXNUM, n)
|
||||
#ifdef MRB_64BIT
|
||||
#define SET_SYM_VALUE(r,v) ((r).value.sym = v, (r).value.sym_flag = BOXWORD_SYMBOL_FLAG)
|
||||
#define SET_SYM_VALUE(r,v) do {\
|
||||
union mrb_value_ mrb_value_union_variable;\
|
||||
mrb_value_union_variable.sym = v;\
|
||||
mrb_value_union_variable.sym_flag = BOXWORD_SYMBOL_FLAG;\
|
||||
(r) = mrb_value_union_variable.w;\
|
||||
} while (0)
|
||||
#else
|
||||
#define SET_SYM_VALUE(r,n) BOXWORD_SET_SHIFT_VALUE(r, SYMBOL, n)
|
||||
#endif
|
||||
#define SET_OBJ_VALUE(r,v) ((r).value.p = v)
|
||||
#define SET_OBJ_VALUE(r,v) ((r) = (uintptr_t)v)
|
||||
|
||||
MRB_INLINE enum mrb_vtype
|
||||
mrb_type(mrb_value o)
|
||||
{
|
||||
return !mrb_bool(o) ? MRB_TT_FALSE :
|
||||
mrb_true_p(o) ? MRB_TT_TRUE :
|
||||
mrb_fixnum_p(o) ? MRB_TT_FIXNUM :
|
||||
mrb_fixnum_p(o) ? MRB_TT_INTEGER :
|
||||
mrb_symbol_p(o) ? MRB_TT_SYMBOL :
|
||||
mrb_undef_p(o) ? MRB_TT_UNDEF :
|
||||
o.value.bp->tt;
|
||||
mrb_val_union(o).bp->tt;
|
||||
}
|
||||
|
||||
#endif /* MRUBY_BOXING_WORD_H */
|
||||
|
||||
+11
-8
@@ -17,7 +17,7 @@ MRB_BEGIN_DECL
|
||||
struct RClass {
|
||||
MRB_OBJECT_HEADER;
|
||||
struct iv_tbl *iv;
|
||||
struct kh_mt *mt;
|
||||
struct mt_tbl *mt;
|
||||
struct RClass *super;
|
||||
};
|
||||
|
||||
@@ -35,9 +35,9 @@ mrb_class(mrb_state *mrb, mrb_value v)
|
||||
return mrb->true_class;
|
||||
case MRB_TT_SYMBOL:
|
||||
return mrb->symbol_class;
|
||||
case MRB_TT_FIXNUM:
|
||||
return mrb->fixnum_class;
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
case MRB_TT_INTEGER:
|
||||
return mrb->integer_class;
|
||||
#ifndef MRB_NO_FLOAT
|
||||
case MRB_TT_FLOAT:
|
||||
return mrb->float_class;
|
||||
#endif
|
||||
@@ -73,13 +73,11 @@ mrb_class(mrb_state *mrb, mrb_value v)
|
||||
#define MRB_SET_INSTANCE_TT(c, tt) ((c)->flags = (((c)->flags & ~MRB_INSTANCE_TT_MASK) | (char)(tt)))
|
||||
#define MRB_INSTANCE_TT(c) (enum mrb_vtype)((c)->flags & MRB_INSTANCE_TT_MASK)
|
||||
|
||||
MRB_API struct RClass* mrb_define_class_id(mrb_state*, mrb_sym, struct RClass*);
|
||||
MRB_API struct RClass* mrb_define_module_id(mrb_state*, mrb_sym);
|
||||
struct RClass *mrb_vm_define_class(mrb_state*, mrb_value, mrb_value, mrb_sym);
|
||||
struct RClass *mrb_vm_define_module(mrb_state*, mrb_value, mrb_sym);
|
||||
MRB_API void mrb_define_method_raw(mrb_state*, struct RClass*, mrb_sym, mrb_method_t);
|
||||
MRB_API void mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, mrb_aspec aspec);
|
||||
MRB_API void mrb_alias_method(mrb_state*, struct RClass *c, mrb_sym a, mrb_sym b);
|
||||
MRB_API void mrb_remove_method(mrb_state *mrb, struct RClass *c, mrb_sym sym);
|
||||
|
||||
MRB_API mrb_method_t mrb_method_search_vm(mrb_state*, struct RClass**, mrb_sym);
|
||||
MRB_API mrb_method_t mrb_method_search(mrb_state*, struct RClass*, mrb_sym);
|
||||
@@ -95,12 +93,17 @@ void mrb_gc_mark_mt(mrb_state*, struct RClass*);
|
||||
size_t mrb_gc_mark_mt_size(mrb_state*, struct RClass*);
|
||||
void mrb_gc_free_mt(mrb_state*, struct RClass*);
|
||||
|
||||
#ifdef MRB_METHOD_CACHE
|
||||
#ifndef MRB_NO_METHOD_CACHE
|
||||
void mrb_mc_clear_by_class(mrb_state *mrb, struct RClass* c);
|
||||
#else
|
||||
#define mrb_mc_clear_by_class(mrb,c)
|
||||
#endif
|
||||
|
||||
/* return non zero to break the loop */
|
||||
struct mt_elem;
|
||||
typedef int (mrb_mt_foreach_func)(mrb_state*,mrb_sym,struct mt_elem*,void*);
|
||||
MRB_API void mrb_mt_foreach(mrb_state*, struct RClass*, mrb_mt_foreach_func*, void*);
|
||||
|
||||
MRB_END_DECL
|
||||
|
||||
#endif /* MRUBY_CLASS_H */
|
||||
|
||||
@@ -82,6 +82,9 @@ MRB_BEGIN_DECL
|
||||
# elif defined(__MINGW32_MAJOR_VERSION)
|
||||
# define MRB_MINGW32_VERSION (__MINGW32_MAJOR_VERSION * 1000 + __MINGW32_MINOR_VERSION)
|
||||
# endif
|
||||
# if defined(__MINGW32__) && !defined(__MINGW64__)
|
||||
# define MRB_MINGW32_LEGACY
|
||||
# endif
|
||||
#endif
|
||||
|
||||
MRB_END_DECL
|
||||
|
||||
@@ -33,7 +33,7 @@ typedef struct mrbc_context {
|
||||
mrb_bool no_exec:1;
|
||||
mrb_bool keep_lv:1;
|
||||
mrb_bool no_optimize:1;
|
||||
struct RProc *upper;
|
||||
const struct RProc *upper;
|
||||
|
||||
size_t parser_nerr;
|
||||
} mrbc_context;
|
||||
@@ -42,6 +42,7 @@ MRB_API mrbc_context* mrbc_context_new(mrb_state *mrb);
|
||||
MRB_API void mrbc_context_free(mrb_state *mrb, mrbc_context *cxt);
|
||||
MRB_API const char *mrbc_filename(mrb_state *mrb, mrbc_context *c, const char *s);
|
||||
MRB_API void mrbc_partial_hook(mrb_state *mrb, mrbc_context *c, int (*partial_hook)(struct mrb_parser_state*), void*data);
|
||||
MRB_API void mrbc_cleanup_local_variables(mrb_state *mrb, mrbc_context *c);
|
||||
|
||||
/* AST node structure */
|
||||
typedef struct mrb_ast_node {
|
||||
@@ -152,7 +153,7 @@ struct mrb_parser_state {
|
||||
|
||||
mrb_bool no_optimize:1;
|
||||
mrb_bool capture_errors:1;
|
||||
struct RProc *upper;
|
||||
const struct RProc *upper;
|
||||
struct mrb_parser_message error_buffer[10];
|
||||
struct mrb_parser_message warn_buffer[10];
|
||||
|
||||
|
||||
@@ -46,13 +46,13 @@ typedef struct mrb_irep_debug_info {
|
||||
* get line 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, mrb_irep *irep, ptrdiff_t pc);
|
||||
MRB_API const char *mrb_debug_get_filename(mrb_state *mrb, const mrb_irep *irep, ptrdiff_t pc);
|
||||
|
||||
/*
|
||||
* get line from irep's debug info and program counter
|
||||
* @return returns -1 if not found
|
||||
*/
|
||||
MRB_API int32_t mrb_debug_get_line(mrb_state *mrb, mrb_irep *irep, ptrdiff_t pc);
|
||||
MRB_API int32_t mrb_debug_get_line(mrb_state *mrb, const mrb_irep *irep, size_t pc);
|
||||
|
||||
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(
|
||||
|
||||
+13
-25
@@ -18,10 +18,11 @@ MRB_BEGIN_DECL
|
||||
|
||||
#define DUMP_DEBUG_INFO 1
|
||||
|
||||
int mrb_dump_irep(mrb_state *mrb, 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);
|
||||
#ifndef MRB_DISABLE_STDIO
|
||||
int mrb_dump_irep_binary(mrb_state*, mrb_irep*, uint8_t, FILE*);
|
||||
int mrb_dump_irep_cfunc(mrb_state *mrb, mrb_irep*, uint8_t flags, FILE *f, const char *initname);
|
||||
int mrb_dump_irep_binary(mrb_state*, const mrb_irep*, uint8_t, FILE*);
|
||||
int mrb_dump_irep_cfunc(mrb_state *mrb, const mrb_irep*, uint8_t flags, FILE *f, const char *initname);
|
||||
int mrb_dump_irep_cstruct(mrb_state *mrb, const mrb_irep*, uint8_t flags, FILE *f, const char *initname);
|
||||
mrb_irep *mrb_read_irep_file(mrb_state*, FILE*);
|
||||
MRB_API mrb_value mrb_load_irep_file(mrb_state*,FILE*);
|
||||
MRB_API mrb_value mrb_load_irep_file_cxt(mrb_state*, FILE*, mrbc_context*);
|
||||
@@ -48,11 +49,16 @@ MRB_API mrb_irep *mrb_read_irep_buf(mrb_state*, const void*, size_t);
|
||||
|
||||
/* Rite Binary File header */
|
||||
#define RITE_BINARY_IDENT "RITE"
|
||||
#define RITE_BINARY_FORMAT_VER "0007"
|
||||
/* Binary Format Version Major:Minor */
|
||||
/* Major: Incompatible to prior versions */
|
||||
/* Minor: Upper-compatible to prior versions */
|
||||
#define RITE_BINARY_MAJOR_VER "01"
|
||||
#define RITE_BINARY_MINOR_VER "00"
|
||||
#define RITE_BINARY_FORMAT_VER RITE_BINARY_MAJOR_VER RITE_BINARY_MINOR_VER
|
||||
#define RITE_COMPILER_NAME "MATZ"
|
||||
#define RITE_COMPILER_VERSION "0000"
|
||||
|
||||
#define RITE_VM_VER "0002"
|
||||
#define RITE_VM_VER "0300"
|
||||
|
||||
#define RITE_BINARY_EOF "END\0"
|
||||
#define RITE_SECTION_IREP_IDENT "IREP"
|
||||
@@ -65,7 +71,8 @@ MRB_API mrb_irep *mrb_read_irep_buf(mrb_state*, const void*, size_t);
|
||||
/* binary header */
|
||||
struct rite_binary_header {
|
||||
uint8_t binary_ident[4]; /* Binary Identifier */
|
||||
uint8_t binary_version[4]; /* Binary Format Version */
|
||||
uint8_t major_version[2]; /* Binary Format Major Version */
|
||||
uint8_t minor_version[2]; /* Binary Format Minor Version */
|
||||
uint8_t binary_crc[2]; /* Binary CRC */
|
||||
uint8_t binary_size[4]; /* Binary Size */
|
||||
uint8_t compiler_name[4]; /* Compiler name */
|
||||
@@ -126,16 +133,6 @@ uint32_to_bin(uint32_t l, uint8_t *bin)
|
||||
return sizeof(uint32_t);
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
uint32l_to_bin(uint32_t l, uint8_t *bin)
|
||||
{
|
||||
bin[3] = (l >> 24) & 0xff;
|
||||
bin[2] = (l >> 16) & 0xff;
|
||||
bin[1] = (l >> 8) & 0xff;
|
||||
bin[0] = l & 0xff;
|
||||
return sizeof(uint32_t);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
bin_to_uint32(const uint8_t *bin)
|
||||
{
|
||||
@@ -145,15 +142,6 @@ bin_to_uint32(const uint8_t *bin)
|
||||
(uint32_t)bin[3];
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
bin_to_uint32l(const uint8_t *bin)
|
||||
{
|
||||
return (uint32_t)bin[3] << 24 |
|
||||
(uint32_t)bin[2] << 16 |
|
||||
(uint32_t)bin[1] << 8 |
|
||||
(uint32_t)bin[0];
|
||||
}
|
||||
|
||||
static inline uint16_t
|
||||
bin_to_uint16(const uint8_t *bin)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
** @file mruby/endian.h - detect endian-ness
|
||||
**
|
||||
** See Copyright Notice in mruby.h
|
||||
*/
|
||||
|
||||
#ifndef MRUBY_ENDIAN_H
|
||||
#define MRUBY_ENDIAN_H
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
MRB_BEGIN_DECL
|
||||
|
||||
#if !defined(BYTE_ORDER) && defined(__BYTE_ORDER__)
|
||||
# define BYTE_ORDER __BYTE_ORDER__
|
||||
#endif
|
||||
#if !defined(BIG_ENDIAN) && defined(__ORDER_BIG_ENDIAN__)
|
||||
# define BIG_ENDIAN __ORDER_BIG_ENDIAN__
|
||||
#endif
|
||||
#if !defined(LITTLE_ENDIAN) && defined(__ORDER_LITTLE_ENDIAN__)
|
||||
# define LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__
|
||||
#endif
|
||||
|
||||
#ifdef BYTE_ORDER
|
||||
# if BYTE_ORDER == BIG_ENDIAN
|
||||
# define littleendian 0
|
||||
# elif BYTE_ORDER == LITTLE_ENDIAN
|
||||
# define littleendian 1
|
||||
# endif
|
||||
#endif
|
||||
#ifndef littleendian
|
||||
/* can't distinguish endian in compile time */
|
||||
static inline int
|
||||
check_little_endian(void)
|
||||
{
|
||||
unsigned int n = 1;
|
||||
return (*(unsigned char *)&n == 1);
|
||||
}
|
||||
# define littleendian check_little_endian()
|
||||
#endif
|
||||
|
||||
MRB_END_DECL
|
||||
|
||||
#endif /* MRUBY_ENDIAN_H */
|
||||
+39
-5
@@ -23,7 +23,8 @@ struct RException {
|
||||
|
||||
MRB_API 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_str_lit(mrb, c, lit) mrb_exc_new_str(mrb, c, mrb_str_new_lit(mrb, lit))
|
||||
#define mrb_exc_new_lit(mrb, c, lit) mrb_exc_new_str(mrb, c, mrb_str_new_lit(mrb, lit))
|
||||
#define mrb_exc_new_str_lit(mrb, c, lit) mrb_exc_new_str_lit(mrb, c, lit)
|
||||
MRB_API mrb_value mrb_make_exception(mrb_state *mrb, mrb_int argc, const mrb_value *argv);
|
||||
MRB_API mrb_value mrb_exc_backtrace(mrb_state *mrb, mrb_value exc);
|
||||
MRB_API mrb_value mrb_get_backtrace(mrb_state *mrb);
|
||||
@@ -32,10 +33,10 @@ MRB_API mrb_noreturn void mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_va
|
||||
/* declaration for `fail` method */
|
||||
MRB_API mrb_value mrb_f_raise(mrb_state*, mrb_value);
|
||||
|
||||
#if defined(MRB_64BIT) || defined(MRB_USE_FLOAT) || defined(MRB_NAN_BOXING) || defined(MRB_WORD_BOXING)
|
||||
#if defined(MRB_64BIT) || defined(MRB_USE_FLOAT32) || defined(MRB_NAN_BOXING) || defined(MRB_WORD_BOXING)
|
||||
struct RBreak {
|
||||
MRB_OBJECT_HEADER;
|
||||
struct RProc *proc;
|
||||
const struct RProc *proc;
|
||||
mrb_value val;
|
||||
};
|
||||
#define mrb_break_value_get(brk) ((brk)->val)
|
||||
@@ -43,7 +44,7 @@ struct RBreak {
|
||||
#else
|
||||
struct RBreak {
|
||||
MRB_OBJECT_HEADER;
|
||||
struct RProc *proc;
|
||||
const struct RProc *proc;
|
||||
union mrb_value_union value;
|
||||
};
|
||||
#define RBREAK_VALUE_TT_MASK ((1 << 8) - 1)
|
||||
@@ -62,10 +63,43 @@ mrb_break_value_set(struct RBreak *brk, mrb_value val)
|
||||
brk->flags &= ~RBREAK_VALUE_TT_MASK;
|
||||
brk->flags |= val.tt;
|
||||
}
|
||||
#endif /* MRB_64BIT || MRB_USE_FLOAT || MRB_NAN_BOXING || MRB_WORD_BOXING */
|
||||
#endif /* MRB_64BIT || MRB_USE_FLOAT32 || MRB_NAN_BOXING || MRB_WORD_BOXING */
|
||||
#define mrb_break_proc_get(brk) ((brk)->proc)
|
||||
#define mrb_break_proc_set(brk, p) ((brk)->proc = p)
|
||||
|
||||
#define RBREAK_TAG_FOREACH(f) \
|
||||
f(RBREAK_TAG_BREAK, 0) \
|
||||
f(RBREAK_TAG_BREAK_UPPER, 1) \
|
||||
f(RBREAK_TAG_BREAK_INTARGET, 2) \
|
||||
f(RBREAK_TAG_RETURN_BLOCK, 3) \
|
||||
f(RBREAK_TAG_RETURN, 4) \
|
||||
f(RBREAK_TAG_RETURN_TOPLEVEL, 5) \
|
||||
f(RBREAK_TAG_JUMP, 6) \
|
||||
f(RBREAK_TAG_STOP, 7)
|
||||
|
||||
#define RBREAK_TAG_DEFINE(tag, i) tag = i,
|
||||
enum {
|
||||
RBREAK_TAG_FOREACH(RBREAK_TAG_DEFINE)
|
||||
};
|
||||
#undef RBREAK_TAG_DEFINE
|
||||
|
||||
#define RBREAK_TAG_BIT 3
|
||||
#define RBREAK_TAG_BIT_OFF 8
|
||||
#define RBREAK_TAG_MASK (~(~UINT32_C(0) << RBREAK_TAG_BIT))
|
||||
|
||||
static inline uint32_t
|
||||
mrb_break_tag_get(struct RBreak *brk)
|
||||
{
|
||||
return (brk->flags >> RBREAK_TAG_BIT_OFF) & RBREAK_TAG_MASK;
|
||||
}
|
||||
|
||||
static inline void
|
||||
mrb_break_tag_set(struct RBreak *brk, uint32_t tag)
|
||||
{
|
||||
brk->flags &= ~(RBREAK_TAG_MASK << RBREAK_TAG_BIT_OFF);
|
||||
brk->flags |= (tag & RBREAK_TAG_MASK) << RBREAK_TAG_BIT_OFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Protect
|
||||
*
|
||||
|
||||
@@ -21,6 +21,7 @@ struct mrb_state;
|
||||
#define MRB_EACH_OBJ_BREAK 1
|
||||
typedef int (mrb_each_object_callback)(struct mrb_state *mrb, struct RBasic *obj, void *data);
|
||||
void mrb_objspace_each_objects(struct mrb_state *mrb, mrb_each_object_callback *callback, void *data);
|
||||
size_t mrb_objspace_page_slot_size(void);
|
||||
MRB_API void mrb_free_context(struct mrb_state *mrb, struct mrb_context *c);
|
||||
|
||||
#ifndef MRB_GC_ARENA_SIZE
|
||||
|
||||
@@ -23,6 +23,7 @@ struct RHash {
|
||||
#define mrb_hash_ptr(v) ((struct RHash*)(mrb_ptr(v)))
|
||||
#define mrb_hash_value(p) mrb_obj_value((void*)(p))
|
||||
|
||||
size_t mrb_os_memsize_of_hash_table(mrb_value obj);
|
||||
MRB_API mrb_value mrb_hash_new_capa(mrb_state *mrb, mrb_int capa);
|
||||
MRB_API mrb_value mrb_ensure_hash_type(mrb_state *mrb, mrb_value hash);
|
||||
MRB_API mrb_value mrb_check_hash_type(mrb_state *mrb, mrb_value hash);
|
||||
@@ -200,7 +201,7 @@ MRB_API void mrb_hash_merge(mrb_state *mrb, mrb_value hash1, mrb_value hash2);
|
||||
/* RHASH_TBL allocates st_table if not available. */
|
||||
#define RHASH(obj) ((struct RHash*)(mrb_ptr(obj)))
|
||||
#define RHASH_TBL(h) (RHASH(h)->ht)
|
||||
#define RHASH_IFNONE(h) mrb_iv_get(mrb, (h), mrb_intern_lit(mrb, "ifnone"))
|
||||
#define RHASH_IFNONE(h) mrb_iv_get(mrb, (h), MRB_SYM(ifnone))
|
||||
#define RHASH_PROCDEFAULT(h) RHASH_IFNONE(h)
|
||||
|
||||
#define MRB_HASH_DEFAULT 1
|
||||
|
||||
+53
-10
@@ -16,28 +16,58 @@
|
||||
MRB_BEGIN_DECL
|
||||
|
||||
enum irep_pool_type {
|
||||
IREP_TT_STRING,
|
||||
IREP_TT_FIXNUM,
|
||||
IREP_TT_FLOAT,
|
||||
IREP_TT_STR = 0, /* string (need free) */
|
||||
IREP_TT_SSTR = 2, /* string (static) */
|
||||
IREP_TT_INT32 = 1, /* 32bit integer */
|
||||
IREP_TT_INT64 = 3, /* 64bit integer */
|
||||
IREP_TT_FLOAT = 5, /* float (double/float) */
|
||||
};
|
||||
|
||||
struct mrb_locals {
|
||||
mrb_sym name;
|
||||
uint16_t r;
|
||||
#define IREP_TT_NFLAG 1 /* number (non string) flag */
|
||||
#define IREP_TT_SFLAG 2 /* static string flag */
|
||||
|
||||
typedef struct mrb_pool_value {
|
||||
uint32_t tt; /* packed type and length (for string) */
|
||||
union {
|
||||
const char *str;
|
||||
int32_t i32;
|
||||
#ifdef MRB_64BIT
|
||||
int64_t i64;
|
||||
#endif
|
||||
mrb_float f;
|
||||
} u;
|
||||
} mrb_pool_value;
|
||||
|
||||
enum mrb_catch_type {
|
||||
MRB_CATCH_RESCUE = 0,
|
||||
MRB_CATCH_ENSURE = 1,
|
||||
};
|
||||
|
||||
struct mrb_irep_catch_handler {
|
||||
uint8_t type; /* enum mrb_catch_type */
|
||||
uint8_t begin[2]; /* The starting address to match the hander. Includes this. */
|
||||
uint8_t end[2]; /* The endpoint address that matches the hander. Not Includes this. */
|
||||
uint8_t target[2]; /* The address to jump to if a match is made. */
|
||||
};
|
||||
|
||||
/* Program data array struct */
|
||||
typedef struct mrb_irep {
|
||||
uint16_t nlocals; /* Number of local variables */
|
||||
uint16_t nregs; /* Number of register variables */
|
||||
uint16_t clen; /* Number of catch handlers */
|
||||
uint8_t flags;
|
||||
|
||||
const mrb_code *iseq;
|
||||
mrb_value *pool;
|
||||
mrb_sym *syms;
|
||||
struct mrb_irep **reps;
|
||||
/*
|
||||
* A catch handler table is placed after the iseq entity.
|
||||
* The reason it doesn't add fields to the structure is to keep the mrb_irep structure from bloating.
|
||||
* The catch handler table can be obtained with `mrb_irep_catch_handler_table(irep)`.
|
||||
*/
|
||||
const mrb_pool_value *pool;
|
||||
const mrb_sym *syms;
|
||||
const struct mrb_irep * const *reps;
|
||||
|
||||
struct mrb_locals *lv;
|
||||
const mrb_sym *lv;
|
||||
/* debug info */
|
||||
struct mrb_irep_debug_info* debug_info;
|
||||
|
||||
@@ -46,6 +76,8 @@ typedef struct mrb_irep {
|
||||
} mrb_irep;
|
||||
|
||||
#define MRB_ISEQ_NO_FREE 1
|
||||
#define MRB_IREP_NO_FREE 2
|
||||
#define MRB_IREP_STATIC (MRB_ISEQ_NO_FREE | MRB_IREP_NO_FREE)
|
||||
|
||||
MRB_API mrb_irep *mrb_add_irep(mrb_state *mrb);
|
||||
|
||||
@@ -92,6 +124,17 @@ struct mrb_insn_data {
|
||||
|
||||
struct mrb_insn_data mrb_decode_insn(const mrb_code *pc);
|
||||
|
||||
static inline const struct mrb_irep_catch_handler *
|
||||
mrb_irep_catch_handler_table(const struct mrb_irep *irep)
|
||||
{
|
||||
if (irep->clen > 0) {
|
||||
return (const struct mrb_irep_catch_handler*)(irep->iseq + irep->ilen);
|
||||
}
|
||||
else {
|
||||
return (const struct mrb_irep_catch_handler*)NULL;
|
||||
}
|
||||
}
|
||||
|
||||
MRB_END_DECL
|
||||
|
||||
#endif /* MRUBY_IREP_H */
|
||||
|
||||
+5
-13
@@ -61,7 +61,6 @@ static const uint8_t __m_either[] = {0x03, 0x0c, 0x30, 0xc0};
|
||||
typedef struct kh_##name { \
|
||||
khint_t n_buckets; \
|
||||
khint_t size; \
|
||||
khint_t n_occupied; \
|
||||
uint8_t *ed_flags; \
|
||||
khkey_t *keys; \
|
||||
khval_t *vals; \
|
||||
@@ -73,7 +72,6 @@ static const uint8_t __m_either[] = {0x03, 0x0c, 0x30, 0xc0};
|
||||
void kh_clear_##name(mrb_state *mrb, kh_##name##_t *h); \
|
||||
khint_t kh_get_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key); \
|
||||
khint_t kh_put_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key, int *ret); \
|
||||
void kh_put_prepare_##name(mrb_state *mrb, kh_##name##_t *h); \
|
||||
void kh_resize_##name(mrb_state *mrb, kh_##name##_t *h, khint_t new_n_buckets); \
|
||||
void kh_del_##name(mrb_state *mrb, kh_##name##_t *h, khint_t x); \
|
||||
kh_##name##_t *kh_copy_##name(mrb_state *mrb, kh_##name##_t *h);
|
||||
@@ -103,7 +101,7 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
|
||||
size_t len = sizeof(khkey_t) + (kh_is_map ? sizeof(khval_t) : 0); \
|
||||
uint8_t *p = (uint8_t*)mrb_malloc_simple(mrb, sizeof(uint8_t)*sz/4+len*sz); \
|
||||
if (!p) { return 1; } \
|
||||
h->size = h->n_occupied = 0; \
|
||||
h->size = 0; \
|
||||
h->keys = (khkey_t *)p; \
|
||||
h->vals = kh_is_map ? (khval_t *)(p+sizeof(khkey_t)*sz) : NULL; \
|
||||
h->ed_flags = p+len*sz; \
|
||||
@@ -143,7 +141,7 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
|
||||
(void)mrb; \
|
||||
if (h && h->ed_flags) { \
|
||||
kh_fill_flags(h->ed_flags, 0xaa, h->n_buckets/4); \
|
||||
h->size = h->n_occupied = 0; \
|
||||
h->size = 0; \
|
||||
} \
|
||||
} \
|
||||
khint_t kh_get_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key) \
|
||||
@@ -184,16 +182,12 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
|
||||
mrb_free(mrb, old_keys); \
|
||||
} \
|
||||
} \
|
||||
void kh_put_prepare_##name(mrb_state *mrb, kh_##name##_t *h) \
|
||||
{ \
|
||||
if (h->n_occupied >= khash_upper_bound(h)) { \
|
||||
kh_resize_##name(mrb, h, h->n_buckets*2); \
|
||||
} \
|
||||
} \
|
||||
khint_t kh_put_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key, int *ret) \
|
||||
{ \
|
||||
khint_t k, del_k, step = 0; \
|
||||
kh_put_prepare_##name(mrb, h); \
|
||||
if (h->size >= khash_upper_bound(h)) { \
|
||||
kh_resize_##name(mrb, h, h->n_buckets*2); \
|
||||
} \
|
||||
k = __hash_func(mrb,key) & khash_mask(h); \
|
||||
del_k = kh_end(h); \
|
||||
while (!__ac_isempty(h->ed_flags, k)) { \
|
||||
@@ -221,7 +215,6 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
|
||||
h->keys[k] = key; \
|
||||
h->ed_flags[k/4] &= ~__m_empty[k%4]; \
|
||||
h->size++; \
|
||||
h->n_occupied++; \
|
||||
if (ret) *ret = 1; \
|
||||
return k; \
|
||||
} \
|
||||
@@ -256,7 +249,6 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
|
||||
#define kh_destroy(name, mrb, h) kh_destroy_##name(mrb, h)
|
||||
#define kh_clear(name, mrb, h) kh_clear_##name(mrb, h)
|
||||
#define kh_resize(name, mrb, h, s) kh_resize_##name(mrb, h, s)
|
||||
#define kh_put_prepare(name, mrb, h) kh_put_prepare_##name(mrb, h)
|
||||
#define kh_put(name, mrb, h, k) kh_put_##name(mrb, h, k, NULL)
|
||||
#define kh_put2(name, mrb, h, k, r) kh_put_##name(mrb, h, k, r)
|
||||
#define kh_get(name, mrb, h, k) kh_get_##name(mrb, h, k)
|
||||
|
||||
+15
-16
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
** @file mruby/numeric.h - Numeric, Integer, Float, Fixnum class
|
||||
** @file mruby/numeric.h - Numeric, Integer, Float class
|
||||
**
|
||||
** See Copyright Notice in mruby.h
|
||||
*/
|
||||
@@ -12,17 +12,17 @@
|
||||
/**
|
||||
* Numeric class and it's sub-classes.
|
||||
*
|
||||
* Integer, Float and Fixnum
|
||||
* Integer and Float
|
||||
*/
|
||||
MRB_BEGIN_DECL
|
||||
|
||||
#define TYPED_POSFIXABLE(f,t) ((f) <= (t)MRB_INT_MAX)
|
||||
#define TYPED_NEGFIXABLE(f,t) ((f) >= (t)MRB_INT_MIN)
|
||||
#define TYPED_POSFIXABLE(f,t) ((f) <= (t)MRB_FIXNUM_MAX)
|
||||
#define TYPED_NEGFIXABLE(f,t) ((f) >= (t)MRB_FIXNUM_MIN)
|
||||
#define TYPED_FIXABLE(f,t) (TYPED_POSFIXABLE(f,t) && TYPED_NEGFIXABLE(f,t))
|
||||
#define POSFIXABLE(f) TYPED_POSFIXABLE(f,mrb_int)
|
||||
#define NEGFIXABLE(f) TYPED_NEGFIXABLE(f,mrb_int)
|
||||
#define FIXABLE(f) TYPED_FIXABLE(f,mrb_int)
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
#ifdef MRB_INT64
|
||||
#define FIXABLE_FLOAT(f) ((f)>=-9223372036854775808.0 && (f)<9223372036854775808.0)
|
||||
#else
|
||||
@@ -30,16 +30,15 @@ MRB_BEGIN_DECL
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
MRB_API mrb_value mrb_flo_to_fixnum(mrb_state *mrb, mrb_value val);
|
||||
#endif
|
||||
MRB_API mrb_value mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, mrb_int base);
|
||||
/* ArgumentError if format string doesn't match /%(\.[0-9]+)?[aAeEfFgG]/ */
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
MRB_API mrb_value mrb_float_to_str(mrb_state *mrb, mrb_value x, const char *fmt);
|
||||
MRB_API int mrb_float_to_cstr(mrb_state *mrb, char *buf, size_t len, const char *fmt, mrb_float f);
|
||||
MRB_API mrb_float mrb_to_flo(mrb_state *mrb, mrb_value x);
|
||||
MRB_API mrb_value mrb_int_value(mrb_state *mrb, mrb_float f);
|
||||
#endif
|
||||
|
||||
MRB_API mrb_value mrb_num_plus(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
@@ -137,15 +136,15 @@ mrb_int_mul_overflow(mrb_int multiplier, mrb_int multiplicand, mrb_int *product)
|
||||
if (multiplicand > 0) {
|
||||
if (multiplier > MRB_INT_MAX / multiplicand) return TRUE;
|
||||
}
|
||||
else {
|
||||
else if (multiplicand < 0) {
|
||||
if (multiplicand < MRB_INT_MAX / multiplier) return TRUE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
else if (multiplier < 0) {
|
||||
if (multiplicand > 0) {
|
||||
if (multiplier < MRB_INT_MAX / multiplicand) return TRUE;
|
||||
}
|
||||
else {
|
||||
else if (multiplicand < 0) {
|
||||
if (multiplier != 0 && multiplicand < MRB_INT_MAX / multiplier) return TRUE;
|
||||
}
|
||||
}
|
||||
@@ -161,13 +160,13 @@ mrb_int_mul_overflow(mrb_int multiplier, mrb_int multiplicand, mrb_int *product)
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
# include <stdint.h>
|
||||
# include <float.h>
|
||||
|
||||
# define MRB_FLT_RADIX FLT_RADIX
|
||||
|
||||
# ifdef MRB_USE_FLOAT
|
||||
# ifdef MRB_USE_FLOAT32
|
||||
# define MRB_FLT_MANT_DIG FLT_MANT_DIG
|
||||
# define MRB_FLT_EPSILON FLT_EPSILON
|
||||
# define MRB_FLT_DIG FLT_DIG
|
||||
@@ -178,7 +177,7 @@ mrb_int_mul_overflow(mrb_int multiplier, mrb_int multiplicand, mrb_int *product)
|
||||
# define MRB_FLT_MAX FLT_MAX
|
||||
# define MRB_FLT_MAX_10_EXP FLT_MAX_10_EXP
|
||||
|
||||
# else /* not MRB_USE_FLOAT */
|
||||
# else /* not MRB_USE_FLOAT32 */
|
||||
# define MRB_FLT_MANT_DIG DBL_MANT_DIG
|
||||
# define MRB_FLT_EPSILON DBL_EPSILON
|
||||
# define MRB_FLT_DIG DBL_DIG
|
||||
@@ -188,8 +187,8 @@ mrb_int_mul_overflow(mrb_int multiplier, mrb_int multiplicand, mrb_int *product)
|
||||
# define MRB_FLT_MAX_EXP DBL_MAX_EXP
|
||||
# define MRB_FLT_MAX DBL_MAX
|
||||
# define MRB_FLT_MAX_10_EXP DBL_MAX_10_EXP
|
||||
# endif /* MRB_USE_FLOAT */
|
||||
#endif /* MRB_WITHOUT_FLOAT */
|
||||
# endif /* MRB_USE_FLOAT32 */
|
||||
#endif /* MRB_NO_FLOAT */
|
||||
|
||||
MRB_END_DECL
|
||||
|
||||
|
||||
@@ -39,31 +39,4 @@ enum mrb_insn {
|
||||
#define FETCH_S() do {a=READ_S();} while (0)
|
||||
#define FETCH_W() do {a=READ_W();} while (0)
|
||||
|
||||
/* with OP_EXT1 (1st 16bit) */
|
||||
#define FETCH_Z_1() FETCH_Z()
|
||||
#define FETCH_B_1() FETCH_S()
|
||||
#define FETCH_BB_1() do {a=READ_S(); b=READ_B();} while (0)
|
||||
#define FETCH_BBB_1() do {a=READ_S(); b=READ_B(); c=READ_B();} while (0)
|
||||
#define FETCH_BS_1() do {a=READ_S(); b=READ_S();} while (0)
|
||||
#define FETCH_S_1() FETCH_S()
|
||||
#define FETCH_W_1() FETCH_W()
|
||||
|
||||
/* with OP_EXT2 (2nd 16bit) */
|
||||
#define FETCH_Z_2() FETCH_Z()
|
||||
#define FETCH_B_2() FETCH_B()
|
||||
#define FETCH_BB_2() do {a=READ_B(); b=READ_S();} while (0)
|
||||
#define FETCH_BBB_2() do {a=READ_B(); b=READ_S(); c=READ_B();} while (0)
|
||||
#define FETCH_BS_2() FETCH_BS()
|
||||
#define FETCH_S_2() FETCH_S()
|
||||
#define FETCH_W_2() FETCH_W()
|
||||
|
||||
/* with OP_EXT3 (1st & 2nd 16bit) */
|
||||
#define FETCH_Z_3() FETCH_Z()
|
||||
#define FETCH_B_3() FETCH_B()
|
||||
#define FETCH_BB_3() do {a=READ_S(); b=READ_S();} while (0)
|
||||
#define FETCH_BBB_3() do {a=READ_S(); b=READ_S(); c=READ_B();} while (0)
|
||||
#define FETCH_BS_3() do {a=READ_S(); b=READ_S();} while (0)
|
||||
#define FETCH_S_3() FETCH_S()
|
||||
#define FETCH_W_3() FETCH_W()
|
||||
|
||||
#endif /* MRUBY_OPCODE_H */
|
||||
|
||||
+3
-9
@@ -25,6 +25,7 @@ OPCODE(LOADI_4, B) /* R(a) = mrb_int(4) */
|
||||
OPCODE(LOADI_5, B) /* R(a) = mrb_int(5) */
|
||||
OPCODE(LOADI_6, B) /* R(a) = mrb_int(6) */
|
||||
OPCODE(LOADI_7, B) /* R(a) = mrb_int(7) */
|
||||
OPCODE(LOADI16, BS) /* R(a) = mrb_int(b) */
|
||||
OPCODE(LOADSYM, BB) /* R(a) = Syms(b) */
|
||||
OPCODE(LOADNIL, B) /* R(a) = nil */
|
||||
OPCODE(LOADSELF, B) /* R(a) = self */
|
||||
@@ -48,13 +49,10 @@ OPCODE(JMP, S) /* pc=a */
|
||||
OPCODE(JMPIF, BS) /* if R(a) pc=b */
|
||||
OPCODE(JMPNOT, BS) /* if !R(a) pc=b */
|
||||
OPCODE(JMPNIL, BS) /* if R(a)==nil pc=b */
|
||||
OPCODE(ONERR, S) /* rescue_push(a) */
|
||||
OPCODE(JMPUW, S) /* unwind_and_jump_to(a) */
|
||||
OPCODE(EXCEPT, B) /* R(a) = exc */
|
||||
OPCODE(RESCUE, BB) /* R(b) = R(a).isa?(R(b)) */
|
||||
OPCODE(POPERR, B) /* a.times{rescue_pop()} */
|
||||
OPCODE(RAISE, B) /* raise(R(a)) */
|
||||
OPCODE(EPUSH, B) /* ensure_push(SEQ[a]) */
|
||||
OPCODE(EPOP, B) /* A.times{ensure_pop().call} */
|
||||
OPCODE(RAISEIF, B) /* raise(R(a)) if R(a) */
|
||||
OPCODE(SENDV, BB) /* R(a) = call(R(a),Syms(b),*R(a+1)) */
|
||||
OPCODE(SENDVB, BB) /* R(a) = call(R(a),Syms(b),*R(a+1),&R(a+2)) */
|
||||
OPCODE(SEND, BBB) /* R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c)) */
|
||||
@@ -111,8 +109,4 @@ OPCODE(SCLASS, B) /* R(a) = R(a).singleton_class */
|
||||
OPCODE(TCLASS, B) /* R(a) = target_class */
|
||||
OPCODE(DEBUG, BBB) /* print a,b,c */
|
||||
OPCODE(ERR, B) /* raise(LocalJumpError, Lit(a)) */
|
||||
OPCODE(EXT1, Z) /* make 1st operand 16bit */
|
||||
OPCODE(EXT2, Z) /* make 2nd operand 16bit */
|
||||
OPCODE(EXT3, Z) /* make 1st and 2nd operands 16bit */
|
||||
OPCODE(STOP, Z) /* stop VM */
|
||||
OPCODE(LOADI16, BS) /* R(a) = mrb_int(b) */
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
** @file mruby/presym.h - Preallocated Symbols
|
||||
**
|
||||
** See Copyright Notice in mruby.h
|
||||
*/
|
||||
|
||||
#ifndef MRUBY_PRESYM_H
|
||||
#define MRUBY_PRESYM_H
|
||||
|
||||
#undef MRB_PRESYM_MAX
|
||||
#define MRB_PRESYM_CSYM(sym, num) MRB_PRESYM__##sym = (num<<1),
|
||||
#define MRB_PRESYM_QSYM(str, sym, num) MRB_PRESYM_q_##sym = (num<<1),
|
||||
#define MRB_PRESYM_SYM(sym, num)
|
||||
|
||||
enum mruby_presym {
|
||||
#include <../build/presym.inc>
|
||||
};
|
||||
|
||||
#undef MRB_PRESYM_CSYM
|
||||
#undef MRB_PRESYM_QSYM
|
||||
#undef MRB_PRESYM_SYM
|
||||
|
||||
#define MRB_SYM(sym) MRB_PRESYM__##sym
|
||||
#define MRB_QSYM(sym) MRB_PRESYM_q_##sym
|
||||
#endif /* MRUBY_PRESYM_H */
|
||||
+10
-10
@@ -41,10 +41,10 @@ void mrb_env_unshare(mrb_state*, struct REnv*);
|
||||
struct RProc {
|
||||
MRB_OBJECT_HEADER;
|
||||
union {
|
||||
mrb_irep *irep;
|
||||
const mrb_irep *irep;
|
||||
mrb_func_t func;
|
||||
} body;
|
||||
struct RProc *upper;
|
||||
const struct RProc *upper;
|
||||
union {
|
||||
struct RClass *target_class;
|
||||
struct REnv *env;
|
||||
@@ -57,7 +57,7 @@ struct RProc {
|
||||
#define MRB_ASPEC_REST(a) (((a) >> 12) & 0x1)
|
||||
#define MRB_ASPEC_POST(a) (((a) >> 7) & 0x1f)
|
||||
#define MRB_ASPEC_KEY(a) (((a) >> 2) & 0x1f)
|
||||
#define MRB_ASPEC_KDICT(a) ((a) & (1<<1))
|
||||
#define MRB_ASPEC_KDICT(a) (((a) >> 1) & 0x1)
|
||||
#define MRB_ASPEC_BLOCK(a) ((a) & 1)
|
||||
|
||||
#define MRB_PROC_CFUNC_FL 128
|
||||
@@ -86,16 +86,13 @@ struct RProc {
|
||||
|
||||
#define mrb_proc_ptr(v) ((struct RProc*)(mrb_ptr(v)))
|
||||
|
||||
struct RProc *mrb_proc_new(mrb_state*, mrb_irep*);
|
||||
struct RProc *mrb_closure_new(mrb_state*, mrb_irep*);
|
||||
struct RProc *mrb_proc_new(mrb_state*, const mrb_irep*);
|
||||
struct RProc *mrb_closure_new(mrb_state*, const mrb_irep*);
|
||||
MRB_API struct RProc *mrb_proc_new_cfunc(mrb_state*, mrb_func_t);
|
||||
MRB_API struct RProc *mrb_closure_new_cfunc(mrb_state *mrb, mrb_func_t func, int nlocals);
|
||||
void mrb_proc_copy(struct RProc *a, struct RProc *b);
|
||||
mrb_int mrb_proc_arity(const struct RProc *p);
|
||||
|
||||
/* implementation of #send method */
|
||||
mrb_value mrb_f_send(mrb_state *mrb, mrb_value self);
|
||||
|
||||
/* following functions are defined in mruby-proc-ext so please include it when using */
|
||||
MRB_API struct RProc *mrb_proc_new_cfunc_with_env(mrb_state *mrb, mrb_func_t func, mrb_int argc, const mrb_value *argv);
|
||||
MRB_API mrb_value mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx);
|
||||
@@ -104,7 +101,8 @@ MRB_API mrb_value mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx);
|
||||
|
||||
#define MRB_METHOD_FUNC_FL 1
|
||||
#define MRB_METHOD_NOARG_FL 2
|
||||
#ifndef MRB_METHOD_T_STRUCT
|
||||
|
||||
#ifndef MRB_USE_METHOD_T_STRUCT
|
||||
|
||||
#define MRB_METHOD_FUNC_P(m) (((uintptr_t)(m))&MRB_METHOD_FUNC_FL)
|
||||
#define MRB_METHOD_NOARG_P(m) (((uintptr_t)(m))&MRB_METHOD_NOARG_FL)
|
||||
@@ -128,7 +126,7 @@ MRB_API mrb_value mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx);
|
||||
#define MRB_METHOD_PROC(m) ((m).proc)
|
||||
#define MRB_METHOD_UNDEF_P(m) ((m).proc==NULL)
|
||||
|
||||
#endif /* MRB_METHOD_T_STRUCT */
|
||||
#endif /* MRB_USE_METHOD_T_STRUCT */
|
||||
|
||||
#define MRB_METHOD_CFUNC_P(m) (MRB_METHOD_FUNC_P(m)?TRUE:(MRB_METHOD_PROC(m)?(MRB_PROC_CFUNC_P(MRB_METHOD_PROC(m))):FALSE))
|
||||
#define MRB_METHOD_CFUNC(m) (MRB_METHOD_FUNC_P(m)?MRB_METHOD_FUNC(m):((MRB_METHOD_PROC(m)&&MRB_PROC_CFUNC_P(MRB_METHOD_PROC(m)))?MRB_PROC_CFUNC(MRB_METHOD_PROC(m)):NULL))
|
||||
@@ -137,6 +135,8 @@ MRB_API mrb_value mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx);
|
||||
#include <mruby/khash.h>
|
||||
KHASH_DECLARE(mt, mrb_sym, mrb_method_t, TRUE)
|
||||
|
||||
MRB_API mrb_value mrb_load_proc(mrb_state *mrb, const struct RProc *proc);
|
||||
|
||||
MRB_END_DECL
|
||||
|
||||
#endif /* MRUBY_PROC_H */
|
||||
|
||||
+5
-10
@@ -35,7 +35,7 @@ struct RString {
|
||||
};
|
||||
struct RStringEmbed {
|
||||
MRB_OBJECT_HEADER;
|
||||
char ary[];
|
||||
char ary[RSTRING_EMBED_LEN_MAX+1];
|
||||
};
|
||||
|
||||
#define RSTR_SET_TYPE_FLAG(s, type) (RSTR_UNSET_TYPE_FLAG(s), (s)->flags |= MRB_STR_##type)
|
||||
@@ -92,9 +92,6 @@ struct RStringEmbed {
|
||||
# define RSTR_COPY_ASCII_FLAG(dst, src) (void)0
|
||||
#endif
|
||||
|
||||
#define RSTR_POOL_P(s) ((s)->flags & MRB_STR_POOL)
|
||||
#define RSTR_SET_POOL_FLAG(s) ((s)->flags |= MRB_STR_POOL)
|
||||
|
||||
/**
|
||||
* Returns a pointer from a Ruby string
|
||||
*/
|
||||
@@ -112,13 +109,11 @@ MRB_API mrb_int mrb_str_strlen(mrb_state*, struct RString*);
|
||||
#define MRB_STR_FSHARED 2
|
||||
#define MRB_STR_NOFREE 4
|
||||
#define MRB_STR_EMBED 8 /* type flags up to here */
|
||||
#define MRB_STR_POOL 16 /* status flags from here */
|
||||
#define MRB_STR_ASCII 32
|
||||
#define MRB_STR_ASCII 16
|
||||
#define MRB_STR_EMBED_LEN_SHIFT 6
|
||||
#define MRB_STR_EMBED_LEN_BIT 5
|
||||
#define MRB_STR_EMBED_LEN_MASK (((1 << MRB_STR_EMBED_LEN_BIT) - 1) << MRB_STR_EMBED_LEN_SHIFT)
|
||||
#define MRB_STR_TYPE_MASK (MRB_STR_POOL - 1)
|
||||
|
||||
#define MRB_STR_TYPE_MASK 15
|
||||
|
||||
void mrb_gc_free_str(mrb_state*, struct RString*);
|
||||
|
||||
@@ -382,8 +377,9 @@ MRB_API double mrb_cstr_to_dbl(mrb_state *mrb, const char *s, mrb_bool badcheck)
|
||||
/**
|
||||
* Returns a converted string type.
|
||||
* For type checking, non converting `mrb_to_str` is recommended.
|
||||
* obsolete: use `mrb_obj_as_string()` instead.
|
||||
*/
|
||||
MRB_API mrb_value mrb_str_to_str(mrb_state *mrb, mrb_value str);
|
||||
#define mrb_str_to_str(mrb, str) mrb_obj_as_string(mrb, str)
|
||||
|
||||
/**
|
||||
* Returns true if the strings match and false if the strings don't match.
|
||||
@@ -447,7 +443,6 @@ MRB_API int mrb_str_cmp(mrb_state *mrb, mrb_value str1, mrb_value str2);
|
||||
*/
|
||||
MRB_API char *mrb_str_to_cstr(mrb_state *mrb, mrb_value str);
|
||||
|
||||
mrb_value mrb_str_pool(mrb_state *mrb, const char *s, mrb_int len, mrb_bool nofree);
|
||||
uint32_t mrb_str_hash(mrb_state *mrb, mrb_value str);
|
||||
mrb_value mrb_str_dump(mrb_state *mrb, mrb_value str);
|
||||
|
||||
|
||||
+10
-2
@@ -13,7 +13,9 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(MRB_ENABLE_CXX_EXCEPTION) && defined(__cplusplus)
|
||||
#if defined(MRB_ENABLE_CXX_EXCEPTION)
|
||||
|
||||
# if defined(__cplusplus)
|
||||
|
||||
#define MRB_TRY(buf) try {
|
||||
#define MRB_CATCH(buf) } catch(mrb_jmpbuf_impl e) { if (e != (buf)->impl) { throw e; }
|
||||
@@ -22,6 +24,10 @@
|
||||
#define MRB_THROW(buf) throw((buf)->impl)
|
||||
typedef mrb_int mrb_jmpbuf_impl;
|
||||
|
||||
# else
|
||||
# error "need to be compiled with C++ compiler"
|
||||
# endif /* __cplusplus */
|
||||
|
||||
#else
|
||||
|
||||
#include <setjmp.h>
|
||||
@@ -46,9 +52,11 @@ typedef mrb_int mrb_jmpbuf_impl;
|
||||
struct mrb_jmpbuf {
|
||||
mrb_jmpbuf_impl impl;
|
||||
|
||||
#if defined(MRB_ENABLE_CXX_EXCEPTION) && defined(__cplusplus)
|
||||
#if defined(MRB_ENABLE_CXX_EXCEPTION)
|
||||
static mrb_int jmpbuf_id;
|
||||
# if defined(__cplusplus)
|
||||
mrb_jmpbuf() : impl(jmpbuf_id++) {}
|
||||
# endif
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
+30
-15
@@ -54,16 +54,20 @@ struct mrb_state;
|
||||
#if defined(MRB_INT64)
|
||||
typedef int64_t mrb_int;
|
||||
# define MRB_INT_BIT 64
|
||||
# define MRB_INT_MIN (INT64_MIN>>MRB_FIXNUM_SHIFT)
|
||||
# define MRB_INT_MAX (INT64_MAX>>MRB_FIXNUM_SHIFT)
|
||||
# define MRB_INT_MIN INT64_MIN
|
||||
# define MRB_INT_MAX INT64_MAX
|
||||
# define MRB_FIXNUM_MIN (INT64_MIN>>MRB_FIXNUM_SHIFT)
|
||||
# define MRB_FIXNUM_MAX (INT64_MAX>>MRB_FIXNUM_SHIFT)
|
||||
# define MRB_PRIo PRIo64
|
||||
# define MRB_PRId PRId64
|
||||
# define MRB_PRIx PRIx64
|
||||
#else
|
||||
typedef int32_t mrb_int;
|
||||
# define MRB_INT_BIT 32
|
||||
# define MRB_INT_MIN (INT32_MIN>>MRB_FIXNUM_SHIFT)
|
||||
# define MRB_INT_MAX (INT32_MAX>>MRB_FIXNUM_SHIFT)
|
||||
# define MRB_INT_MIN INT32_MIN
|
||||
# define MRB_INT_MAX INT32_MAX
|
||||
# define MRB_FIXNUM_MIN (INT32_MIN>>MRB_FIXNUM_SHIFT)
|
||||
# define MRB_FIXNUM_MAX (INT32_MAX>>MRB_FIXNUM_SHIFT)
|
||||
# define MRB_PRIo PRIo32
|
||||
# define MRB_PRId PRId32
|
||||
# define MRB_PRIx PRIx32
|
||||
@@ -75,9 +79,9 @@ struct mrb_state;
|
||||
# define MRB_ENDIAN_LOHI(a,b) b a
|
||||
#endif
|
||||
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
MRB_API double mrb_float_read(const char*, char**);
|
||||
#ifdef MRB_USE_FLOAT
|
||||
#ifdef MRB_USE_FLOAT32
|
||||
typedef float mrb_float;
|
||||
#else
|
||||
typedef double mrb_float;
|
||||
@@ -90,7 +94,7 @@ MRB_API int mrb_msvc_vsnprintf(char *s, size_t n, const char *format, va_list ar
|
||||
MRB_API int mrb_msvc_snprintf(char *s, size_t n, const char *format, ...);
|
||||
# define vsnprintf(s, n, format, arg) mrb_msvc_vsnprintf(s, n, format, arg)
|
||||
# define snprintf(s, n, format, ...) mrb_msvc_snprintf(s, n, format, __VA_ARGS__)
|
||||
# if _MSC_VER < 1800 && !defined MRB_WITHOUT_FLOAT
|
||||
# if _MSC_VER < 1800 && !defined MRB_NO_FLOAT
|
||||
# include <float.h>
|
||||
# define isfinite(n) _finite(n)
|
||||
# define isnan _isnan
|
||||
@@ -106,7 +110,7 @@ enum mrb_vtype {
|
||||
MRB_TT_FALSE = 0,
|
||||
MRB_TT_TRUE,
|
||||
MRB_TT_FLOAT,
|
||||
MRB_TT_FIXNUM,
|
||||
MRB_TT_INTEGER,
|
||||
MRB_TT_SYMBOL,
|
||||
MRB_TT_UNDEF,
|
||||
MRB_TT_CPTR,
|
||||
@@ -130,6 +134,9 @@ enum mrb_vtype {
|
||||
MRB_TT_MAXDEFINE
|
||||
};
|
||||
|
||||
/* for compatibility */
|
||||
#define MRB_TT_FIXNUM MRB_TT_INTEGER
|
||||
|
||||
#include <mruby/object.h>
|
||||
|
||||
#ifdef MRB_DOCUMENTATION_BLOCK
|
||||
@@ -177,8 +184,11 @@ struct RCptr {
|
||||
#ifndef mrb_immediate_p
|
||||
#define mrb_immediate_p(o) (mrb_type(o) < MRB_TT_FREE)
|
||||
#endif
|
||||
#ifndef mrb_integer_p
|
||||
#define mrb_integer_p(o) (mrb_type(o) == MRB_TT_INTEGER)
|
||||
#endif
|
||||
#ifndef mrb_fixnum_p
|
||||
#define mrb_fixnum_p(o) (mrb_type(o) == MRB_TT_FIXNUM)
|
||||
#define mrb_fixnum_p(o) mrb_integer_p(o)
|
||||
#endif
|
||||
#ifndef mrb_symbol_p
|
||||
#define mrb_symbol_p(o) (mrb_type(o) == MRB_TT_SYMBOL)
|
||||
@@ -195,7 +205,7 @@ struct RCptr {
|
||||
#ifndef mrb_true_p
|
||||
#define mrb_true_p(o) (mrb_type(o) == MRB_TT_TRUE)
|
||||
#endif
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
#ifndef mrb_float_p
|
||||
#define mrb_float_p(o) (mrb_type(o) == MRB_TT_FLOAT)
|
||||
#endif
|
||||
@@ -264,7 +274,7 @@ struct RCptr {
|
||||
*
|
||||
* Takes a float and boxes it into an mrb_value
|
||||
*/
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
MRB_INLINE mrb_value mrb_float_value(struct mrb_state *mrb, mrb_float f)
|
||||
{
|
||||
mrb_value v;
|
||||
@@ -284,14 +294,19 @@ mrb_cptr_value(struct mrb_state *mrb, void *p)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a fixnum in Ruby.
|
||||
*
|
||||
* Takes an integer and boxes it into an mrb_value
|
||||
* Returns an integer in Ruby.
|
||||
*/
|
||||
MRB_INLINE mrb_value mrb_int_value(struct mrb_state *mrb, mrb_int i)
|
||||
{
|
||||
mrb_value v;
|
||||
SET_INT_VALUE(mrb, v, i);
|
||||
return v;
|
||||
}
|
||||
|
||||
MRB_INLINE mrb_value mrb_fixnum_value(mrb_int i)
|
||||
{
|
||||
mrb_value v;
|
||||
SET_INT_VALUE(v, i);
|
||||
SET_FIXNUM_VALUE(v, i);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ mrb_value mrb_vm_cv_get(mrb_state*, mrb_sym);
|
||||
void mrb_vm_cv_set(mrb_state*, mrb_sym, mrb_value);
|
||||
mrb_value mrb_vm_const_get(mrb_state*, mrb_sym);
|
||||
void mrb_vm_const_set(mrb_state*, mrb_sym, mrb_value);
|
||||
size_t mrb_obj_iv_tbl_memsize(mrb_state*, mrb_value);
|
||||
MRB_API mrb_value mrb_const_get(mrb_state*, mrb_value, mrb_sym);
|
||||
MRB_API void mrb_const_set(mrb_state*, mrb_value, mrb_sym, mrb_value);
|
||||
MRB_API mrb_bool mrb_const_defined(mrb_state*, mrb_value, mrb_sym);
|
||||
|
||||
@@ -27,7 +27,7 @@ MRB_BEGIN_DECL
|
||||
/*
|
||||
* The version of Ruby used by mruby.
|
||||
*/
|
||||
#define MRUBY_RUBY_VERSION "2.0"
|
||||
#define MRUBY_RUBY_VERSION "3.0"
|
||||
|
||||
/*
|
||||
* Ruby engine.
|
||||
@@ -37,17 +37,17 @@ MRB_BEGIN_DECL
|
||||
/*
|
||||
* Major release version number.
|
||||
*/
|
||||
#define MRUBY_RELEASE_MAJOR 2
|
||||
#define MRUBY_RELEASE_MAJOR 3
|
||||
|
||||
/*
|
||||
* Minor release version number.
|
||||
*/
|
||||
#define MRUBY_RELEASE_MINOR 1
|
||||
#define MRUBY_RELEASE_MINOR 0
|
||||
|
||||
/*
|
||||
* Tiny release version number.
|
||||
*/
|
||||
#define MRUBY_RELEASE_TEENY 2
|
||||
#define MRUBY_RELEASE_TEENY 0
|
||||
|
||||
/*
|
||||
* The mruby version.
|
||||
@@ -67,12 +67,12 @@ MRB_BEGIN_DECL
|
||||
/*
|
||||
* Release month.
|
||||
*/
|
||||
#define MRUBY_RELEASE_MONTH 7
|
||||
#define MRUBY_RELEASE_MONTH 10
|
||||
|
||||
/*
|
||||
* Release day.
|
||||
*/
|
||||
#define MRUBY_RELEASE_DAY 10
|
||||
#define MRUBY_RELEASE_DAY 16
|
||||
|
||||
/*
|
||||
* Release date as a string.
|
||||
|
||||
+25
-10
@@ -81,7 +81,8 @@ module MRuby
|
||||
@mrbc = Command::Mrbc.new(self)
|
||||
|
||||
@bins = []
|
||||
@gems, @libmruby_objs = MRuby::Gem::List.new, []
|
||||
@gems = MRuby::Gem::List.new
|
||||
@libmruby_objs = []
|
||||
@build_mrbtest_lib_only = false
|
||||
@cxx_exception_enabled = false
|
||||
@cxx_exception_disabled = false
|
||||
@@ -95,11 +96,10 @@ module MRuby
|
||||
MRuby.targets[@name] = self
|
||||
end
|
||||
|
||||
MRuby::Build.current = MRuby.targets[@name]
|
||||
MRuby.targets[@name].instance_eval(&block)
|
||||
|
||||
build_mrbc_exec if name == 'host'
|
||||
build_mrbtest if test_enabled?
|
||||
current = MRuby.targets[@name]
|
||||
MRuby::Build.current = current
|
||||
current.instance_eval(&block)
|
||||
current.build_mrbtest if current.test_enabled?
|
||||
end
|
||||
|
||||
def debug_enabled?
|
||||
@@ -196,6 +196,7 @@ EOS
|
||||
end
|
||||
|
||||
def enable_bintest
|
||||
raise "bintest works only on 'host' target" unless name == "host"
|
||||
@enable_bintest = true
|
||||
end
|
||||
|
||||
@@ -246,9 +247,11 @@ EOS
|
||||
def mrbcfile
|
||||
return @mrbcfile if @mrbcfile
|
||||
|
||||
mrbc_build = MRuby.targets['host']
|
||||
gems.each { |v| mrbc_build = self if v.name == 'mruby-bin-mrbc' }
|
||||
@mrbcfile = mrbc_build.exefile("#{mrbc_build.build_dir}/bin/mrbc")
|
||||
unless gems.detect {|v| v.name == 'mruby-bin-mrbc' }
|
||||
build_mrbc_exec
|
||||
gems.detect {|v| v.name == 'mruby-bin-mrbc' }.setup
|
||||
end
|
||||
@mrbcfile = self.exefile("#{self.build_dir}/bin/mrbc")
|
||||
end
|
||||
|
||||
def compilers
|
||||
@@ -369,13 +372,25 @@ EOS
|
||||
attr_accessor :host_target, :build_target
|
||||
|
||||
def initialize(name, build_dir=nil, &block)
|
||||
unless MRuby.targets['host']
|
||||
# add minimal 'host'
|
||||
MRuby::Build.new('host') do |conf|
|
||||
if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR']
|
||||
toolchain :visualcpp
|
||||
else
|
||||
toolchain :gcc
|
||||
end
|
||||
conf.gem :core => 'mruby-bin-mrbc'
|
||||
end
|
||||
end
|
||||
@endian = nil
|
||||
@test_runner = Command::CrossTestRunner.new(self)
|
||||
super
|
||||
end
|
||||
|
||||
def mrbcfile
|
||||
MRuby.targets['host'].exefile("#{MRuby.targets['host'].build_dir}/bin/mrbc")
|
||||
host = MRuby.targets['host']
|
||||
host.exefile("#{host.build_dir}/bin/mrbc")
|
||||
end
|
||||
|
||||
def run_test
|
||||
|
||||
+18
-15
@@ -133,18 +133,14 @@ module MRuby
|
||||
#
|
||||
# ==== Without <tt>-MP</tt> compiler flag
|
||||
#
|
||||
# /build/host/src/array.o: \
|
||||
# /src/array.c \
|
||||
# /include/mruby/common.h \
|
||||
# /include/mruby/value.h \
|
||||
# /build/host/src/array.o: /src/array.c \
|
||||
# /include/mruby/common.h /include/mruby/value.h \
|
||||
# /src/value_array.h
|
||||
#
|
||||
# ==== With <tt>-MP</tt> compiler flag
|
||||
#
|
||||
# /build/host/src/array.o: \
|
||||
# /src/array.c \
|
||||
# /include/mruby/common.h \
|
||||
# /include/mruby/value.h \
|
||||
# /build/host/src/array.o: /src/array.c \
|
||||
# /include/mruby/common.h /include/mruby/value.h \
|
||||
# /src/value_array.h
|
||||
#
|
||||
# /include/mruby/common.h:
|
||||
@@ -155,11 +151,18 @@ module MRuby
|
||||
#
|
||||
def get_dependencies(file)
|
||||
file = file.ext('d') unless File.extname(file) == '.d'
|
||||
deps = []
|
||||
if File.exist?(file)
|
||||
File.foreach(file){|line| deps << $1 if /^ +(.*?)(?: *\\)?$/ =~ line}
|
||||
deps.uniq!
|
||||
end
|
||||
return [MRUBY_CONFIG] unless File.exist?(file)
|
||||
|
||||
deps = File.read(file).gsub("\\\n ", "").split("\n").map do |dep_line|
|
||||
# dep_line:
|
||||
# - "/build/host/src/array.o: /src/array.c /include/mruby/common.h ..."
|
||||
# - ""
|
||||
# - "/include/mruby/common.h:"
|
||||
dep_line.scan(/^\S+:\s+(.+)$/).flatten.map { |s| s.split(' ') }.flatten
|
||||
# => ["/src/array.c", "/include/mruby/common.h" , ...]
|
||||
# []
|
||||
# []
|
||||
end.flatten.uniq
|
||||
deps << MRUBY_CONFIG
|
||||
end
|
||||
end
|
||||
@@ -310,13 +313,13 @@ module MRuby
|
||||
@compile_options = "-B%{funcname} -o-"
|
||||
end
|
||||
|
||||
def run(out, infiles, funcname)
|
||||
def run(out, infiles, funcname, cdump = true)
|
||||
@command ||= @build.mrbcfile
|
||||
infiles = [infiles].flatten
|
||||
infiles.each do |f|
|
||||
_pp "MRBC", f.relative_path, nil, :indent => 2
|
||||
end
|
||||
cmd = %Q["#{filename @command}" #{@compile_options % {:funcname => funcname}} #{filename(infiles).map{|f| %Q["#{f}"]}.join(' ')}]
|
||||
cmd = %Q["#{filename @command}" #{cdump ? "-S" : ""} #{@compile_options % {:funcname => funcname}} #{filename(infiles).map{|f| %Q["#{f}"]}.join(' ')}]
|
||||
puts cmd if Rake.verbose
|
||||
IO.popen(cmd, 'r+') do |io|
|
||||
out.puts io.read
|
||||
|
||||
@@ -28,18 +28,19 @@ module MRuby
|
||||
Gem.current = nil
|
||||
load gemrake
|
||||
return nil unless Gem.current
|
||||
current = Gem.current
|
||||
|
||||
Gem.current.dir = gemdir
|
||||
Gem.current.build = self.is_a?(MRuby::Build) ? self : MRuby::Build.current
|
||||
Gem.current.build_config_initializer = block
|
||||
gems << Gem.current
|
||||
current.dir = gemdir
|
||||
current.build = self.is_a?(MRuby::Build) ? self : MRuby::Build.current
|
||||
current.build_config_initializer = block
|
||||
gems << current
|
||||
|
||||
cxx_srcs = ['src', 'test', 'tools'].map do |subdir|
|
||||
Dir.glob("#{Gem.current.dir}/#{subdir}/*.{cpp,cxx,cc}")
|
||||
Dir.glob("#{current.dir}/#{subdir}/*.{cpp,cxx,cc}")
|
||||
end.flatten
|
||||
enable_cxx_exception unless cxx_srcs.empty?
|
||||
|
||||
Gem.current
|
||||
current
|
||||
end
|
||||
|
||||
def load_special_path_gem(params)
|
||||
|
||||
+17
-8
@@ -47,12 +47,14 @@ module MRuby
|
||||
@version = "0.0.0"
|
||||
@mrblib_dir = "mrblib"
|
||||
@objs_dir = "src"
|
||||
@dependencies = []
|
||||
@conflicts = []
|
||||
MRuby::Gem.current = self
|
||||
end
|
||||
|
||||
def setup
|
||||
return if defined?(@linker) # return if already set up
|
||||
|
||||
|
||||
MRuby::Gem.current = self
|
||||
MRuby::Build::COMMANDS.each do |command|
|
||||
instance_variable_set("@#{command}", @build.send(command).clone)
|
||||
@@ -75,7 +77,6 @@ module MRuby
|
||||
@bins = []
|
||||
|
||||
@requirements = []
|
||||
@dependencies, @conflicts = [], []
|
||||
@export_include_paths = []
|
||||
@export_include_paths << "#{dir}/include" if File.directory? "#{dir}/include"
|
||||
|
||||
@@ -174,20 +175,24 @@ module MRuby
|
||||
def generate_gem_init(fname)
|
||||
open(fname, 'w') do |f|
|
||||
print_gem_init_header f
|
||||
build.mrbc.run f, rbfiles, "gem_mrblib_irep_#{funcname}" unless rbfiles.empty?
|
||||
build.mrbc.run f, rbfiles, "gem_mrblib_#{funcname}_proc" unless rbfiles.empty?
|
||||
f.puts %Q[void mrb_#{funcname}_gem_init(mrb_state *mrb);]
|
||||
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[ struct REnv *e;] unless rbfiles.empty?
|
||||
f.puts %Q[ mrb_#{funcname}_gem_init(mrb);] if objs != [objfile("#{build_dir}/gem_init")]
|
||||
unless rbfiles.empty?
|
||||
f.puts %Q[ mrb_load_irep(mrb, gem_mrblib_irep_#{funcname});]
|
||||
f.puts %Q[ mrb_load_proc(mrb, gem_mrblib_#{funcname}_proc);]
|
||||
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[ e = mrb->c->cibase->env;]
|
||||
f.puts %Q[ mrb->c->cibase->env = NULL;]
|
||||
f.puts %Q[ mrb_env_unshare(mrb, e);]
|
||||
end
|
||||
f.puts %Q[ mrb_gc_arena_restore(mrb, ai);]
|
||||
f.puts %Q[}]
|
||||
@@ -211,9 +216,13 @@ module MRuby
|
||||
|
||||
def print_gem_init_header(f)
|
||||
print_gem_comment(f)
|
||||
f.puts %Q[#include <stdlib.h>] unless rbfiles.empty?
|
||||
f.puts %Q[#include <mruby.h>]
|
||||
f.puts %Q[#include <mruby/irep.h>] unless rbfiles.empty?
|
||||
unless rbfiles.empty?
|
||||
f.puts %Q[#include <stdlib.h>]
|
||||
f.puts %Q[#include <mruby.h>]
|
||||
f.puts %Q[#include <mruby/proc.h>]
|
||||
else
|
||||
f.puts %Q[#include <mruby.h>]
|
||||
end
|
||||
end
|
||||
|
||||
def print_gem_test_header(f)
|
||||
@@ -221,7 +230,7 @@ module MRuby
|
||||
f.puts %Q[#include <stdio.h>]
|
||||
f.puts %Q[#include <stdlib.h>]
|
||||
f.puts %Q[#include <mruby.h>]
|
||||
f.puts %Q[#include <mruby/irep.h>]
|
||||
f.puts %Q[#include <mruby/proc.h>]
|
||||
f.puts %Q[#include <mruby/variable.h>]
|
||||
f.puts %Q[#include <mruby/hash.h>] unless test_args.empty?
|
||||
end
|
||||
|
||||
@@ -26,7 +26,7 @@ module MRuby
|
||||
end
|
||||
|
||||
def instance
|
||||
@instance ||= new("#{MRUBY_CONFIG}.lock")
|
||||
@instance ||= new("#{MRUBY_ROOT}/build/#{MRUBY_TARGET}.lock")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -39,7 +39,7 @@ module MRuby
|
||||
end
|
||||
|
||||
def write
|
||||
locks = {"mruby_version" => mruby}
|
||||
locks = {"mruby" => mruby}
|
||||
locks["builds"] = @builds if @builds
|
||||
File.write(@filename, YAML.dump(locks))
|
||||
end
|
||||
|
||||
@@ -5,6 +5,9 @@ MRuby::GemBox.new do |conf|
|
||||
# Use standard IO/File class
|
||||
conf.gem :core => "mruby-io"
|
||||
|
||||
# Use standard IO/File class
|
||||
conf.gem :core => "mruby-socket"
|
||||
|
||||
# Use standard Array#pack, String#unpack methods
|
||||
conf.gem :core => "mruby-pack"
|
||||
|
||||
@@ -84,6 +87,9 @@ MRuby::GemBox.new do |conf|
|
||||
# Generate mruby-strip command
|
||||
conf.gem :core => "mruby-bin-strip"
|
||||
|
||||
# Generate mruby-config command
|
||||
conf.gem :core => "mruby-bin-config"
|
||||
|
||||
# Use Kernel module extension
|
||||
conf.gem :core => "mruby-kernel-ext"
|
||||
|
||||
|
||||
@@ -148,11 +148,11 @@ mrb_ary_slice_bang(mrb_state *mrb, mrb_value self)
|
||||
else {
|
||||
return mrb_nil_value();
|
||||
}
|
||||
case MRB_TT_FIXNUM:
|
||||
val = mrb_funcall(mrb, self, "delete_at", 1, index);
|
||||
case MRB_TT_INTEGER:
|
||||
val = mrb_funcall_id(mrb, self, MRB_SYM(delete_at), 1, index);
|
||||
return val;
|
||||
default:
|
||||
val = mrb_funcall(mrb, self, "delete_at", 1, index);
|
||||
val = mrb_funcall_id(mrb, self, MRB_SYM(delete_at), 1, index);
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -516,7 +516,7 @@ SRC
|
||||
tc << {:cmd=>'p a+1', :exp=>'$1 = 2'}
|
||||
tc << {:cmd=>'p 2-b', :exp=>'$2 = -3'}
|
||||
tc << {:cmd=>'p c * 3', :exp=>'$3 = 24'}
|
||||
tc << {:cmd=>'p a/b', :exp=>'$4 = 0.2'}
|
||||
tc << {:cmd=>'p a/b', :exp=>'$4 = 0'}
|
||||
tc << {:cmd=>'p c%b', :exp=>'$5 = 3'}
|
||||
tc << {:cmd=>'p 2**10', :exp=>'$6 = 1024'}
|
||||
tc << {:cmd=>'p ~3', :exp=>'$7 = -4'}
|
||||
@@ -614,13 +614,13 @@ SRC
|
||||
tc << {:cmd=>'p a+=9', :exp=>'$1 = 10'}
|
||||
tc << {:cmd=>'p b-=c', :exp=>'$2 = 15'}
|
||||
tc << {:cmd=>'p bar*=2', :exp=>'$3 = "barbar"'}
|
||||
tc << {:cmd=>'p a/=4', :exp=>'$4 = 2.5'}
|
||||
tc << {:cmd=>'p a/=4', :exp=>'$4 = 2'}
|
||||
tc << {:cmd=>'p c%=4', :exp=>'$5 = 2'}
|
||||
|
||||
tc << {:cmd=>'p b&=0b0101', :exp=>'$6 = 5'}
|
||||
tc << {:cmd=>'p c|=0x10', :exp=>'$7 = 18'}
|
||||
|
||||
tc << {:cmd=>'p "#{a} #{b} #{c}"', :exp=>'$8 = "2.5 5 18"'}
|
||||
tc << {:cmd=>'p "#{a} #{b} #{c}"', :exp=>'$8 = "2 5 18"'}
|
||||
tc << {:cmd=>'p "#{foo}#{bar}#{baz}"', :exp=>'$9 = "foobarbarbaz"'}
|
||||
|
||||
tc << {:cmd=>'p a,b,c=[10,20,30]',:exp=>'$10 = [10, 20, 30]'}
|
||||
@@ -682,13 +682,13 @@ SRC
|
||||
tc << {:cmd=>'p a+=9', :exp=>'$1 = 10'}
|
||||
tc << {:cmd=>'p b-=c', :exp=>'$2 = 15'}
|
||||
tc << {:cmd=>'p bar*=2', :exp=>'$3 = "barbar"'}
|
||||
tc << {:cmd=>'p a/=4', :exp=>'$4 = 2.5'}
|
||||
tc << {:cmd=>'p a/=4', :exp=>'$4 = 2'}
|
||||
tc << {:cmd=>'p c%=4', :exp=>'$5 = 2'}
|
||||
|
||||
tc << {:cmd=>'p b&=0b0101', :exp=>'$6 = 5'}
|
||||
tc << {:cmd=>'p c|=0x10', :exp=>'$7 = 18'}
|
||||
|
||||
tc << {:cmd=>'p "#{a} #{b} #{c}"', :exp=>'$8 = "2.5 5 18"'}
|
||||
tc << {:cmd=>'p "#{a} #{b} #{c}"', :exp=>'$8 = "2 5 18"'}
|
||||
tc << {:cmd=>'p "#{foo}#{bar}#{baz}"', :exp=>'$9 = "foobarbarbaz"'}
|
||||
|
||||
tc << {:cmd=>'p a,b,c=[10,20,30]',:exp=>'$10 = [10, 20, 30]'}
|
||||
|
||||
@@ -84,7 +84,7 @@ free_breakpoint(mrb_state *mrb, mrb_debug_breakpoint *bp)
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
check_file_lineno(mrb_state *mrb, struct mrb_irep *irep, const char *file, uint16_t lineno)
|
||||
check_file_lineno(mrb_state *mrb, const struct mrb_irep *irep, const char *file, uint16_t lineno)
|
||||
{
|
||||
mrb_irep_debug_info_file *info_file;
|
||||
uint16_t result = 0;
|
||||
@@ -151,7 +151,7 @@ compare_break_method(mrb_state *mrb, mrb_debug_breakpoint *bp, struct RClass *cl
|
||||
}
|
||||
|
||||
sc = mrb_class_get(mrb, method_p->class_name);
|
||||
ssym = mrb_symbol(mrb_check_intern_cstr(mrb, method_p->method_name));
|
||||
ssym = mrb_intern_check_cstr(mrb, method_p->method_name);
|
||||
m = mrb_method_search_vm(mrb, &sc, ssym);
|
||||
if (MRB_METHOD_UNDEF_P(m)) {
|
||||
return MRB_DEBUG_OK;
|
||||
@@ -428,7 +428,7 @@ mrb_debug_disable_break_all(mrb_state *mrb, mrb_debug_context *dbg)
|
||||
}
|
||||
|
||||
static mrb_bool
|
||||
check_start_pc_for_line(mrb_state *mrb, mrb_irep *irep, const mrb_code *pc, uint16_t line)
|
||||
check_start_pc_for_line(mrb_state *mrb, const mrb_irep *irep, const mrb_code *pc, uint16_t line)
|
||||
{
|
||||
if (pc > irep->iseq) {
|
||||
if (line == mrb_debug_get_line(mrb, irep, pc - irep->iseq - 1)) {
|
||||
|
||||
@@ -33,7 +33,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 *, 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;
|
||||
@@ -67,7 +67,7 @@ mrb_debug_eval(mrb_state *mrb, mrb_debug_context *dbg, const char *expr, size_t
|
||||
|
||||
recv = dbg->regs[0];
|
||||
|
||||
v = mrb_funcall(mrb, recv, "instance_eval", 1, ruby_code);
|
||||
v = mrb_funcall_id(mrb, recv, MRB_SYM(instance_eval), 1, ruby_code);
|
||||
}
|
||||
|
||||
if (exc) {
|
||||
|
||||
@@ -504,7 +504,7 @@ get_and_parse_command(mrb_state *mrb, mrdb_state *mrdb)
|
||||
}
|
||||
|
||||
static int32_t
|
||||
check_method_breakpoint(mrb_state *mrb, mrb_irep *irep, const mrb_code *pc, mrb_value *regs)
|
||||
check_method_breakpoint(mrb_state *mrb, const mrb_irep *irep, const mrb_code *pc, mrb_value *regs)
|
||||
{
|
||||
struct RClass* c;
|
||||
mrb_sym sym;
|
||||
@@ -545,7 +545,7 @@ check_method_breakpoint(mrb_state *mrb, mrb_irep *irep, const mrb_code *pc, mrb_
|
||||
}
|
||||
|
||||
static void
|
||||
mrb_code_fetch_hook(mrb_state *mrb, mrb_irep *irep, const mrb_code *pc, mrb_value *regs)
|
||||
mrb_code_fetch_hook(mrb_state *mrb, const mrb_irep *irep, const mrb_code *pc, mrb_value *regs)
|
||||
{
|
||||
const char *file;
|
||||
int32_t line;
|
||||
|
||||
@@ -103,8 +103,8 @@ typedef struct mrb_debug_breakpoint {
|
||||
} mrb_debug_breakpoint;
|
||||
|
||||
typedef struct mrb_debug_context {
|
||||
struct mrb_irep *root_irep;
|
||||
struct mrb_irep *irep;
|
||||
const struct mrb_irep *root_irep;
|
||||
const struct mrb_irep *irep;
|
||||
const mrb_code *pc;
|
||||
mrb_value *regs;
|
||||
|
||||
|
||||
@@ -32,3 +32,20 @@ EOS
|
||||
o, _ = Open3.capture2("bin/mirb -r #{lib.path}", :stdin_data => "Hoge.new.hoge\n")
|
||||
assert_true o.include?('=> :hoge')
|
||||
end
|
||||
|
||||
assert('top level local variables are in file scope') do
|
||||
lib = Tempfile.new('lib.rb')
|
||||
lib.write <<-TESTLIB
|
||||
a = 1
|
||||
A = -> { a }
|
||||
TESTLIB
|
||||
lib.flush
|
||||
|
||||
o, _ = Open3.capture2("bin/mirb -r #{lib.path}", :stdin_data => <<-TESTCODE)
|
||||
a
|
||||
a = 5
|
||||
A.call
|
||||
TESTCODE
|
||||
|
||||
assert_kind_of Integer, o =~ /\bundefined method 'a' \(NoMethodError\).*=> 5\b.*=> 1\b/m
|
||||
end
|
||||
|
||||
@@ -104,13 +104,13 @@ p(mrb_state *mrb, mrb_value obj, int prompt)
|
||||
mrb_value val;
|
||||
char* msg;
|
||||
|
||||
val = mrb_funcall(mrb, obj, "inspect", 0);
|
||||
val = mrb_funcall_id(mrb, obj, MRB_SYM(inspect), 0);
|
||||
if (prompt) {
|
||||
if (!mrb->exc) {
|
||||
fputs(" => ", stdout);
|
||||
}
|
||||
else {
|
||||
val = mrb_funcall(mrb, mrb_obj_value(mrb->exc), "inspect", 0);
|
||||
val = mrb_funcall_id(mrb, mrb_obj_value(mrb->exc), MRB_SYM(inspect), 0);
|
||||
}
|
||||
}
|
||||
if (!mrb_string_p(val)) {
|
||||
@@ -495,12 +495,9 @@ main(int argc, char **argv)
|
||||
|
||||
cxt = mrbc_context_new(mrb);
|
||||
|
||||
#ifndef DISABLE_MIRB_UNDERSCORE
|
||||
decl_lv_underscore(mrb, cxt);
|
||||
#endif
|
||||
|
||||
/* 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]);
|
||||
@@ -509,8 +506,16 @@ main(int argc, char **argv)
|
||||
}
|
||||
mrb_load_file_cxt(mrb, lfp, cxt);
|
||||
fclose(lfp);
|
||||
e = mrb->c->cibase->env;
|
||||
mrb->c->cibase->env = NULL;
|
||||
mrb_env_unshare(mrb, e);
|
||||
mrbc_cleanup_local_variables(mrb, cxt);
|
||||
}
|
||||
|
||||
#ifndef DISABLE_MIRB_UNDERSCORE
|
||||
decl_lv_underscore(mrb, cxt);
|
||||
#endif
|
||||
|
||||
cxt->capture_errors = TRUE;
|
||||
cxt->lineno = 1;
|
||||
mrbc_filename(mrb, cxt, "(mirb)");
|
||||
@@ -520,10 +525,7 @@ main(int argc, char **argv)
|
||||
|
||||
while (TRUE) {
|
||||
char *utf8;
|
||||
struct mrb_jmpbuf c_jmp;
|
||||
|
||||
MRB_TRY(&c_jmp);
|
||||
mrb->jmp = &c_jmp;
|
||||
if (args.rfp) {
|
||||
if (fgets(last_code_line, sizeof(last_code_line)-1, args.rfp) != NULL)
|
||||
goto done;
|
||||
@@ -667,7 +669,7 @@ main(int argc, char **argv)
|
||||
}
|
||||
else {
|
||||
/* no */
|
||||
if (!mrb_respond_to(mrb, result, mrb_intern_lit(mrb, "inspect"))){
|
||||
if (!mrb_respond_to(mrb, result, MRB_SYM(inspect))){
|
||||
result = mrb_any_to_s(mrb, result);
|
||||
}
|
||||
p(mrb, result, 1);
|
||||
@@ -682,11 +684,6 @@ main(int argc, char **argv)
|
||||
}
|
||||
mrb_parser_free(parser);
|
||||
cxt->lineno++;
|
||||
MRB_CATCH(&c_jmp) {
|
||||
p(mrb, mrb_obj_value(mrb->exc), 0);
|
||||
mrb->exc = 0;
|
||||
}
|
||||
MRB_END_EXC(&c_jmp);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_READLINE
|
||||
|
||||
@@ -20,6 +20,7 @@ struct mrbc_args {
|
||||
const char *prog;
|
||||
const char *outfile;
|
||||
const char *initname;
|
||||
mrb_bool dump_struct : 1;
|
||||
mrb_bool check_syntax : 1;
|
||||
mrb_bool verbose : 1;
|
||||
mrb_bool remove_lv : 1;
|
||||
@@ -32,10 +33,11 @@ usage(const char *name)
|
||||
static const char *const usage_msg[] = {
|
||||
"switches:",
|
||||
"-c check syntax only",
|
||||
"-o<outfile> place the output into <outfile>",
|
||||
"-o<outfile> place the output into <outfile>; required for multi-files",
|
||||
"-v print version number, then turn on verbose mode",
|
||||
"-g produce debugging information",
|
||||
"-B<symbol> binary <symbol> output in C language format",
|
||||
"-S dump C struct (requires -B)",
|
||||
"--remove-lv remove local variables",
|
||||
"--verbose run at verbose mode",
|
||||
"--version print the version",
|
||||
@@ -44,7 +46,7 @@ usage(const char *name)
|
||||
};
|
||||
const char *const *p = usage_msg;
|
||||
|
||||
printf("Usage: %s [switches] programfile\n", name);
|
||||
printf("Usage: %s [switches] programfile...\n", name);
|
||||
while (*p)
|
||||
printf(" %s\n", *p++);
|
||||
}
|
||||
@@ -105,6 +107,9 @@ parse_args(mrb_state *mrb, int argc, char **argv, struct mrbc_args *args)
|
||||
args->outfile = get_outfilename(mrb, argv[i] + 2, "");
|
||||
}
|
||||
break;
|
||||
case 'S':
|
||||
args->dump_struct = TRUE;
|
||||
break;
|
||||
case 'B':
|
||||
if (argv[i][2] == '\0' && argv[i+1]) {
|
||||
i++;
|
||||
@@ -238,13 +243,18 @@ static int
|
||||
dump_file(mrb_state *mrb, FILE *wfp, const char *outfile, struct RProc *proc, struct mrbc_args *args)
|
||||
{
|
||||
int n = MRB_DUMP_OK;
|
||||
mrb_irep *irep = proc->body.irep;
|
||||
const mrb_irep *irep = proc->body.irep;
|
||||
|
||||
if (args->remove_lv) {
|
||||
mrb_irep_remove_lv(mrb, irep);
|
||||
mrb_irep_remove_lv(mrb, (mrb_irep*)irep);
|
||||
}
|
||||
if (args->initname) {
|
||||
n = mrb_dump_irep_cfunc(mrb, irep, args->flags, wfp, args->initname);
|
||||
if (args->dump_struct) {
|
||||
n = mrb_dump_irep_cstruct(mrb, irep, args->flags, wfp, args->initname);
|
||||
}
|
||||
else {
|
||||
n = mrb_dump_irep_cfunc(mrb, irep, args->flags, wfp, args->initname);
|
||||
}
|
||||
if (n == MRB_DUMP_INVALID_ARGUMENT) {
|
||||
fprintf(stderr, "%s: invalid C language symbol name\n", args->initname);
|
||||
}
|
||||
|
||||
@@ -162,3 +162,24 @@ assert('codegen error') do
|
||||
code = "def f(#{(1..100).map{|n| "a#{n}"} * ","}); end"
|
||||
assert_mruby("", /\Acodegen error:.*\n\z/, false, ["-e", code])
|
||||
end
|
||||
|
||||
assert('top level local variables are in file scope') do
|
||||
arb, amrb = Tempfile.new('a.rb'), Tempfile.new('a.mrb')
|
||||
brb, bmrb = Tempfile.new('b.rb'), Tempfile.new('b.mrb')
|
||||
crb, cmrb = Tempfile.new('c.rb'), Tempfile.new('c.mrb')
|
||||
drb, dmrb = Tempfile.new('d.rb'), Tempfile.new('d.mrb')
|
||||
|
||||
File.write arb.path, 'a = 1'
|
||||
system "#{cmd('mrbc')} -g -o #{amrb.path} #{arb.path}"
|
||||
File.write brb.path, 'p a'
|
||||
system "#{cmd('mrbc')} -g -o #{bmrb.path} #{brb.path}"
|
||||
assert_mruby("", /:1: undefined method 'a' \(NoMethodError\)\n\z/, false, ["-r", arb.path, brb.path])
|
||||
assert_mruby("", /:1: undefined method 'a' \(NoMethodError\)\n\z/, false, ["-b", "-r", amrb.path, bmrb.path])
|
||||
|
||||
File.write crb.path, 'a, b, c = 1, 2, 3; A = -> { b = -2; [a, b, c] }'
|
||||
system "#{cmd('mrbc')} -g -o #{cmrb.path} #{crb.path}"
|
||||
File.write drb.path, 'a, b = 5, 6; p A.call; p a, b'
|
||||
system "#{cmd('mrbc')} -g -o #{dmrb.path} #{drb.path}"
|
||||
assert_mruby("[1, -2, 3]\n5\n6\n", "", true, ["-r", crb.path, drb.path])
|
||||
assert_mruby("[1, -2, 3]\n5\n6\n", "", true, ["-b", "-r", cmrb.path, dmrb.path])
|
||||
end
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <mruby/compile.h>
|
||||
#include <mruby/dump.h>
|
||||
#include <mruby/variable.h>
|
||||
#include <mruby/proc.h>
|
||||
|
||||
struct _args {
|
||||
FILE *rfp;
|
||||
@@ -307,6 +308,7 @@ main(int argc, char **argv)
|
||||
|
||||
/* Load libraries */
|
||||
for (i = 0; i < args.libc; i++) {
|
||||
struct REnv *e;
|
||||
FILE *lfp = fopen(args.libv[i], args.mrbfile ? "rb" : "r");
|
||||
if (lfp == NULL) {
|
||||
fprintf(stderr, "%s: Cannot open library file: %s\n", *argv, args.libv[i]);
|
||||
@@ -321,6 +323,10 @@ main(int argc, char **argv)
|
||||
v = mrb_load_file_cxt(mrb, lfp, c);
|
||||
}
|
||||
fclose(lfp);
|
||||
e = mrb->c->cibase->env;
|
||||
mrb->c->cibase->env = NULL;
|
||||
mrb_env_unshare(mrb, e);
|
||||
mrbc_cleanup_local_variables(mrb, c);
|
||||
}
|
||||
|
||||
/* Load program */
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
MRuby::Gem::Specification.new('mruby-catch') do |spec|
|
||||
spec.license = 'MIT'
|
||||
spec.author = 'mruby developers'
|
||||
spec.summary = 'Catch / Throw non-local Jump'
|
||||
end
|
||||
@@ -0,0 +1,27 @@
|
||||
class ThrowCatchJump < Exception
|
||||
def initialize(tag, val)
|
||||
@tag = tag
|
||||
@val = val
|
||||
super("uncaught throw :#{tag}")
|
||||
end
|
||||
def _tag
|
||||
@tag
|
||||
end
|
||||
def _val
|
||||
@val
|
||||
end
|
||||
end
|
||||
|
||||
module Kernel
|
||||
def catch(tag, &block)
|
||||
block.call(tag)
|
||||
rescue ThrowCatchJump => e
|
||||
unless e._tag == tag
|
||||
raise e
|
||||
end
|
||||
return e._val
|
||||
end
|
||||
def throw(tag, val=nil)
|
||||
raise ThrowCatchJump.new(tag, val)
|
||||
end
|
||||
end
|
||||
@@ -5,13 +5,13 @@
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <mruby.h>
|
||||
#include <mruby/compile.h>
|
||||
#include <mruby/proc.h>
|
||||
#include <mruby/dump.h>
|
||||
#include <mruby/numeric.h>
|
||||
#include <mruby/string.h>
|
||||
#include <mruby/debug.h>
|
||||
@@ -40,7 +40,6 @@ enum looptype {
|
||||
struct loopinfo {
|
||||
enum looptype type;
|
||||
int pc0, pc1, pc2, pc3, acc;
|
||||
int ensure_level;
|
||||
struct loopinfo *prev;
|
||||
};
|
||||
|
||||
@@ -61,7 +60,6 @@ typedef struct scope {
|
||||
mrb_bool mscope:1;
|
||||
|
||||
struct loopinfo *loop;
|
||||
int ensure_level;
|
||||
mrb_sym filename_sym;
|
||||
uint16_t lineno;
|
||||
|
||||
@@ -70,6 +68,10 @@ typedef struct scope {
|
||||
uint32_t icapa;
|
||||
|
||||
mrb_irep *irep;
|
||||
mrb_pool_value *pool;
|
||||
mrb_sym *syms;
|
||||
mrb_irep **reps;
|
||||
struct mrb_irep_catch_handler *catch_table;
|
||||
uint32_t pcapa, scapa, rcapa;
|
||||
|
||||
uint16_t nlocals;
|
||||
@@ -89,6 +91,15 @@ static struct loopinfo *loop_push(codegen_scope *s, enum looptype t);
|
||||
static void loop_break(codegen_scope *s, node *tree);
|
||||
static void loop_pop(codegen_scope *s, int val);
|
||||
|
||||
/*
|
||||
* The search for catch handlers starts at the end of the table in mrb_vm_run().
|
||||
* Therefore, the next handler to be added must meet one of the following conditions.
|
||||
* - Larger start position
|
||||
* - Same start position but smaller end position
|
||||
*/
|
||||
static int catch_handler_new(codegen_scope *s);
|
||||
static void catch_handler_set(codegen_scope *s, int ent, enum mrb_catch_type type, uint32_t begin, uint32_t end, uint32_t target);
|
||||
|
||||
static void gen_assignment(codegen_scope *s, node *tree, int sp, int val);
|
||||
static void gen_vmassignment(codegen_scope *s, node *tree, int rhs, int val);
|
||||
|
||||
@@ -98,10 +109,22 @@ static void raise_error(codegen_scope *s, const char *msg);
|
||||
static void
|
||||
codegen_error(codegen_scope *s, const char *message)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!s) return;
|
||||
while (s->prev) {
|
||||
codegen_scope *tmp = s->prev;
|
||||
mrb_free(s->mrb, s->iseq);
|
||||
mrb_free(s->mrb, s->pool);
|
||||
mrb_free(s->mrb, s->syms);
|
||||
if (s->reps) {
|
||||
/* copied from mrb_irep_free() in state.c */
|
||||
for (i=0; i<s->irep->rlen; i++) {
|
||||
if (s->reps[i])
|
||||
mrb_irep_decref(s->mrb, (mrb_irep*)s->reps[i]);
|
||||
}
|
||||
mrb_free(s->mrb, s->reps);
|
||||
}
|
||||
mrb_free(s->mrb, s->lines);
|
||||
mrb_pool_close(s->mpool);
|
||||
s = tmp;
|
||||
@@ -203,9 +226,7 @@ genop_1(codegen_scope *s, mrb_code i, uint16_t a)
|
||||
{
|
||||
s->lastpc = s->pc;
|
||||
if (a > 0xff) {
|
||||
gen_B(s, OP_EXT1);
|
||||
gen_B(s, i);
|
||||
gen_S(s, a);
|
||||
codegen_error(s, "too big operand");
|
||||
}
|
||||
else {
|
||||
gen_B(s, i);
|
||||
@@ -217,23 +238,8 @@ static void
|
||||
genop_2(codegen_scope *s, mrb_code i, uint16_t a, uint16_t b)
|
||||
{
|
||||
s->lastpc = s->pc;
|
||||
if (a > 0xff && b > 0xff) {
|
||||
gen_B(s, OP_EXT3);
|
||||
gen_B(s, i);
|
||||
gen_S(s, a);
|
||||
gen_S(s, b);
|
||||
}
|
||||
else if (b > 0xff) {
|
||||
gen_B(s, OP_EXT2);
|
||||
gen_B(s, i);
|
||||
gen_B(s, (uint8_t)a);
|
||||
gen_S(s, b);
|
||||
}
|
||||
else if (a > 0xff) {
|
||||
gen_B(s, OP_EXT1);
|
||||
gen_B(s, i);
|
||||
gen_S(s, a);
|
||||
gen_B(s, (uint8_t)b);
|
||||
if (a > 0xff || b > 0xff) {
|
||||
codegen_error(s, "too big operand");
|
||||
}
|
||||
else {
|
||||
gen_B(s, i);
|
||||
@@ -295,32 +301,6 @@ mrb_decode_insn(const mrb_code *pc)
|
||||
#define OPCODE(i,x) case OP_ ## i: FETCH_ ## x (); break;
|
||||
#include "mruby/ops.h"
|
||||
#undef OPCODE
|
||||
}
|
||||
switch (insn) {
|
||||
case OP_EXT1:
|
||||
insn = READ_B();
|
||||
switch (insn) {
|
||||
#define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _1 (); break;
|
||||
#include "mruby/ops.h"
|
||||
#undef OPCODE
|
||||
}
|
||||
break;
|
||||
case OP_EXT2:
|
||||
insn = READ_B();
|
||||
switch (insn) {
|
||||
#define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _2 (); break;
|
||||
#include "mruby/ops.h"
|
||||
#undef OPCODE
|
||||
}
|
||||
break;
|
||||
case OP_EXT3:
|
||||
insn = READ_B();
|
||||
switch (insn) {
|
||||
#define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _3 (); break;
|
||||
#include "mruby/ops.h"
|
||||
#undef OPCODE
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -377,11 +357,8 @@ genjmp2(codegen_scope *s, mrb_code i, uint16_t a, int pc, int val)
|
||||
|
||||
s->lastpc = s->pc;
|
||||
if (a > 0xff) {
|
||||
gen_B(s, OP_EXT1);
|
||||
gen_B(s, i);
|
||||
gen_S(s, a);
|
||||
pos = s->pc;
|
||||
gen_S(s, pc);
|
||||
codegen_error(s, "too big operand");
|
||||
pos = 0;
|
||||
}
|
||||
else {
|
||||
gen_B(s, i);
|
||||
@@ -539,37 +516,46 @@ static inline int
|
||||
new_lit(codegen_scope *s, mrb_value val)
|
||||
{
|
||||
int i;
|
||||
mrb_value *pv;
|
||||
mrb_pool_value *pv;
|
||||
|
||||
switch (mrb_type(val)) {
|
||||
case MRB_TT_STRING:
|
||||
for (i=0; i<s->irep->plen; i++) {
|
||||
mrb_int len;
|
||||
pv = &s->irep->pool[i];
|
||||
|
||||
if (!mrb_string_p(*pv)) continue;
|
||||
if ((len = RSTRING_LEN(*pv)) != RSTRING_LEN(val)) continue;
|
||||
if (memcmp(RSTRING_PTR(*pv), RSTRING_PTR(val), len) == 0)
|
||||
pv = &s->pool[i];
|
||||
if (pv->tt & IREP_TT_NFLAG) continue;
|
||||
len = pv->tt>>2;
|
||||
if (RSTRING_LEN(val) != len) continue;
|
||||
if (memcmp(pv->u.str, RSTRING_PTR(val), len) == 0)
|
||||
return i;
|
||||
}
|
||||
break;
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
case MRB_TT_FLOAT:
|
||||
for (i=0; i<s->irep->plen; i++) {
|
||||
mrb_float f1, f2;
|
||||
pv = &s->irep->pool[i];
|
||||
if (!mrb_float_p(*pv)) continue;
|
||||
f1 = mrb_float(*pv);
|
||||
pv = &s->pool[i];
|
||||
if (pv->tt != IREP_TT_FLOAT) continue;
|
||||
pv = &s->pool[i];
|
||||
f1 = pv->u.f;
|
||||
f2 = mrb_float(val);
|
||||
if (f1 == f2 && !signbit(f1) == !signbit(f2)) return i;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case MRB_TT_FIXNUM:
|
||||
case MRB_TT_INTEGER:
|
||||
for (i=0; i<s->irep->plen; i++) {
|
||||
pv = &s->irep->pool[i];
|
||||
if (!mrb_fixnum_p(*pv)) continue;
|
||||
if (mrb_fixnum(*pv) == mrb_fixnum(val)) return i;
|
||||
mrb_int v = mrb_integer(val);
|
||||
pv = &s->pool[i];
|
||||
if (pv->tt == IREP_TT_INT32) {
|
||||
if (v == pv->u.i32) return i;
|
||||
}
|
||||
#ifdef MRB_64BIT
|
||||
else if (pv->tt == IREP_TT_INT64) {
|
||||
if (v == pv->u.i64) return i;
|
||||
}
|
||||
continue;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -579,26 +565,43 @@ new_lit(codegen_scope *s, mrb_value val)
|
||||
|
||||
if (s->irep->plen == s->pcapa) {
|
||||
s->pcapa *= 2;
|
||||
s->irep->pool = (mrb_value *)codegen_realloc(s, s->irep->pool, sizeof(mrb_value)*s->pcapa);
|
||||
s->pool = (mrb_pool_value*)codegen_realloc(s, s->pool, sizeof(mrb_pool_value)*s->pcapa);
|
||||
}
|
||||
|
||||
pv = &s->irep->pool[s->irep->plen];
|
||||
pv = &s->pool[s->irep->plen];
|
||||
i = s->irep->plen++;
|
||||
|
||||
switch (mrb_type(val)) {
|
||||
case MRB_TT_STRING:
|
||||
*pv = mrb_str_pool(s->mrb, RSTRING_PTR(val), RSTRING_LEN(val), RSTR_NOFREE_P(RSTRING(val)));
|
||||
if (RSTR_NOFREE_P(RSTRING(val))) {
|
||||
pv->tt = (uint32_t)(RSTRING_LEN(val)<<2) | IREP_TT_SSTR;
|
||||
pv->u.str = RSTRING_PTR(val);
|
||||
}
|
||||
else {
|
||||
char *p;
|
||||
mrb_int len = RSTRING_LEN(val);
|
||||
pv->tt = (uint32_t)(len<<2) | IREP_TT_STR;
|
||||
p = (char*)codegen_realloc(s, NULL, len+1);
|
||||
memcpy(p, RSTRING_PTR(val), len);
|
||||
p[len] = '\0';
|
||||
pv->u.str = p;
|
||||
}
|
||||
break;
|
||||
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
case MRB_TT_FLOAT:
|
||||
#ifdef MRB_WORD_BOXING
|
||||
*pv = mrb_float_pool(s->mrb, mrb_float(val));
|
||||
pv->tt = IREP_TT_FLOAT;
|
||||
pv->u.f = mrb_float(val);
|
||||
break;
|
||||
#endif
|
||||
case MRB_TT_INTEGER:
|
||||
#ifdef MRB_INT64
|
||||
pv->tt = IREP_TT_INT64;
|
||||
pv->u.i64 = mrb_integer(val);
|
||||
#else
|
||||
pv->tt = IREP_TT_INT32;
|
||||
pv->u.i32 = mrb_integer(val);
|
||||
#endif
|
||||
case MRB_TT_FIXNUM:
|
||||
*pv = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -620,13 +623,13 @@ new_sym(codegen_scope *s, mrb_sym sym)
|
||||
|
||||
len = s->irep->slen;
|
||||
for (i=0; i<len; i++) {
|
||||
if (s->irep->syms[i] == sym) return i;
|
||||
if (s->syms[i] == sym) return i;
|
||||
}
|
||||
if (s->irep->slen >= s->scapa) {
|
||||
s->scapa *= 2;
|
||||
s->irep->syms = (mrb_sym*)codegen_realloc(s, s->irep->syms, sizeof(mrb_sym)*s->scapa);
|
||||
s->syms = (mrb_sym*)codegen_realloc(s, s->syms, sizeof(mrb_sym)*s->scapa);
|
||||
}
|
||||
s->irep->syms[s->irep->slen] = sym;
|
||||
s->syms[s->irep->slen] = sym;
|
||||
return s->irep->slen++;
|
||||
}
|
||||
|
||||
@@ -665,7 +668,7 @@ lv_idx(codegen_scope *s, mrb_sym id)
|
||||
static int
|
||||
search_upvar(codegen_scope *s, mrb_sym id, int *idx)
|
||||
{
|
||||
struct RProc *u;
|
||||
const struct RProc *u;
|
||||
int lv = 0;
|
||||
codegen_scope *up = s->prev;
|
||||
|
||||
@@ -681,12 +684,14 @@ search_upvar(codegen_scope *s, mrb_sym id, int *idx)
|
||||
if (lv < 1) lv = 1;
|
||||
u = s->parser->upper;
|
||||
while (u && !MRB_PROC_CFUNC_P(u)) {
|
||||
struct mrb_irep *ir = u->body.irep;
|
||||
const struct mrb_irep *ir = u->body.irep;
|
||||
uint_fast16_t n = ir->nlocals;
|
||||
const struct mrb_locals *v = ir->lv;
|
||||
for (; n > 1; n --, v ++) {
|
||||
if (v->name == id) {
|
||||
*idx = v->r;
|
||||
int i;
|
||||
|
||||
const mrb_sym *v = ir->lv;
|
||||
for (i=1; n > 1; n--, v++, i++) {
|
||||
if (*v == id) {
|
||||
*idx = i;
|
||||
return lv - 1;
|
||||
}
|
||||
}
|
||||
@@ -737,7 +742,7 @@ for_body(codegen_scope *s, node *tree)
|
||||
genop_2(s, OP_BLOCK, cursp(), s->irep->rlen-1);
|
||||
push();pop(); /* space for a block */
|
||||
pop();
|
||||
idx = new_sym(s, mrb_intern_lit(s->mrb, "each"));
|
||||
idx = new_sym(s, MRB_SYM(each));
|
||||
genop_3(s, OP_SENDB, cursp(), idx, 0);
|
||||
}
|
||||
|
||||
@@ -1325,7 +1330,7 @@ raise_error(codegen_scope *s, const char *msg)
|
||||
genop_1(s, OP_ERR, idx);
|
||||
}
|
||||
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
static double
|
||||
readint_float(codegen_scope *s, const char *p, int base)
|
||||
{
|
||||
@@ -1458,16 +1463,19 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
{
|
||||
int noexc, exend, pos1, pos2, tmp;
|
||||
struct loopinfo *lp;
|
||||
int catch_entry, begin, end;
|
||||
|
||||
if (tree->car == NULL) goto exit;
|
||||
lp = loop_push(s, LOOP_BEGIN);
|
||||
lp->pc0 = new_label(s);
|
||||
lp->pc1 = genjmp(s, OP_ONERR, 0);
|
||||
catch_entry = catch_handler_new(s);
|
||||
begin = s->pc;
|
||||
codegen(s, tree->car, VAL);
|
||||
pop();
|
||||
lp->type = LOOP_RESCUE;
|
||||
end = s->pc;
|
||||
noexc = genjmp(s, OP_JMP, 0);
|
||||
dispatch(s, lp->pc1);
|
||||
catch_handler_set(s, catch_entry, MRB_CATCH_RESCUE, begin, end, s->pc);
|
||||
tree = tree->cdr;
|
||||
exend = 0;
|
||||
pos1 = 0;
|
||||
@@ -1489,14 +1497,14 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
gen_move(s, cursp(), exc, 0);
|
||||
push_n(2); pop_n(2); /* space for one arg and a block */
|
||||
pop();
|
||||
genop_3(s, OP_SEND, cursp(), new_sym(s, mrb_intern_lit(s->mrb, "__case_eqq")), 1);
|
||||
genop_3(s, OP_SEND, cursp(), new_sym(s, MRB_SYM(__case_eqq)), 1);
|
||||
}
|
||||
else {
|
||||
if (n4) {
|
||||
codegen(s, n4->car, VAL);
|
||||
}
|
||||
else {
|
||||
genop_2(s, OP_GETCONST, cursp(), new_sym(s, mrb_intern_lit(s->mrb, "StandardError")));
|
||||
genop_2(s, OP_GETCONST, cursp(), new_sym(s, MRB_SYM(StandardError)));
|
||||
push();
|
||||
}
|
||||
pop();
|
||||
@@ -1526,13 +1534,12 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
}
|
||||
if (pos1) {
|
||||
dispatch(s, pos1);
|
||||
genop_1(s, OP_RAISE, exc);
|
||||
genop_1(s, OP_RAISEIF, exc);
|
||||
}
|
||||
}
|
||||
pop();
|
||||
tree = tree->cdr;
|
||||
dispatch(s, noexc);
|
||||
genop_1(s, OP_POPERR, 1);
|
||||
if (tree->car) {
|
||||
codegen(s, tree->car, val);
|
||||
}
|
||||
@@ -1548,14 +1555,22 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
if (!tree->cdr || !tree->cdr->cdr ||
|
||||
(nint(tree->cdr->cdr->car) == NODE_BEGIN &&
|
||||
tree->cdr->cdr->cdr)) {
|
||||
int catch_entry, begin, end, target;
|
||||
int idx;
|
||||
|
||||
s->ensure_level++;
|
||||
idx = scope_body(s, tree->cdr, NOVAL);
|
||||
genop_1(s, OP_EPUSH, idx);
|
||||
catch_entry = catch_handler_new(s);
|
||||
begin = s->pc;
|
||||
codegen(s, tree->car, val);
|
||||
s->ensure_level--;
|
||||
genop_1(s, OP_EPOP, 1);
|
||||
end = target = s->pc;
|
||||
push();
|
||||
idx = cursp();
|
||||
genop_1(s, OP_EXCEPT, idx);
|
||||
push();
|
||||
codegen(s, tree->cdr->cdr, NOVAL);
|
||||
pop();
|
||||
genop_1(s, OP_RAISEIF, idx);
|
||||
pop();
|
||||
catch_handler_set(s, catch_entry, MRB_CATCH_ENSURE, begin, end, target);
|
||||
}
|
||||
else { /* empty ensure ignored */
|
||||
codegen(s, tree->car, val);
|
||||
@@ -1603,7 +1618,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
{
|
||||
node *n = tree->car->cdr;
|
||||
mrb_sym mid = nsym(n->cdr->car);
|
||||
mrb_sym mnil = mrb_intern_lit(s->mrb, "nil?");
|
||||
mrb_sym mnil = MRB_QSYM(nil_p);
|
||||
if (mid == mnil && n->cdr->cdr->car == NULL) {
|
||||
nil_p = TRUE;
|
||||
codegen(s, n->car, VAL);
|
||||
@@ -1739,10 +1754,10 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
gen_move(s, cursp(), head, 0);
|
||||
push(); push(); pop(); pop(); pop();
|
||||
if (nint(n->car->car) == NODE_SPLAT) {
|
||||
genop_3(s, OP_SEND, cursp(), new_sym(s, mrb_intern_lit(s->mrb, "__case_eqq")), 1);
|
||||
genop_3(s, OP_SEND, cursp(), new_sym(s, MRB_SYM(__case_eqq)), 1);
|
||||
}
|
||||
else {
|
||||
genop_3(s, OP_SEND, cursp(), new_sym(s, mrb_intern_lit(s->mrb, "===")), 1);
|
||||
genop_3(s, OP_SEND, cursp(), new_sym(s, MRB_QSYM(eqq)), 1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -2017,18 +2032,20 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
if ((len == 2 && name[0] == '|' && name[1] == '|') &&
|
||||
(nint(tree->car->car) == NODE_CONST ||
|
||||
nint(tree->car->car) == NODE_CVAR)) {
|
||||
int onerr, noexc, exc;
|
||||
int catch_entry, begin, end;
|
||||
int noexc, exc;
|
||||
struct loopinfo *lp;
|
||||
|
||||
onerr = genjmp(s, OP_ONERR, 0);
|
||||
lp = loop_push(s, LOOP_BEGIN);
|
||||
lp->pc1 = onerr;
|
||||
lp->pc0 = new_label(s);
|
||||
catch_entry = catch_handler_new(s);
|
||||
begin = s->pc;
|
||||
exc = cursp();
|
||||
codegen(s, tree->car, VAL);
|
||||
lp->type = LOOP_RESCUE;
|
||||
genop_1(s, OP_POPERR, 1);
|
||||
end = s->pc;
|
||||
noexc = genjmp(s, OP_JMP, 0);
|
||||
dispatch(s, onerr);
|
||||
lp->type = LOOP_RESCUE;
|
||||
catch_handler_set(s, catch_entry, MRB_CATCH_RESCUE, begin, end, s->pc);
|
||||
genop_1(s, OP_EXCEPT, exc);
|
||||
genop_1(s, OP_LOADF, exc);
|
||||
dispatch(s, noexc);
|
||||
@@ -2266,7 +2283,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
pop_n(n+1);
|
||||
genop_2S(s, OP_BLKPUSH, cursp(), (ainfo<<4)|(lv & 0xf));
|
||||
if (sendv) n = CALL_MAXARGS;
|
||||
genop_3(s, OP_SEND, cursp(), new_sym(s, mrb_intern_lit(s->mrb, "call")), n);
|
||||
genop_3(s, OP_SEND, cursp(), new_sym(s, MRB_SYM(call)), n);
|
||||
if (val) push();
|
||||
}
|
||||
break;
|
||||
@@ -2281,11 +2298,8 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
raise_error(s, "unexpected next");
|
||||
}
|
||||
else if (s->loop->type == LOOP_NORMAL) {
|
||||
if (s->ensure_level > s->loop->ensure_level) {
|
||||
genop_1(s, OP_EPOP, s->ensure_level - s->loop->ensure_level);
|
||||
}
|
||||
codegen(s, tree, NOVAL);
|
||||
genjmp(s, OP_JMP, s->loop->pc0);
|
||||
genjmp(s, OP_JMPUW, s->loop->pc0);
|
||||
}
|
||||
else {
|
||||
if (tree) {
|
||||
@@ -2305,10 +2319,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
raise_error(s, "unexpected redo");
|
||||
}
|
||||
else {
|
||||
if (s->ensure_level > s->loop->ensure_level) {
|
||||
genop_1(s, OP_EPOP, s->ensure_level - s->loop->ensure_level);
|
||||
}
|
||||
genjmp(s, OP_JMP, s->loop->pc2);
|
||||
genjmp(s, OP_JMPUW, s->loop->pc2);
|
||||
}
|
||||
if (val) push();
|
||||
break;
|
||||
@@ -2316,32 +2327,16 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
case NODE_RETRY:
|
||||
{
|
||||
const char *msg = "unexpected retry";
|
||||
const struct loopinfo *lp = s->loop;
|
||||
|
||||
if (!s->loop) {
|
||||
while (lp && lp->type != LOOP_RESCUE) {
|
||||
lp = lp->prev;
|
||||
}
|
||||
if (!lp) {
|
||||
raise_error(s, msg);
|
||||
}
|
||||
else {
|
||||
struct loopinfo *lp = s->loop;
|
||||
int n = 0;
|
||||
|
||||
while (lp && lp->type != LOOP_RESCUE) {
|
||||
if (lp->type == LOOP_BEGIN) {
|
||||
n++;
|
||||
}
|
||||
lp = lp->prev;
|
||||
}
|
||||
if (!lp) {
|
||||
raise_error(s, msg);
|
||||
}
|
||||
else {
|
||||
if (n > 0) {
|
||||
genop_1(s, OP_POPERR, n);
|
||||
}
|
||||
if (s->ensure_level > lp->ensure_level) {
|
||||
genop_1(s, OP_EPOP, s->ensure_level - lp->ensure_level);
|
||||
}
|
||||
genjmp(s, OP_JMP, lp->pc0);
|
||||
}
|
||||
genjmp(s, OP_JMPUW, lp->pc0);
|
||||
}
|
||||
if (val) push();
|
||||
}
|
||||
@@ -2447,7 +2442,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
mrb_bool overflow;
|
||||
|
||||
i = readint_mrb_int(s, p, base, FALSE, &overflow);
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
if (overflow) {
|
||||
double f = readint_float(s, p, base);
|
||||
int off = new_lit(s, mrb_float_value(s->mrb, f));
|
||||
@@ -2470,7 +2465,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
int off;
|
||||
|
||||
lit_int:
|
||||
off = new_lit(s, mrb_fixnum_value(i));
|
||||
off = new_lit(s, mrb_int_value(s->mrb, i));
|
||||
genop_2(s, OP_LOADL, cursp(), off);
|
||||
}
|
||||
}
|
||||
@@ -2478,7 +2473,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
}
|
||||
break;
|
||||
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
case NODE_FLOAT:
|
||||
if (val) {
|
||||
char *p = (char*)tree;
|
||||
@@ -2495,7 +2490,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
{
|
||||
nt = nint(tree->car);
|
||||
switch (nt) {
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
case NODE_FLOAT:
|
||||
if (val) {
|
||||
char *p = (char*)tree->cdr;
|
||||
@@ -2516,7 +2511,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
mrb_bool overflow;
|
||||
|
||||
i = readint_mrb_int(s, p, base, TRUE, &overflow);
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
if (overflow) {
|
||||
double f = readint_float(s, p, base);
|
||||
int off = new_lit(s, mrb_float_value(s->mrb, -f));
|
||||
@@ -2533,10 +2528,10 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
genop_2S(s, OP_LOADI16, cursp(), (uint16_t)i);
|
||||
}
|
||||
else {
|
||||
int off = new_lit(s, mrb_fixnum_value(i));
|
||||
int off = new_lit(s, mrb_int_value(s->mrb, i));
|
||||
genop_2(s, OP_LOADL, cursp(), off);
|
||||
}
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
}
|
||||
#endif
|
||||
push();
|
||||
@@ -2545,7 +2540,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
|
||||
default:
|
||||
if (val) {
|
||||
int sym = new_sym(s, mrb_intern_lit(s->mrb, "-@"));
|
||||
int sym = new_sym(s, MRB_QSYM(minus));
|
||||
codegen(s, tree, VAL);
|
||||
pop();
|
||||
genop_3(s, OP_SEND, cursp(), sym, 0);
|
||||
@@ -2618,7 +2613,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
{
|
||||
node *n;
|
||||
int ai = mrb_gc_arena_save(s->mrb);
|
||||
int sym = new_sym(s, mrb_intern_lit(s->mrb, "Kernel"));
|
||||
int sym = new_sym(s, MRB_SYM(Kernel));
|
||||
|
||||
genop_1(s, OP_LOADSELF, cursp());
|
||||
push();
|
||||
@@ -2637,7 +2632,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
}
|
||||
push(); /* for block */
|
||||
pop_n(3);
|
||||
sym = new_sym(s, mrb_intern_lit(s->mrb, "`"));
|
||||
sym = new_sym(s, MRB_QSYM(tick)); /* ` */
|
||||
genop_3(s, OP_SEND, cursp(), sym, 1);
|
||||
if (val) push();
|
||||
mrb_gc_arena_restore(s->mrb, ai);
|
||||
@@ -2657,7 +2652,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
genop_2(s, OP_STRING, cursp(), off);
|
||||
push(); push();
|
||||
pop_n(3);
|
||||
sym = new_sym(s, mrb_intern_lit(s->mrb, "`"));
|
||||
sym = new_sym(s, MRB_QSYM(tick)); /* ` */
|
||||
genop_3(s, OP_SEND, cursp(), sym, 1);
|
||||
if (val) push();
|
||||
mrb_gc_arena_restore(s->mrb, ai);
|
||||
@@ -2698,7 +2693,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
}
|
||||
push(); /* space for a block */
|
||||
pop_n(argc+2);
|
||||
sym = new_sym(s, mrb_intern_lit(s->mrb, "compile"));
|
||||
sym = new_sym(s, MRB_SYM(compile));
|
||||
genop_3(s, OP_SEND, cursp(), sym, argc);
|
||||
mrb_gc_arena_restore(s->mrb, ai);
|
||||
push();
|
||||
@@ -2752,7 +2747,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
}
|
||||
push(); /* space for a block */
|
||||
pop_n(argc+2);
|
||||
sym = new_sym(s, mrb_intern_lit(s->mrb, "compile"));
|
||||
sym = new_sym(s, MRB_SYM(compile));
|
||||
genop_3(s, OP_SEND, cursp(), sym, argc);
|
||||
mrb_gc_arena_restore(s->mrb, ai);
|
||||
push();
|
||||
@@ -2993,91 +2988,86 @@ scope_add_irep(codegen_scope *s, mrb_irep *irep)
|
||||
}
|
||||
if (s->irep->rlen == s->rcapa) {
|
||||
s->rcapa *= 2;
|
||||
s->irep->reps = (mrb_irep**)codegen_realloc(s, s->irep->reps, sizeof(mrb_irep*)*s->rcapa);
|
||||
s->reps = (mrb_irep**)codegen_realloc(s, s->reps, sizeof(mrb_irep*)*s->rcapa);
|
||||
}
|
||||
s->irep->reps[s->irep->rlen] = irep;
|
||||
s->reps[s->irep->rlen] = irep;
|
||||
s->irep->rlen++;
|
||||
}
|
||||
|
||||
static codegen_scope*
|
||||
scope_new(mrb_state *mrb, codegen_scope *prev, node *lv)
|
||||
scope_new(mrb_state *mrb, codegen_scope *prev, node *nlv)
|
||||
{
|
||||
static const codegen_scope codegen_scope_zero = { 0 };
|
||||
mrb_pool *pool = mrb_pool_open(mrb);
|
||||
codegen_scope *p = (codegen_scope *)mrb_pool_alloc(pool, sizeof(codegen_scope));
|
||||
codegen_scope *s = (codegen_scope *)mrb_pool_alloc(pool, sizeof(codegen_scope));
|
||||
|
||||
if (!p) {
|
||||
if (!s) {
|
||||
if (prev)
|
||||
codegen_error(prev, "unexpected scope");
|
||||
return NULL;
|
||||
}
|
||||
*p = codegen_scope_zero;
|
||||
p->mrb = mrb;
|
||||
p->mpool = pool;
|
||||
if (!prev) return p;
|
||||
p->prev = prev;
|
||||
p->ainfo = -1;
|
||||
p->mscope = 0;
|
||||
*s = codegen_scope_zero;
|
||||
s->mrb = mrb;
|
||||
s->mpool = pool;
|
||||
if (!prev) return s;
|
||||
s->prev = prev;
|
||||
s->ainfo = -1;
|
||||
s->mscope = 0;
|
||||
|
||||
p->irep = mrb_add_irep(mrb);
|
||||
scope_add_irep(prev, p->irep);
|
||||
s->irep = mrb_add_irep(mrb);
|
||||
scope_add_irep(prev, s->irep);
|
||||
|
||||
p->rcapa = 8;
|
||||
p->irep->reps = (mrb_irep**)mrb_malloc(mrb, sizeof(mrb_irep*)*p->rcapa);
|
||||
s->rcapa = 8;
|
||||
s->reps = (mrb_irep**)mrb_malloc(mrb, sizeof(mrb_irep*)*s->rcapa);
|
||||
|
||||
p->icapa = 1024;
|
||||
p->iseq = (mrb_code*)mrb_malloc(mrb, sizeof(mrb_code)*p->icapa);
|
||||
p->irep->iseq = NULL;
|
||||
s->icapa = 1024;
|
||||
s->iseq = (mrb_code*)mrb_malloc(mrb, sizeof(mrb_code)*s->icapa);
|
||||
s->irep->iseq = NULL;
|
||||
|
||||
p->pcapa = 32;
|
||||
p->irep->pool = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value)*p->pcapa);
|
||||
p->irep->plen = 0;
|
||||
s->pcapa = 32;
|
||||
s->pool = (mrb_pool_value*)mrb_malloc(mrb, sizeof(mrb_pool_value)*s->pcapa);
|
||||
s->irep->plen = 0;
|
||||
|
||||
p->scapa = 256;
|
||||
p->irep->syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym)*p->scapa);
|
||||
p->irep->slen = 0;
|
||||
s->scapa = 256;
|
||||
s->syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym)*s->scapa);
|
||||
s->irep->slen = 0;
|
||||
|
||||
p->lv = lv;
|
||||
p->sp += node_len(lv)+1; /* add self */
|
||||
p->nlocals = p->sp;
|
||||
if (lv) {
|
||||
node *n = lv;
|
||||
s->lv = nlv;
|
||||
s->sp += node_len(nlv)+1; /* add self */
|
||||
s->nlocals = s->sp;
|
||||
if (nlv) {
|
||||
mrb_sym *lv;
|
||||
node *n = nlv;
|
||||
size_t i = 0;
|
||||
|
||||
p->irep->lv = (struct mrb_locals*)mrb_malloc(mrb, sizeof(struct mrb_locals) * (p->nlocals - 1));
|
||||
for (i=0, n=lv; n; i++,n=n->cdr) {
|
||||
p->irep->lv[i].name = lv_name(n);
|
||||
if (lv_name(n)) {
|
||||
p->irep->lv[i].r = lv_idx(p, lv_name(n));
|
||||
}
|
||||
else {
|
||||
p->irep->lv[i].r = 0;
|
||||
}
|
||||
s->irep->lv = lv = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym)*(s->nlocals-1));
|
||||
for (i=0, n=nlv; n; i++,n=n->cdr) {
|
||||
lv[i] = lv_name(n);
|
||||
}
|
||||
mrb_assert(i + 1 == p->nlocals);
|
||||
mrb_assert(i + 1 == s->nlocals);
|
||||
}
|
||||
p->ai = mrb_gc_arena_save(mrb);
|
||||
s->ai = mrb_gc_arena_save(mrb);
|
||||
|
||||
p->filename_sym = prev->filename_sym;
|
||||
if (p->filename_sym) {
|
||||
p->lines = (uint16_t*)mrb_malloc(mrb, sizeof(short)*p->icapa);
|
||||
s->filename_sym = prev->filename_sym;
|
||||
if (s->filename_sym) {
|
||||
s->lines = (uint16_t*)mrb_malloc(mrb, sizeof(short)*s->icapa);
|
||||
}
|
||||
p->lineno = prev->lineno;
|
||||
s->lineno = prev->lineno;
|
||||
|
||||
/* debug setting */
|
||||
p->debug_start_pos = 0;
|
||||
if (p->filename_sym) {
|
||||
mrb_debug_info_alloc(mrb, p->irep);
|
||||
s->debug_start_pos = 0;
|
||||
if (s->filename_sym) {
|
||||
mrb_debug_info_alloc(mrb, s->irep);
|
||||
}
|
||||
else {
|
||||
p->irep->debug_info = NULL;
|
||||
s->irep->debug_info = NULL;
|
||||
}
|
||||
p->parser = prev->parser;
|
||||
p->filename_index = prev->filename_index;
|
||||
s->parser = prev->parser;
|
||||
s->filename_index = prev->filename_index;
|
||||
|
||||
p->rlev = prev->rlev+1;
|
||||
s->rlev = prev->rlev+1;
|
||||
|
||||
return p;
|
||||
return s;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3091,12 +3081,21 @@ scope_finish(codegen_scope *s)
|
||||
}
|
||||
irep->flags = 0;
|
||||
if (s->iseq) {
|
||||
irep->iseq = (mrb_code *)codegen_realloc(s, s->iseq, sizeof(mrb_code)*s->pc);
|
||||
size_t catchsize = sizeof(struct mrb_irep_catch_handler) * irep->clen;
|
||||
irep->iseq = (const mrb_code *)codegen_realloc(s, s->iseq, sizeof(mrb_code)*s->pc + catchsize);
|
||||
irep->ilen = s->pc;
|
||||
if (irep->clen > 0) {
|
||||
memcpy((void *)(irep->iseq + irep->ilen), s->catch_table, catchsize);
|
||||
}
|
||||
}
|
||||
irep->pool = (mrb_value*)codegen_realloc(s, irep->pool, sizeof(mrb_value)*irep->plen);
|
||||
irep->syms = (mrb_sym*)codegen_realloc(s, irep->syms, sizeof(mrb_sym)*irep->slen);
|
||||
irep->reps = (mrb_irep**)codegen_realloc(s, irep->reps, sizeof(mrb_irep*)*irep->rlen);
|
||||
else {
|
||||
irep->clen = 0;
|
||||
}
|
||||
mrb_free(s->mrb, s->catch_table);
|
||||
s->catch_table = NULL;
|
||||
irep->pool = (const mrb_pool_value*)codegen_realloc(s, s->pool, sizeof(mrb_pool_value)*irep->plen);
|
||||
irep->syms = (const mrb_sym*)codegen_realloc(s, s->syms, sizeof(mrb_sym)*irep->slen);
|
||||
irep->reps = (const mrb_irep**)codegen_realloc(s, s->reps, sizeof(mrb_irep*)*irep->rlen);
|
||||
if (s->filename_sym) {
|
||||
mrb_sym fname = mrb_parser_get_filename(s->parser, s->filename_index);
|
||||
const char *filename = mrb_sym_name_len(s->mrb, fname, NULL);
|
||||
@@ -3121,7 +3120,6 @@ loop_push(codegen_scope *s, enum looptype t)
|
||||
p->type = t;
|
||||
p->pc0 = p->pc1 = p->pc2 = p->pc3 = 0;
|
||||
p->prev = s->loop;
|
||||
p->ensure_level = s->ensure_level;
|
||||
p->acc = cursp();
|
||||
s->loop = p;
|
||||
|
||||
@@ -3137,7 +3135,6 @@ loop_break(codegen_scope *s, node *tree)
|
||||
}
|
||||
else {
|
||||
struct loopinfo *loop;
|
||||
int n = 0;
|
||||
|
||||
if (tree) {
|
||||
gen_retval(s, tree);
|
||||
@@ -3146,7 +3143,6 @@ loop_break(codegen_scope *s, node *tree)
|
||||
loop = s->loop;
|
||||
while (loop) {
|
||||
if (loop->type == LOOP_BEGIN) {
|
||||
n++;
|
||||
loop = loop->prev;
|
||||
}
|
||||
else if (loop->type == LOOP_RESCUE) {
|
||||
@@ -3160,20 +3156,14 @@ loop_break(codegen_scope *s, node *tree)
|
||||
raise_error(s, "unexpected break");
|
||||
return;
|
||||
}
|
||||
if (n > 0) {
|
||||
genop_1(s, OP_POPERR, n);
|
||||
}
|
||||
|
||||
if (loop->type == LOOP_NORMAL) {
|
||||
int tmp;
|
||||
|
||||
if (s->ensure_level > s->loop->ensure_level) {
|
||||
genop_1(s, OP_EPOP, s->ensure_level - s->loop->ensure_level);
|
||||
}
|
||||
if (tree) {
|
||||
gen_move(s, loop->acc, cursp(), 0);
|
||||
}
|
||||
tmp = genjmp(s, OP_JMP, loop->pc3);
|
||||
tmp = genjmp(s, OP_JMPUW, loop->pc3);
|
||||
loop->pc3 = tmp;
|
||||
}
|
||||
else {
|
||||
@@ -3196,6 +3186,31 @@ loop_pop(codegen_scope *s, int val)
|
||||
if (val) push();
|
||||
}
|
||||
|
||||
static int
|
||||
catch_handler_new(codegen_scope *s)
|
||||
{
|
||||
size_t newsize = sizeof(struct mrb_irep_catch_handler) * (s->irep->clen + 1);
|
||||
s->catch_table = (struct mrb_irep_catch_handler *)codegen_realloc(s, (void *)s->catch_table, newsize);
|
||||
return s->irep->clen ++;
|
||||
}
|
||||
|
||||
static void
|
||||
catch_handler_set(codegen_scope *s, int ent, enum mrb_catch_type type, uint32_t begin, uint32_t end, uint32_t target)
|
||||
{
|
||||
struct mrb_irep_catch_handler *e;
|
||||
|
||||
mrb_assert(ent >= 0 && ent < s->irep->clen);
|
||||
mrb_assert(begin < MAXARG_S);
|
||||
mrb_assert(end < MAXARG_S);
|
||||
mrb_assert(target < MAXARG_S);
|
||||
|
||||
e = &s->catch_table[ent];
|
||||
uint8_to_bin(type, &e->type);
|
||||
uint16_to_bin(begin, e->begin);
|
||||
uint16_to_bin(end, e->end);
|
||||
uint16_to_bin(target, e->target);
|
||||
}
|
||||
|
||||
static struct RProc*
|
||||
generate_code(mrb_state *mrb, parser_state *p, int val)
|
||||
{
|
||||
@@ -3242,13 +3257,14 @@ mrb_irep_remove_lv(mrb_state *mrb, mrb_irep *irep)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (irep->flags & MRB_IREP_NO_FREE) return;
|
||||
if (irep->lv) {
|
||||
mrb_free(mrb, irep->lv);
|
||||
mrb_free(mrb, (void*)irep->lv);
|
||||
irep->lv = NULL;
|
||||
}
|
||||
|
||||
if (!irep->reps) return;
|
||||
for (i = 0; i < irep->rlen; ++i) {
|
||||
mrb_irep_remove_lv(mrb, irep->reps[i]);
|
||||
mrb_irep_remove_lv(mrb, (mrb_irep*)irep->reps[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3272,35 +3288,3 @@ uint8_t mrb_insn_size[] = {
|
||||
#undef SB
|
||||
#undef BBB
|
||||
};
|
||||
/* EXT1 instruction sizes */
|
||||
uint8_t mrb_insn_size1[] = {
|
||||
#define B 3
|
||||
#define BB 4
|
||||
#define BBB 5
|
||||
#define BS 5
|
||||
#define SB 5
|
||||
#define OPCODE(_,x) x,
|
||||
#include "mruby/ops.h"
|
||||
#undef OPCODE
|
||||
#undef B
|
||||
};
|
||||
/* EXT2 instruction sizes */
|
||||
uint8_t mrb_insn_size2[] = {
|
||||
#define B 2
|
||||
#define OPCODE(_,x) x,
|
||||
#include "mruby/ops.h"
|
||||
#undef OPCODE
|
||||
#undef BB
|
||||
#undef BBB
|
||||
#undef BS
|
||||
#undef SB
|
||||
};
|
||||
/* EXT3 instruction sizes */
|
||||
#define BB 5
|
||||
#define BBB 6
|
||||
#define BS 4
|
||||
#define SB 5
|
||||
uint8_t mrb_insn_size3[] = {
|
||||
#define OPCODE(_,x) x,
|
||||
#include "mruby/ops.h"
|
||||
};
|
||||
|
||||
+221
-116
@@ -265,7 +265,7 @@ local_unnest(parser_state *p)
|
||||
static mrb_bool
|
||||
local_var_p(parser_state *p, mrb_sym sym)
|
||||
{
|
||||
struct RProc *u;
|
||||
const struct RProc *u;
|
||||
node *l = p->locals;
|
||||
|
||||
while (l) {
|
||||
@@ -279,11 +279,13 @@ local_var_p(parser_state *p, mrb_sym sym)
|
||||
|
||||
u = p->upper;
|
||||
while (u && !MRB_PROC_CFUNC_P(u)) {
|
||||
struct mrb_irep *ir = u->body.irep;
|
||||
uint_fast16_t n = ir->nlocals;
|
||||
const struct mrb_locals *v = ir->lv;
|
||||
for (; n > 1; n --, v ++) {
|
||||
if (v->name == sym) return TRUE;
|
||||
const struct mrb_irep *ir = u->body.irep;
|
||||
const mrb_sym *v = ir->lv;
|
||||
int i;
|
||||
|
||||
if (!v) break;
|
||||
for (i=0; i+1 < ir->nlocals; i++) {
|
||||
if (v[i] == sym) return TRUE;
|
||||
}
|
||||
if (MRB_PROC_SCOPE_P(u)) break;
|
||||
u = u->upper;
|
||||
@@ -311,14 +313,14 @@ static void
|
||||
local_add_blk(parser_state *p, mrb_sym blk)
|
||||
{
|
||||
/* allocate register for block */
|
||||
local_add_f(p, blk ? blk : mrb_intern_lit(p->mrb, "&"));
|
||||
local_add_f(p, blk ? blk : MRB_QSYM(and));
|
||||
}
|
||||
|
||||
static void
|
||||
local_add_kw(parser_state *p, mrb_sym kwd)
|
||||
{
|
||||
/* allocate register for keywords hash */
|
||||
local_add_f(p, kwd ? kwd : mrb_intern_lit(p->mrb, "**"));
|
||||
local_add_f(p, kwd ? kwd : MRB_QSYM(pow));
|
||||
}
|
||||
|
||||
static node*
|
||||
@@ -730,7 +732,19 @@ new_module(parser_state *p, node *m, node *b)
|
||||
static node*
|
||||
new_def(parser_state *p, mrb_sym m, node *a, node *b)
|
||||
{
|
||||
return list5((node*)NODE_DEF, nsym(m), locals_node(p), a, b);
|
||||
return list5((node*)NODE_DEF, nsym(m), 0, a, b);
|
||||
}
|
||||
|
||||
static void
|
||||
defn_setup(parser_state *p, node *d, node *a, node *b)
|
||||
{
|
||||
node *n = d->cdr->cdr;
|
||||
|
||||
n->car = locals_node(p);
|
||||
p->cmdarg_stack = intn(n->cdr->car);
|
||||
n->cdr->car = a;
|
||||
local_resume(p, n->cdr->cdr->car);
|
||||
n->cdr->cdr->car = b;
|
||||
}
|
||||
|
||||
/* (:sdef obj m lv (arg . body)) */
|
||||
@@ -738,7 +752,19 @@ static node*
|
||||
new_sdef(parser_state *p, node *o, mrb_sym m, node *a, node *b)
|
||||
{
|
||||
void_expr_error(p, o);
|
||||
return list6((node*)NODE_SDEF, o, nsym(m), locals_node(p), a, b);
|
||||
return list6((node*)NODE_SDEF, o, nsym(m), 0, a, b);
|
||||
}
|
||||
|
||||
static void
|
||||
defs_setup(parser_state *p, node *d, node *a, node *b)
|
||||
{
|
||||
node *n = d->cdr->cdr->cdr;
|
||||
|
||||
n->car = locals_node(p);
|
||||
p->cmdarg_stack = intn(n->cdr->car);
|
||||
n->cdr->car = a;
|
||||
local_resume(p, n->cdr->cdr->car);
|
||||
n->cdr->cdr->car = b;
|
||||
}
|
||||
|
||||
/* (:arg . sym) */
|
||||
@@ -932,13 +958,13 @@ new_op_asgn(parser_state *p, node *a, mrb_sym op, node *b)
|
||||
static node*
|
||||
new_imaginary(parser_state *p, node *imaginary)
|
||||
{
|
||||
return new_call(p, new_const(p, intern_lit("Kernel")), intern_lit("Complex"), list1(list2(list3((node*)NODE_INT, (node*)strdup("0"), nint(10)), imaginary)), 1);
|
||||
return new_call(p, new_const(p, MRB_SYM(Kernel)), MRB_SYM(Complex), list1(list2(list3((node*)NODE_INT, (node*)strdup("0"), nint(10)), imaginary)), 1);
|
||||
}
|
||||
|
||||
static node*
|
||||
new_rational(parser_state *p, node *rational)
|
||||
{
|
||||
return new_call(p, new_const(p, intern_lit("Kernel")), intern_lit("Rational"), list1(list1(rational)), 1);
|
||||
return new_call(p, new_const(p, MRB_SYM(Kernel)), MRB_SYM(Rational), list1(list1(rational)), 1);
|
||||
}
|
||||
|
||||
/* (:int . i) */
|
||||
@@ -955,7 +981,7 @@ new_int(parser_state *p, const char *s, int base, int suffix)
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
/* (:float . i) */
|
||||
static node*
|
||||
new_float(parser_state *p, const char *s, int suffix)
|
||||
@@ -1415,8 +1441,8 @@ heredoc_end(parser_state *p)
|
||||
%token <num> tNUMPARAM
|
||||
|
||||
%type <nd> singleton string string_fragment string_rep string_interp xstring regexp
|
||||
%type <nd> literal numeric cpath symbol
|
||||
%type <nd> top_compstmt top_stmts top_stmt
|
||||
%type <nd> literal numeric cpath symbol defn_head defs_head
|
||||
%type <nd> top_compstmt top_stmts top_stmt rassign
|
||||
%type <nd> bodystmt compstmt stmts stmt expr arg primary command command_call method_call
|
||||
%type <nd> expr_value arg_rhs primary_value
|
||||
%type <nd> if_tail opt_else case_body cases opt_rescue exc_list exc_var opt_ensure
|
||||
@@ -1425,7 +1451,7 @@ heredoc_end(parser_state *p)
|
||||
%type <nd> command_args aref_args opt_block_arg block_arg var_ref var_lhs
|
||||
%type <nd> command_asgn command_rhs mrhs superclass block_call block_command
|
||||
%type <nd> f_block_optarg f_block_opt
|
||||
%type <nd> f_arglist f_args f_arg f_arg_item f_optarg f_margs
|
||||
%type <nd> f_arglist_paren f_arglist f_args f_arg f_arg_item f_optarg f_margs
|
||||
%type <nd> assoc_list assocs assoc undef_list backref for_var
|
||||
%type <nd> block_param opt_block_param block_param_def f_opt
|
||||
%type <nd> bv_decls opt_bv_decl bvar f_larglist lambda_body
|
||||
@@ -1658,9 +1684,30 @@ stmt : keyword_alias fsym {p->lstate = EXPR_FNAME;} fsym
|
||||
{
|
||||
$$ = new_masgn(p, $1, new_array(p, $3));
|
||||
}
|
||||
| rassign
|
||||
| expr
|
||||
;
|
||||
|
||||
rassign : arg tASSOC lhs
|
||||
{
|
||||
void_expr_error(p, $1);
|
||||
$$ = new_asgn(p, $3, $1);
|
||||
}
|
||||
| arg tASSOC mlhs
|
||||
{
|
||||
void_expr_error(p, $1);
|
||||
$$ = new_masgn(p, $3, $1);
|
||||
}
|
||||
| rassign tASSOC lhs
|
||||
{
|
||||
$$ = new_asgn(p, $3, $1);
|
||||
}
|
||||
| rassign tASSOC mlhs
|
||||
{
|
||||
$$ = new_masgn(p, $3, $1);
|
||||
}
|
||||
;
|
||||
|
||||
command_asgn : lhs '=' command_rhs
|
||||
{
|
||||
$$ = new_asgn(p, $1, $3);
|
||||
@@ -1671,7 +1718,7 @@ command_asgn : lhs '=' command_rhs
|
||||
}
|
||||
| primary_value '[' opt_call_args ']' tOP_ASGN command_rhs
|
||||
{
|
||||
$$ = new_op_asgn(p, new_call(p, $1, intern_lit("[]"), $3, '.'), $5, $6);
|
||||
$$ = new_op_asgn(p, new_call(p, $1, MRB_QSYM(aref), $3, '.'), $5, $6);
|
||||
}
|
||||
| primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
|
||||
{
|
||||
@@ -1726,6 +1773,31 @@ expr : command_call
|
||||
| arg
|
||||
;
|
||||
|
||||
|
||||
defn_head : keyword_def fname
|
||||
{
|
||||
$$ = new_def(p, $2, nint(p->cmdarg_stack), local_switch(p));
|
||||
p->cmdarg_stack = 0;
|
||||
p->in_def++;
|
||||
nvars_block(p);
|
||||
}
|
||||
;
|
||||
|
||||
defs_head : keyword_def singleton dot_or_colon
|
||||
{
|
||||
p->lstate = EXPR_FNAME;
|
||||
}
|
||||
fname
|
||||
{
|
||||
$$ = new_sdef(p, $2, $5, nint(p->cmdarg_stack), local_switch(p));
|
||||
p->cmdarg_stack = 0;
|
||||
p->in_def++;
|
||||
p->in_single++;
|
||||
nvars_block(p);
|
||||
p->lstate = EXPR_ENDFN; /* force for args */
|
||||
}
|
||||
;
|
||||
|
||||
expr_value : expr
|
||||
{
|
||||
if (!$1) $$ = new_nil(p);
|
||||
@@ -1902,7 +1974,7 @@ mlhs_node : variable
|
||||
}
|
||||
| primary_value '[' opt_call_args ']'
|
||||
{
|
||||
$$ = new_call(p, $1, intern_lit("[]"), $3, '.');
|
||||
$$ = new_call(p, $1, MRB_QSYM(aref), $3, '.');
|
||||
}
|
||||
| primary_value call_op tIDENTIFIER
|
||||
{
|
||||
@@ -1941,7 +2013,7 @@ lhs : variable
|
||||
}
|
||||
| primary_value '[' opt_call_args ']'
|
||||
{
|
||||
$$ = new_call(p, $1, intern_lit("[]"), $3, '.');
|
||||
$$ = new_call(p, $1, MRB_QSYM(aref), $3, '.');
|
||||
}
|
||||
| primary_value call_op tIDENTIFIER
|
||||
{
|
||||
@@ -2029,36 +2101,36 @@ undef_list : fsym
|
||||
}
|
||||
;
|
||||
|
||||
op : '|' { $$ = intern_lit("|"); }
|
||||
| '^' { $$ = intern_lit("^"); }
|
||||
| '&' { $$ = intern_lit("&"); }
|
||||
| tCMP { $$ = intern_lit("<=>"); }
|
||||
| tEQ { $$ = intern_lit("=="); }
|
||||
| tEQQ { $$ = intern_lit("==="); }
|
||||
| tMATCH { $$ = intern_lit("=~"); }
|
||||
| tNMATCH { $$ = intern_lit("!~"); }
|
||||
| '>' { $$ = intern_lit(">"); }
|
||||
| tGEQ { $$ = intern_lit(">="); }
|
||||
| '<' { $$ = intern_lit("<"); }
|
||||
| tLEQ { $$ = intern_lit("<="); }
|
||||
| tNEQ { $$ = intern_lit("!="); }
|
||||
| tLSHFT { $$ = intern_lit("<<"); }
|
||||
| tRSHFT { $$ = intern_lit(">>"); }
|
||||
| '+' { $$ = intern_lit("+"); }
|
||||
| '-' { $$ = intern_lit("-"); }
|
||||
| '*' { $$ = intern_lit("*"); }
|
||||
| tSTAR { $$ = intern_lit("*"); }
|
||||
| '/' { $$ = intern_lit("/"); }
|
||||
| '%' { $$ = intern_lit("%"); }
|
||||
| tPOW { $$ = intern_lit("**"); }
|
||||
| tDSTAR { $$ = intern_lit("**"); }
|
||||
| '!' { $$ = intern_lit("!"); }
|
||||
| '~' { $$ = intern_lit("~"); }
|
||||
| tUPLUS { $$ = intern_lit("+@"); }
|
||||
| tUMINUS { $$ = intern_lit("-@"); }
|
||||
| tAREF { $$ = intern_lit("[]"); }
|
||||
| tASET { $$ = intern_lit("[]="); }
|
||||
| '`' { $$ = intern_lit("`"); }
|
||||
op : '|' { $$ = MRB_QSYM(or); }
|
||||
| '^' { $$ = MRB_QSYM(xor); }
|
||||
| '&' { $$ = MRB_QSYM(and); }
|
||||
| tCMP { $$ = MRB_QSYM(cmp); }
|
||||
| tEQ { $$ = MRB_QSYM(eq); }
|
||||
| tEQQ { $$ = MRB_QSYM(eqq); }
|
||||
| tMATCH { $$ = MRB_QSYM(match); }
|
||||
| tNMATCH { $$ = MRB_QSYM(nmatch); }
|
||||
| '>' { $$ = MRB_QSYM(gt); }
|
||||
| tGEQ { $$ = MRB_QSYM(ge); }
|
||||
| '<' { $$ = MRB_QSYM(lt); }
|
||||
| tLEQ { $$ = MRB_QSYM(le); }
|
||||
| tNEQ { $$ = MRB_QSYM(neq); }
|
||||
| tLSHFT { $$ = MRB_QSYM(lshift); }
|
||||
| tRSHFT { $$ = MRB_QSYM(rshift); }
|
||||
| '+' { $$ = MRB_QSYM(add); }
|
||||
| '-' { $$ = MRB_QSYM(sub); }
|
||||
| '*' { $$ = MRB_QSYM(mul); }
|
||||
| tSTAR { $$ = MRB_QSYM(mul); }
|
||||
| '/' { $$ = MRB_QSYM(div); }
|
||||
| '%' { $$ = MRB_QSYM(mod); }
|
||||
| tPOW { $$ = MRB_QSYM(pow); }
|
||||
| tDSTAR { $$ = MRB_QSYM(pow); }
|
||||
| '!' { $$ = MRB_QSYM(not); }
|
||||
| '~' { $$ = MRB_QSYM(neg); }
|
||||
| tUPLUS { $$ = MRB_QSYM(plus); }
|
||||
| tUMINUS { $$ = MRB_QSYM(minus); }
|
||||
| tAREF { $$ = MRB_QSYM(aref); }
|
||||
| tASET { $$ = MRB_QSYM(aset); }
|
||||
| '`' { $$ = MRB_QSYM(tick); }
|
||||
;
|
||||
|
||||
reswords : keyword__LINE__ | keyword__FILE__ | keyword__ENCODING__
|
||||
@@ -2085,7 +2157,7 @@ arg : lhs '=' arg_rhs
|
||||
}
|
||||
| primary_value '[' opt_call_args ']' tOP_ASGN arg_rhs
|
||||
{
|
||||
$$ = new_op_asgn(p, new_call(p, $1, intern_lit("[]"), $3, '.'), $5, $6);
|
||||
$$ = new_op_asgn(p, new_call(p, $1, MRB_QSYM(aref), $3, '.'), $5, $6);
|
||||
}
|
||||
| primary_value call_op tIDENTIFIER tOP_ASGN arg_rhs
|
||||
{
|
||||
@@ -2118,10 +2190,18 @@ arg : lhs '=' arg_rhs
|
||||
{
|
||||
$$ = new_dot2(p, $1, $3);
|
||||
}
|
||||
| arg tDOT2
|
||||
{
|
||||
$$ = new_dot2(p, $1, new_nil(p));
|
||||
}
|
||||
| arg tDOT3 arg
|
||||
{
|
||||
$$ = new_dot3(p, $1, $3);
|
||||
}
|
||||
| arg tDOT3
|
||||
{
|
||||
$$ = new_dot3(p, $1, new_nil(p));
|
||||
}
|
||||
| arg '+' arg
|
||||
{
|
||||
$$ = call_bin_op(p, $1, "+", $3);
|
||||
@@ -2246,6 +2326,42 @@ arg : lhs '=' arg_rhs
|
||||
{
|
||||
$$ = new_if(p, cond($1), $3, $6);
|
||||
}
|
||||
| defn_head f_arglist_paren '=' arg
|
||||
{
|
||||
$$ = $1;
|
||||
void_expr_error(p, $4);
|
||||
defn_setup(p, $$, $2, $4);
|
||||
nvars_unnest(p);
|
||||
p->in_def--;
|
||||
}
|
||||
| defn_head f_arglist_paren '=' arg modifier_rescue arg
|
||||
{
|
||||
$$ = $1;
|
||||
void_expr_error(p, $4);
|
||||
void_expr_error(p, $6);
|
||||
defn_setup(p, $$, $2, new_mod_rescue(p, $4, $6));
|
||||
nvars_unnest(p);
|
||||
p->in_def--;
|
||||
}
|
||||
| defs_head f_arglist_paren '=' arg
|
||||
{
|
||||
$$ = $1;
|
||||
void_expr_error(p, $4);
|
||||
defs_setup(p, $$, $2, $4);
|
||||
nvars_unnest(p);
|
||||
p->in_def--;
|
||||
p->in_single--;
|
||||
}
|
||||
| defs_head f_arglist_paren '=' arg modifier_rescue arg
|
||||
{
|
||||
$$ = $1;
|
||||
void_expr_error(p, $4);
|
||||
void_expr_error(p, $6);
|
||||
defs_setup(p, $$, $2, new_mod_rescue(p, $4, $6));
|
||||
nvars_unnest(p);
|
||||
p->in_def--;
|
||||
p->in_single--;
|
||||
}
|
||||
| primary
|
||||
{
|
||||
$$ = $1;
|
||||
@@ -2288,16 +2404,16 @@ paren_args : '(' opt_call_args ')'
|
||||
| '(' tDOT3 rparen
|
||||
{
|
||||
#if 1
|
||||
mrb_sym r = mrb_intern_lit(p->mrb, "*");
|
||||
mrb_sym b = mrb_intern_lit(p->mrb, "&");
|
||||
mrb_sym r = MRB_QSYM(mul);
|
||||
mrb_sym b = MRB_QSYM(and);
|
||||
if (local_var_p(p, r) && local_var_p(p, b)) {
|
||||
$$ = cons(list1(new_splat(p, new_lvar(p, r))),
|
||||
new_block_arg(p, new_lvar(p, b)));
|
||||
}
|
||||
#else
|
||||
mrb_sym r = mrb_intern_lit(p->mrb, "*");
|
||||
mrb_sym k = mrb_intern_lit(p->mrb, "**");
|
||||
mrb_sym b = mrb_intern_lit(p->mrb, "&");
|
||||
mrb_sym r = MRB_QSYM(mul);
|
||||
mrb_sym k = MRB_QSYM(pow);
|
||||
mrb_sym b = MRB_QSYM(and);
|
||||
if (local_var_p(p, r) && local_var_p(p, k) && local_var_p(p, b)) {
|
||||
$$ = cons(list2(new_splat(p, new_lvar(p, r)),
|
||||
new_kw_hash(p, list1(cons(new_kw_rest_args(p, 0), new_lvar(p, k))))),
|
||||
@@ -2645,50 +2761,26 @@ primary : literal
|
||||
local_resume(p, $<nd>3);
|
||||
nvars_unnest(p);
|
||||
}
|
||||
| keyword_def fname
|
||||
{
|
||||
$<stack>$ = p->cmdarg_stack;
|
||||
p->cmdarg_stack = 0;
|
||||
}
|
||||
{
|
||||
p->in_def++;
|
||||
$<nd>$ = local_switch(p);
|
||||
nvars_block(p);
|
||||
}
|
||||
| defn_head
|
||||
f_arglist
|
||||
bodystmt
|
||||
keyword_end
|
||||
{
|
||||
$$ = new_def(p, $2, $5, $6);
|
||||
SET_LINENO($$, $1);
|
||||
local_resume(p, $<nd>4);
|
||||
$$ = $1;
|
||||
defn_setup(p, $$, $2, $3);
|
||||
nvars_unnest(p);
|
||||
p->in_def--;
|
||||
p->cmdarg_stack = $<stack>3;
|
||||
}
|
||||
| keyword_def singleton dot_or_colon
|
||||
{
|
||||
p->lstate = EXPR_FNAME;
|
||||
$<stack>$ = p->cmdarg_stack;
|
||||
p->cmdarg_stack = 0;
|
||||
}
|
||||
fname
|
||||
{
|
||||
p->in_single++;
|
||||
p->lstate = EXPR_ENDFN; /* force for args */
|
||||
$<nd>$ = local_switch(p);
|
||||
nvars_block(p);
|
||||
}
|
||||
| defs_head
|
||||
f_arglist
|
||||
bodystmt
|
||||
keyword_end
|
||||
{
|
||||
$$ = new_sdef(p, $2, $5, $7, $8);
|
||||
SET_LINENO($$, $1);
|
||||
local_resume(p, $<nd>6);
|
||||
$$ = $1;
|
||||
defs_setup(p, $$, $2, $3);
|
||||
nvars_unnest(p);
|
||||
p->in_def--;
|
||||
p->in_single--;
|
||||
p->cmdarg_stack = $<stack>4;
|
||||
}
|
||||
| keyword_break
|
||||
{
|
||||
@@ -3010,11 +3102,11 @@ method_call : operation paren_args
|
||||
}
|
||||
| primary_value call_op paren_args
|
||||
{
|
||||
$$ = new_call(p, $1, intern_lit("call"), $3, $2);
|
||||
$$ = new_call(p, $1, MRB_SYM(call), $3, $2);
|
||||
}
|
||||
| primary_value tCOLON2 paren_args
|
||||
{
|
||||
$$ = new_call(p, $1, intern_lit("call"), $3, tCOLON2);
|
||||
$$ = new_call(p, $1, MRB_SYM(call), $3, tCOLON2);
|
||||
}
|
||||
| keyword_super paren_args
|
||||
{
|
||||
@@ -3026,7 +3118,7 @@ method_call : operation paren_args
|
||||
}
|
||||
| primary_value '[' opt_call_args ']'
|
||||
{
|
||||
$$ = new_call(p, $1, intern_lit("[]"), $3, '.');
|
||||
$$ = new_call(p, $1, MRB_QSYM(aref), $3, '.');
|
||||
}
|
||||
;
|
||||
|
||||
@@ -3399,7 +3491,7 @@ superclass : /* term */
|
||||
} */
|
||||
;
|
||||
|
||||
f_arglist : '(' f_args rparen
|
||||
f_arglist_paren : '(' f_args rparen
|
||||
{
|
||||
$$ = $2;
|
||||
p->lstate = EXPR_BEG;
|
||||
@@ -3409,20 +3501,23 @@ f_arglist : '(' f_args rparen
|
||||
{
|
||||
#if 1
|
||||
/* til real keyword args implemented */
|
||||
mrb_sym r = mrb_intern_lit(p->mrb, "*");
|
||||
mrb_sym b = mrb_intern_lit(p->mrb, "&");
|
||||
mrb_sym r = MRB_QSYM(mul);
|
||||
mrb_sym b = MRB_QSYM(and);
|
||||
local_add_f(p, r);
|
||||
$$ = new_args(p, 0, 0, r, 0,
|
||||
new_args_tail(p, 0, 0, b));
|
||||
#else
|
||||
mrb_sym r = mrb_intern_lit(p->mrb, "*");
|
||||
mrb_sym k = mrb_intern_lit(p->mrb, "**");
|
||||
mrb_sym b = mrb_intern_lit(p->mrb, "&");
|
||||
mrb_sym r = MRB_QSYM(mul);
|
||||
mrb_sym k = MRB_QSYM(pow);
|
||||
mrb_sym b = MRB_QSYM(and);
|
||||
local_add_f(p, r); local_add_f(p, k);
|
||||
$$ = new_args(p, 0, 0, r, 0,
|
||||
new_args_tail(p, 0, new_kw_rest_args(p, nsym(k)), b));
|
||||
#endif
|
||||
}
|
||||
;
|
||||
|
||||
f_arglist : f_arglist_paren
|
||||
| f_args term
|
||||
{
|
||||
$$ = $1;
|
||||
@@ -3580,7 +3675,7 @@ f_args : f_arg ',' f_optarg ',' f_rest_arg opt_args_tail
|
||||
}
|
||||
| /* none */
|
||||
{
|
||||
local_add_f(p, mrb_intern_lit(p->mrb, "&"));
|
||||
local_add_f(p, MRB_QSYM(and));
|
||||
$$ = new_args(p, 0, 0, 0, 0, 0);
|
||||
}
|
||||
;
|
||||
@@ -3704,7 +3799,7 @@ f_rest_arg : restarg_mark tIDENTIFIER
|
||||
}
|
||||
| restarg_mark
|
||||
{
|
||||
local_add_f(p, mrb_intern_lit(p->mrb, "*"));
|
||||
local_add_f(p, MRB_QSYM(mul));
|
||||
$$ = -1;
|
||||
}
|
||||
;
|
||||
@@ -4961,7 +5056,7 @@ parser_yylex(parser_state *p)
|
||||
case '*':
|
||||
if ((c = nextc(p)) == '*') {
|
||||
if ((c = nextc(p)) == '=') {
|
||||
pylval.id = intern_lit("**");
|
||||
pylval.id = MRB_QSYM(pow);
|
||||
p->lstate = EXPR_BEG;
|
||||
return tOP_ASGN;
|
||||
}
|
||||
@@ -4979,7 +5074,7 @@ parser_yylex(parser_state *p)
|
||||
}
|
||||
else {
|
||||
if (c == '=') {
|
||||
pylval.id = intern_lit("*");
|
||||
pylval.id = MRB_QSYM(mul);
|
||||
p->lstate = EXPR_BEG;
|
||||
return tOP_ASGN;
|
||||
}
|
||||
@@ -5095,7 +5190,7 @@ parser_yylex(parser_state *p)
|
||||
}
|
||||
if (c == '<') {
|
||||
if ((c = nextc(p)) == '=') {
|
||||
pylval.id = intern_lit("<<");
|
||||
pylval.id = MRB_QSYM(lshift);
|
||||
p->lstate = EXPR_BEG;
|
||||
return tOP_ASGN;
|
||||
}
|
||||
@@ -5117,7 +5212,7 @@ parser_yylex(parser_state *p)
|
||||
}
|
||||
if (c == '>') {
|
||||
if ((c = nextc(p)) == '=') {
|
||||
pylval.id = intern_lit(">>");
|
||||
pylval.id = MRB_QSYM(rshift);
|
||||
p->lstate = EXPR_BEG;
|
||||
return tOP_ASGN;
|
||||
}
|
||||
@@ -5225,7 +5320,7 @@ parser_yylex(parser_state *p)
|
||||
if ((c = nextc(p)) == '&') {
|
||||
p->lstate = EXPR_BEG;
|
||||
if ((c = nextc(p)) == '=') {
|
||||
pylval.id = intern_lit("&&");
|
||||
pylval.id = MRB_QSYM(andand);
|
||||
p->lstate = EXPR_BEG;
|
||||
return tOP_ASGN;
|
||||
}
|
||||
@@ -5237,7 +5332,7 @@ parser_yylex(parser_state *p)
|
||||
return tANDDOT;
|
||||
}
|
||||
else if (c == '=') {
|
||||
pylval.id = intern_lit("&");
|
||||
pylval.id = MRB_QSYM(and);
|
||||
p->lstate = EXPR_BEG;
|
||||
return tOP_ASGN;
|
||||
}
|
||||
@@ -5264,7 +5359,7 @@ parser_yylex(parser_state *p)
|
||||
if ((c = nextc(p)) == '|') {
|
||||
p->lstate = EXPR_BEG;
|
||||
if ((c = nextc(p)) == '=') {
|
||||
pylval.id = intern_lit("||");
|
||||
pylval.id = MRB_QSYM(oror);
|
||||
p->lstate = EXPR_BEG;
|
||||
return tOP_ASGN;
|
||||
}
|
||||
@@ -5272,7 +5367,7 @@ parser_yylex(parser_state *p)
|
||||
return tOROP;
|
||||
}
|
||||
if (c == '=') {
|
||||
pylval.id = intern_lit("|");
|
||||
pylval.id = MRB_QSYM(or);
|
||||
p->lstate = EXPR_BEG;
|
||||
return tOP_ASGN;
|
||||
}
|
||||
@@ -5296,7 +5391,7 @@ parser_yylex(parser_state *p)
|
||||
return '+';
|
||||
}
|
||||
if (c == '=') {
|
||||
pylval.id = intern_lit("+");
|
||||
pylval.id = MRB_QSYM(add);
|
||||
p->lstate = EXPR_BEG;
|
||||
return tOP_ASGN;
|
||||
}
|
||||
@@ -5324,7 +5419,7 @@ parser_yylex(parser_state *p)
|
||||
return '-';
|
||||
}
|
||||
if (c == '=') {
|
||||
pylval.id = intern_lit("-");
|
||||
pylval.id = MRB_QSYM(sub);
|
||||
p->lstate = EXPR_BEG;
|
||||
return tOP_ASGN;
|
||||
}
|
||||
@@ -5574,7 +5669,7 @@ parser_yylex(parser_state *p)
|
||||
}
|
||||
tokfix(p);
|
||||
if (is_float) {
|
||||
#ifdef MRB_WITHOUT_FLOAT
|
||||
#ifdef MRB_NO_FLOAT
|
||||
yywarning_s(p, "floating point numbers are not supported", tok(p));
|
||||
pylval.nd = new_int(p, "0", 10, 0);
|
||||
return tINTEGER;
|
||||
@@ -5644,7 +5739,7 @@ parser_yylex(parser_state *p)
|
||||
return tREGEXP_BEG;
|
||||
}
|
||||
if ((c = nextc(p)) == '=') {
|
||||
pylval.id = intern_lit("/");
|
||||
pylval.id = MRB_QSYM(div);
|
||||
p->lstate = EXPR_BEG;
|
||||
return tOP_ASGN;
|
||||
}
|
||||
@@ -5663,7 +5758,7 @@ parser_yylex(parser_state *p)
|
||||
|
||||
case '^':
|
||||
if ((c = nextc(p)) == '=') {
|
||||
pylval.id = intern_lit("^");
|
||||
pylval.id = MRB_QSYM(xor);
|
||||
p->lstate = EXPR_BEG;
|
||||
return tOP_ASGN;
|
||||
}
|
||||
@@ -5840,7 +5935,7 @@ parser_yylex(parser_state *p)
|
||||
}
|
||||
}
|
||||
if ((c = nextc(p)) == '=') {
|
||||
pylval.id = intern_lit("%");
|
||||
pylval.id = MRB_QSYM(mod);
|
||||
p->lstate = EXPR_BEG;
|
||||
return tOP_ASGN;
|
||||
}
|
||||
@@ -6376,11 +6471,21 @@ mrbc_partial_hook(mrb_state *mrb, mrbc_context *c, int (*func)(struct mrb_parser
|
||||
c->partial_data = data;
|
||||
}
|
||||
|
||||
MRB_API void
|
||||
mrbc_cleanup_local_variables(mrb_state *mrb, mrbc_context *c)
|
||||
{
|
||||
if (c->syms) {
|
||||
mrb_free(mrb, c->syms);
|
||||
c->syms = NULL;
|
||||
c->slen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
MRB_API void
|
||||
mrb_parser_set_filename(struct mrb_parser_state *p, const char *f)
|
||||
{
|
||||
mrb_sym sym;
|
||||
size_t i;
|
||||
uint16_t i;
|
||||
mrb_sym* new_table;
|
||||
|
||||
sym = mrb_intern_cstr(p->mrb, f);
|
||||
@@ -6389,7 +6494,7 @@ mrb_parser_set_filename(struct mrb_parser_state *p, const char *f)
|
||||
|
||||
for (i = 0; i < p->filename_table_length; ++i) {
|
||||
if (p->filename_table[i] == sym) {
|
||||
p->current_filename_index = (int)i;
|
||||
p->current_filename_index = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -6458,7 +6563,7 @@ mrb_load_exec(mrb_state *mrb, struct mrb_parser_state *p, mrbc_context *c)
|
||||
struct RClass *target = mrb->object_class;
|
||||
struct RProc *proc;
|
||||
mrb_value v;
|
||||
unsigned int keep = 0;
|
||||
mrb_int keep = 0;
|
||||
|
||||
if (!p) {
|
||||
return mrb_undef_value();
|
||||
@@ -6478,7 +6583,7 @@ mrb_load_exec(mrb_state *mrb, struct mrb_parser_state *p, mrbc_context *c)
|
||||
}
|
||||
else {
|
||||
if (mrb->exc == NULL) {
|
||||
mrb->exc = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, E_SYNTAX_ERROR, "syntax error"));
|
||||
mrb->exc = mrb_obj_ptr(mrb_exc_new_lit(mrb, E_SYNTAX_ERROR, "syntax error"));
|
||||
}
|
||||
mrb_parser_free(p);
|
||||
return mrb_undef_value();
|
||||
@@ -6488,7 +6593,7 @@ mrb_load_exec(mrb_state *mrb, struct mrb_parser_state *p, mrbc_context *c)
|
||||
mrb_parser_free(p);
|
||||
if (proc == NULL) {
|
||||
if (mrb->exc == NULL) {
|
||||
mrb->exc = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, E_SCRIPT_ERROR, "codegen error"));
|
||||
mrb->exc = mrb_obj_ptr(mrb_exc_new_lit(mrb, E_SCRIPT_ERROR, "codegen error"));
|
||||
}
|
||||
return mrb_undef_value();
|
||||
}
|
||||
|
||||
+4826
-4618
File diff suppressed because it is too large
Load Diff
@@ -104,7 +104,7 @@ class Complex < Numeric
|
||||
|
||||
alias_method :imag, :imaginary
|
||||
|
||||
[Fixnum, Float].each do |cls|
|
||||
[Integer, Float].each do |cls|
|
||||
[:+, :-, :*, :/, :==].each do |op|
|
||||
cls.instance_eval do
|
||||
original_operator_name = :"__original_operator_#{op}_complex"
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
#include <mruby/numeric.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifdef MRB_WITHOUT_FLOAT
|
||||
# error Complex conflicts 'MRB_WITHOUT_FLOAT' configuration in your 'build_config.rb'
|
||||
#ifdef MRB_NO_FLOAT
|
||||
# error Complex conflicts with 'MRB_NO_FLOAT' configuration
|
||||
#endif
|
||||
|
||||
struct mrb_complex {
|
||||
@@ -12,13 +12,13 @@ struct mrb_complex {
|
||||
mrb_float imaginary;
|
||||
};
|
||||
|
||||
#ifdef MRB_USE_FLOAT
|
||||
#ifdef MRB_USE_FLOAT32
|
||||
#define F(x) x##f
|
||||
#else
|
||||
#define F(x) x
|
||||
#endif
|
||||
|
||||
#if defined(MRB_64BIT) || defined(MRB_USE_FLOAT)
|
||||
#if defined(MRB_64BIT) || defined(MRB_USE_FLOAT32)
|
||||
|
||||
#define COMPLEX_USE_ISTRUCT
|
||||
/* use TT_ISTRUCT */
|
||||
@@ -69,7 +69,7 @@ complex_ptr(mrb_state *mrb, mrb_value v)
|
||||
static mrb_value
|
||||
complex_new(mrb_state *mrb, mrb_float real, mrb_float imaginary)
|
||||
{
|
||||
struct RClass *c = mrb_class_get(mrb, "Complex");
|
||||
struct RClass *c = mrb_class_get_id(mrb, MRB_SYM(Complex));
|
||||
struct mrb_complex *p;
|
||||
struct RBasic *comp = complex_alloc(mrb, c, &p);
|
||||
p->real = real;
|
||||
@@ -122,7 +122,7 @@ complex_to_i(mrb_state *mrb, mrb_value self)
|
||||
if (p->imaginary != 0) {
|
||||
mrb_raisef(mrb, E_RANGE_ERROR, "can't convert %v into Float", self);
|
||||
}
|
||||
return mrb_int_value(mrb, p->real);
|
||||
return mrb_int_value(mrb, (mrb_int)p->real);
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
@@ -224,7 +224,7 @@ void mrb_mruby_complex_gem_init(mrb_state *mrb)
|
||||
#ifdef COMPLEX_USE_ISTRUCT
|
||||
mrb_assert(sizeof(struct mrb_complex) < ISTRUCT_DATA_SIZE);
|
||||
#endif
|
||||
comp = mrb_define_class(mrb, "Complex", mrb_class_get(mrb, "Numeric"));
|
||||
comp = mrb_define_class(mrb, "Complex", mrb_class_get_id(mrb, MRB_SYM(Numeric)));
|
||||
#ifdef COMPLEX_USE_ISTRUCT
|
||||
MRB_SET_INSTANCE_TT(comp, MRB_TT_ISTRUCT);
|
||||
#else
|
||||
|
||||
@@ -56,11 +56,11 @@ end
|
||||
assert 'Complex#/' do
|
||||
assert_complex Complex(2, 3) / Complex(2, 3) , (1 + 0i)
|
||||
assert_complex Complex(900) / Complex(1) , (900 + 0i)
|
||||
assert_complex Complex(-2, 9) / Complex(-9, 2), ((36 / 85) - (77i / 85))
|
||||
assert_complex Complex(9, 8) / 4 , ((9 / 4) + 2i)
|
||||
assert_complex Complex(-2, 9) / Complex(-9, 2), ((36.0 / 85) - (77i / 85))
|
||||
assert_complex Complex(9, 8) / 4 , ((9.0 / 4) + 2i)
|
||||
assert_complex Complex(20, 9) / 9.8 , (2.0408163265306123 + 0.9183673469387754i)
|
||||
if 1e39.infinite? then
|
||||
# MRB_USE_FLOAT in effect
|
||||
# MRB_USE_FLOAT32 in effect
|
||||
ten = 1e21
|
||||
one = 1e20
|
||||
else
|
||||
@@ -80,7 +80,7 @@ assert 'Complex#abs' do
|
||||
assert_float Complex(-1).abs, 1
|
||||
assert_float Complex(3.0, -4.0).abs, 5.0
|
||||
if 1e39.infinite? then
|
||||
# MRB_USE_FLOAT in effect
|
||||
# MRB_USE_FLOAT32 in effect
|
||||
exp = 125
|
||||
else
|
||||
exp = 1021
|
||||
|
||||
@@ -130,6 +130,7 @@ class Enumerator
|
||||
@feedvalue = nil
|
||||
@stop_exc = false
|
||||
end
|
||||
|
||||
attr_accessor :obj, :meth, :args
|
||||
attr_reader :fib
|
||||
|
||||
|
||||
@@ -445,7 +445,7 @@ assert 'modifying existing methods' do
|
||||
}
|
||||
end
|
||||
|
||||
assert 'Integral#times' do
|
||||
assert 'Integer#times' do
|
||||
a = 3
|
||||
b = a.times
|
||||
c = []
|
||||
|
||||
@@ -12,7 +12,7 @@ mrb_value mrb_obj_instance_eval(mrb_state *mrb, mrb_value self);
|
||||
void mrb_codedump_all(mrb_state*, struct RProc*);
|
||||
|
||||
static struct RProc*
|
||||
create_proc_from_string(mrb_state *mrb, char *s, mrb_int len, mrb_value binding, const char *file, mrb_int line)
|
||||
create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value binding, const char *file, mrb_int line)
|
||||
{
|
||||
mrbc_context *cxt;
|
||||
struct mrb_parser_state *p;
|
||||
@@ -20,7 +20,7 @@ create_proc_from_string(mrb_state *mrb, char *s, mrb_int len, mrb_value binding,
|
||||
struct REnv *e;
|
||||
mrb_callinfo *ci; /* callinfo of eval caller */
|
||||
struct RClass *target_class = NULL;
|
||||
int bidx;
|
||||
mrb_int bidx;
|
||||
|
||||
if (!mrb_nil_p(binding)) {
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "Binding of eval must be nil.");
|
||||
@@ -131,10 +131,10 @@ exec_irep(mrb_state *mrb, mrb_value self, struct RProc *proc)
|
||||
static mrb_value
|
||||
f_eval(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
char *s;
|
||||
const char *s;
|
||||
mrb_int len;
|
||||
mrb_value binding = mrb_nil_value();
|
||||
char *file = NULL;
|
||||
const char *file = NULL;
|
||||
mrb_int line = 1;
|
||||
struct RProc *proc;
|
||||
|
||||
@@ -154,9 +154,9 @@ f_instance_eval(mrb_state *mrb, mrb_value self)
|
||||
mrb_get_args(mrb, "*!&", &argv, &argc, &b);
|
||||
|
||||
if (mrb_nil_p(b)) {
|
||||
char *s;
|
||||
const char *s;
|
||||
mrb_int len;
|
||||
char *file = NULL;
|
||||
const char *file = NULL;
|
||||
mrb_int line = 1;
|
||||
mrb_value cv;
|
||||
struct RProc *proc;
|
||||
@@ -179,7 +179,7 @@ void
|
||||
mrb_mruby_eval_gem_init(mrb_state* mrb)
|
||||
{
|
||||
mrb_define_module_function(mrb, mrb->kernel_module, "eval", f_eval, MRB_ARGS_ARG(1, 3));
|
||||
mrb_define_method(mrb, mrb_class_get(mrb, "BasicObject"), "instance_eval", f_instance_eval, MRB_ARGS_OPT(3)|MRB_ARGS_BLOCK());
|
||||
mrb_define_method(mrb, mrb_class_get_id(mrb, MRB_SYM(BasicObject)), "instance_eval", f_instance_eval, MRB_ARGS_OPT(3)|MRB_ARGS_BLOCK());
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -10,10 +10,10 @@ istruct_test_initialize(mrb_state *mrb, mrb_value self)
|
||||
mrb_int size = mrb_istruct_size();
|
||||
mrb_value object = mrb_get_arg1(mrb);
|
||||
|
||||
if (mrb_fixnum_p(object)) {
|
||||
if (mrb_integer_p(object)) {
|
||||
strncpy(string, "fixnum", size-1);
|
||||
}
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
else if (mrb_float_p(object)) {
|
||||
strncpy(string, "float", size-1);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ class File < IO
|
||||
attr_accessor :path
|
||||
|
||||
def initialize(fd_or_path, mode = "r", perm = 0666)
|
||||
if fd_or_path.kind_of? Fixnum
|
||||
if fd_or_path.kind_of? Integer
|
||||
super(fd_or_path, mode)
|
||||
else
|
||||
@path = fd_or_path
|
||||
@@ -11,6 +11,11 @@ class File < IO
|
||||
end
|
||||
end
|
||||
|
||||
def mtime
|
||||
t = self._mtime
|
||||
t && Time.at(t)
|
||||
end
|
||||
|
||||
def self.join(*names)
|
||||
return "" if names.empty?
|
||||
|
||||
@@ -186,9 +191,9 @@ class File < IO
|
||||
|
||||
def self.extname(filename)
|
||||
fname = self.basename(filename)
|
||||
return '' if fname[0] == '.' || fname.index('.').nil?
|
||||
ext = fname.split('.').last
|
||||
ext.empty? ? '' : ".#{ext}"
|
||||
epos = fname.rindex('.')
|
||||
return '' if epos == 0 || epos.nil?
|
||||
return fname[epos..-1]
|
||||
end
|
||||
|
||||
def self.path(filename)
|
||||
|
||||
@@ -186,7 +186,7 @@ class IO
|
||||
|
||||
def read(length = nil, outbuf = "")
|
||||
unless length.nil?
|
||||
unless length.is_a? Fixnum
|
||||
unless length.is_a? Integer
|
||||
raise TypeError.new "can't convert #{length.class} into Integer"
|
||||
end
|
||||
if length < 0
|
||||
@@ -229,7 +229,7 @@ class IO
|
||||
case arg
|
||||
when String
|
||||
rs = arg
|
||||
when Fixnum
|
||||
when Integer
|
||||
rs = "\n"
|
||||
limit = arg
|
||||
else
|
||||
|
||||
+43
-41
@@ -66,12 +66,16 @@
|
||||
#define LOCK_UN 8
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
#if !defined(_WIN32) || defined(MRB_MINGW32_LEGACY)
|
||||
typedef struct stat mrb_stat;
|
||||
# define mrb_stat(path, sb) stat(path, sb)
|
||||
# define mrb_fstat(fd, sb) fstat(fd, sb)
|
||||
#elif defined MRB_INT32
|
||||
typedef struct _stat32 mrb_stat;
|
||||
# define mrb_stat(path, sb) _stat32(path, sb)
|
||||
# define mrb_fstat(fd, sb) _fstat32(fd, sb)
|
||||
#else
|
||||
typedef struct __stat64 mrb_stat;
|
||||
typedef struct _stat64 mrb_stat;
|
||||
# define mrb_stat(path, sb) _stat64(path, sb)
|
||||
# define mrb_fstat(fd, sb) _fstat64(fd, sb)
|
||||
#endif
|
||||
@@ -390,15 +394,12 @@ mrb_file__gethome(mrb_state *mrb, mrb_value klass)
|
||||
static mrb_value
|
||||
mrb_file_mtime(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value obj;
|
||||
struct stat st;
|
||||
int fd;
|
||||
int fd = mrb_io_fileno(mrb, self);
|
||||
mrb_stat st;
|
||||
|
||||
obj = mrb_obj_value(mrb_class_get(mrb, "Time"));
|
||||
fd = mrb_io_fileno(mrb, self);
|
||||
if (fstat(fd, &st) == -1)
|
||||
if (mrb_fstat(fd, &st) == -1)
|
||||
return mrb_false_value();
|
||||
return mrb_funcall(mrb, obj, "at", 1, mrb_fixnum_value(st.st_mtime));
|
||||
return mrb_int_value(mrb, (mrb_int)st.st_mtime);
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
@@ -447,8 +448,8 @@ mrb_file_size(mrb_state *mrb, mrb_value self)
|
||||
}
|
||||
|
||||
if (st.st_size > MRB_INT_MAX) {
|
||||
#ifdef MRB_WITHOUT_FLOAT
|
||||
mrb_raise(mrb, E_RUNTIME_ERROR, "File#size too large for MRB_WITHOUT_FLOAT");
|
||||
#ifdef MRB_NO_FLOAT
|
||||
mrb_raise(mrb, E_RUNTIME_ERROR, "File#size too large for MRB_NO_FLOAT");
|
||||
#else
|
||||
return mrb_float_value(mrb, (mrb_float)st.st_size);
|
||||
#endif
|
||||
@@ -556,7 +557,8 @@ mrb_file_s_readlink(mrb_state *mrb, mrb_value klass) {
|
||||
mrb_raise(mrb, E_NOTIMP_ERROR, "readlink is not supported on this platform");
|
||||
return mrb_nil_value(); // unreachable
|
||||
#else
|
||||
char *path, *buf, *tmp;
|
||||
const char *path;
|
||||
char *buf, *tmp;
|
||||
size_t bufsize = 100;
|
||||
ssize_t rc;
|
||||
mrb_value ret;
|
||||
@@ -608,40 +610,40 @@ 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, "mtime", mrb_file_mtime, 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));
|
||||
|
||||
cnst = mrb_define_module_under(mrb, file, "Constants");
|
||||
mrb_define_const(mrb, cnst, "LOCK_SH", mrb_fixnum_value(LOCK_SH));
|
||||
mrb_define_const(mrb, cnst, "LOCK_EX", mrb_fixnum_value(LOCK_EX));
|
||||
mrb_define_const(mrb, cnst, "LOCK_UN", mrb_fixnum_value(LOCK_UN));
|
||||
mrb_define_const(mrb, cnst, "LOCK_NB", mrb_fixnum_value(LOCK_NB));
|
||||
mrb_define_const(mrb, cnst, "SEPARATOR", mrb_str_new_cstr(mrb, FILE_SEPARATOR));
|
||||
mrb_define_const(mrb, cnst, "PATH_SEPARATOR", mrb_str_new_cstr(mrb, PATH_SEPARATOR));
|
||||
cnst = mrb_define_module_under_id(mrb, file, MRB_SYM(Constants));
|
||||
mrb_define_const_id(mrb, cnst, MRB_SYM(LOCK_SH), mrb_fixnum_value(LOCK_SH));
|
||||
mrb_define_const_id(mrb, cnst, MRB_SYM(LOCK_EX), mrb_fixnum_value(LOCK_EX));
|
||||
mrb_define_const_id(mrb, cnst, MRB_SYM(LOCK_UN), mrb_fixnum_value(LOCK_UN));
|
||||
mrb_define_const_id(mrb, cnst, MRB_SYM(LOCK_NB), mrb_fixnum_value(LOCK_NB));
|
||||
mrb_define_const_id(mrb, cnst, MRB_SYM(SEPARATOR), mrb_str_new_cstr(mrb, FILE_SEPARATOR));
|
||||
mrb_define_const_id(mrb, cnst, MRB_SYM(PATH_SEPARATOR), mrb_str_new_cstr(mrb, PATH_SEPARATOR));
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
mrb_define_const(mrb, cnst, "ALT_SEPARATOR", mrb_str_new_cstr(mrb, FILE_ALT_SEPARATOR));
|
||||
mrb_define_const_id(mrb, cnst, MRB_SYM(ALT_SEPARATOR), mrb_str_new_cstr(mrb, FILE_ALT_SEPARATOR));
|
||||
#else
|
||||
mrb_define_const(mrb, cnst, "ALT_SEPARATOR", mrb_nil_value());
|
||||
mrb_define_const_id(mrb, cnst, MRB_SYM(ALT_SEPARATOR), mrb_nil_value());
|
||||
#endif
|
||||
mrb_define_const(mrb, cnst, "NULL", mrb_str_new_cstr(mrb, NULL_FILE));
|
||||
mrb_define_const_id(mrb, cnst, MRB_SYM(NULL), mrb_str_new_cstr(mrb, NULL_FILE));
|
||||
|
||||
mrb_define_const(mrb, cnst, "RDONLY", mrb_fixnum_value(MRB_O_RDONLY));
|
||||
mrb_define_const(mrb, cnst, "WRONLY", mrb_fixnum_value(MRB_O_WRONLY));
|
||||
mrb_define_const(mrb, cnst, "RDWR", mrb_fixnum_value(MRB_O_RDWR));
|
||||
mrb_define_const(mrb, cnst, "APPEND", mrb_fixnum_value(MRB_O_APPEND));
|
||||
mrb_define_const(mrb, cnst, "CREAT", mrb_fixnum_value(MRB_O_CREAT));
|
||||
mrb_define_const(mrb, cnst, "EXCL", mrb_fixnum_value(MRB_O_EXCL));
|
||||
mrb_define_const(mrb, cnst, "TRUNC", mrb_fixnum_value(MRB_O_TRUNC));
|
||||
mrb_define_const(mrb, cnst, "NONBLOCK", mrb_fixnum_value(MRB_O_NONBLOCK));
|
||||
mrb_define_const(mrb, cnst, "NOCTTY", mrb_fixnum_value(MRB_O_NOCTTY));
|
||||
mrb_define_const(mrb, cnst, "BINARY", mrb_fixnum_value(MRB_O_BINARY));
|
||||
mrb_define_const(mrb, cnst, "SHARE_DELETE", mrb_fixnum_value(MRB_O_SHARE_DELETE));
|
||||
mrb_define_const(mrb, cnst, "SYNC", mrb_fixnum_value(MRB_O_SYNC));
|
||||
mrb_define_const(mrb, cnst, "DSYNC", mrb_fixnum_value(MRB_O_DSYNC));
|
||||
mrb_define_const(mrb, cnst, "RSYNC", mrb_fixnum_value(MRB_O_RSYNC));
|
||||
mrb_define_const(mrb, cnst, "NOFOLLOW", mrb_fixnum_value(MRB_O_NOFOLLOW));
|
||||
mrb_define_const(mrb, cnst, "NOATIME", mrb_fixnum_value(MRB_O_NOATIME));
|
||||
mrb_define_const(mrb, cnst, "DIRECT", mrb_fixnum_value(MRB_O_DIRECT));
|
||||
mrb_define_const(mrb, cnst, "TMPFILE", mrb_fixnum_value(MRB_O_TMPFILE));
|
||||
mrb_define_const_id(mrb, cnst, MRB_SYM(RDONLY), mrb_fixnum_value(MRB_O_RDONLY));
|
||||
mrb_define_const_id(mrb, cnst, MRB_SYM(WRONLY), mrb_fixnum_value(MRB_O_WRONLY));
|
||||
mrb_define_const_id(mrb, cnst, MRB_SYM(RDWR), mrb_fixnum_value(MRB_O_RDWR));
|
||||
mrb_define_const_id(mrb, cnst, MRB_SYM(APPEND), mrb_fixnum_value(MRB_O_APPEND));
|
||||
mrb_define_const_id(mrb, cnst, MRB_SYM(CREAT), mrb_fixnum_value(MRB_O_CREAT));
|
||||
mrb_define_const_id(mrb, cnst, MRB_SYM(EXCL), mrb_fixnum_value(MRB_O_EXCL));
|
||||
mrb_define_const_id(mrb, cnst, MRB_SYM(TRUNC), mrb_fixnum_value(MRB_O_TRUNC));
|
||||
mrb_define_const_id(mrb, cnst, MRB_SYM(NONBLOCK), mrb_fixnum_value(MRB_O_NONBLOCK));
|
||||
mrb_define_const_id(mrb, cnst, MRB_SYM(NOCTTY), mrb_fixnum_value(MRB_O_NOCTTY));
|
||||
mrb_define_const_id(mrb, cnst, MRB_SYM(BINARY), mrb_fixnum_value(MRB_O_BINARY));
|
||||
mrb_define_const_id(mrb, cnst, MRB_SYM(SHARE_DELETE), mrb_fixnum_value(MRB_O_SHARE_DELETE));
|
||||
mrb_define_const_id(mrb, cnst, MRB_SYM(SYNC), mrb_fixnum_value(MRB_O_SYNC));
|
||||
mrb_define_const_id(mrb, cnst, MRB_SYM(DSYNC), mrb_fixnum_value(MRB_O_DSYNC));
|
||||
mrb_define_const_id(mrb, cnst, MRB_SYM(RSYNC), mrb_fixnum_value(MRB_O_RSYNC));
|
||||
mrb_define_const_id(mrb, cnst, MRB_SYM(NOFOLLOW), mrb_fixnum_value(MRB_O_NOFOLLOW));
|
||||
mrb_define_const_id(mrb, cnst, MRB_SYM(NOATIME), mrb_fixnum_value(MRB_O_NOATIME));
|
||||
mrb_define_const_id(mrb, cnst, MRB_SYM(DIRECT), mrb_fixnum_value(MRB_O_DIRECT));
|
||||
mrb_define_const_id(mrb, cnst, MRB_SYM(TMPFILE), mrb_fixnum_value(MRB_O_TMPFILE));
|
||||
}
|
||||
|
||||
@@ -66,11 +66,13 @@ mrb_stat(mrb_state *mrb, mrb_value obj, struct stat *st)
|
||||
return mrb_stat0(mrb, obj, st, 0);
|
||||
}
|
||||
|
||||
#ifdef S_ISLNK
|
||||
static int
|
||||
mrb_lstat(mrb_state *mrb, mrb_value obj, struct stat *st)
|
||||
{
|
||||
return mrb_stat0(mrb, obj, st, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Document-method: directory?
|
||||
@@ -302,7 +304,7 @@ mrb_filetest_s_size(mrb_state *mrb, mrb_value klass)
|
||||
if (mrb_stat(mrb, obj, &st) < 0)
|
||||
mrb_sys_fail(mrb, "mrb_stat");
|
||||
|
||||
return mrb_fixnum_value(st.st_size);
|
||||
return mrb_int_value(mrb, st.st_size);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -324,7 +326,7 @@ mrb_filetest_s_size_p(mrb_state *mrb, mrb_value klass)
|
||||
if (st.st_size == 0)
|
||||
return mrb_nil_value();
|
||||
|
||||
return mrb_fixnum_value(st.st_size);
|
||||
return mrb_int_value(mrb, st.st_size);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
+48
-33
@@ -18,6 +18,7 @@
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <winsock.h>
|
||||
#include <io.h>
|
||||
#include <basetsd.h>
|
||||
#define open _open
|
||||
#define close _close
|
||||
#define dup _dup
|
||||
@@ -32,6 +33,12 @@
|
||||
typedef long fsuseconds_t;
|
||||
typedef int fmode_t;
|
||||
typedef int mrb_io_read_write_size;
|
||||
#ifndef MRB_MINGW32_LEGACY
|
||||
#if !defined(_SSIZE_T_) && !defined(_SSIZE_T_DEFINED) && \
|
||||
!defined(__have_typedef_ssize_t)
|
||||
typedef SSIZE_T ssize_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef O_TMPFILE
|
||||
#define O_TMPFILE O_TEMPORARY
|
||||
@@ -95,14 +102,14 @@ io_set_process_status(mrb_state *mrb, pid_t pid, int status)
|
||||
mrb_value v;
|
||||
|
||||
c_status = NULL;
|
||||
if (mrb_class_defined(mrb, "Process")) {
|
||||
c_process = mrb_module_get(mrb, "Process");
|
||||
if (mrb_const_defined(mrb, mrb_obj_value(c_process), mrb_intern_cstr(mrb, "Status"))) {
|
||||
c_status = mrb_class_get_under(mrb, c_process, "Status");
|
||||
if (mrb_class_defined_id(mrb, MRB_SYM(Process))) {
|
||||
c_process = mrb_module_get_id(mrb, MRB_SYM(Process));
|
||||
if (mrb_const_defined(mrb, mrb_obj_value(c_process), MRB_SYM(Status))) {
|
||||
c_status = mrb_class_get_under_id(mrb, c_process, MRB_SYM(Status));
|
||||
}
|
||||
}
|
||||
if (c_status != NULL) {
|
||||
v = mrb_funcall(mrb, mrb_obj_value(c_status), "new", 2, mrb_fixnum_value(pid), mrb_fixnum_value(status));
|
||||
v = mrb_funcall_id(mrb, mrb_obj_value(c_status), MRB_SYM(new), 2, mrb_fixnum_value(pid), mrb_fixnum_value(status));
|
||||
} else {
|
||||
v = mrb_fixnum_value(WEXITSTATUS(status));
|
||||
}
|
||||
@@ -320,19 +327,16 @@ mrb_io_alloc(mrb_state *mrb)
|
||||
#endif
|
||||
|
||||
static int
|
||||
option_to_fd(mrb_state *mrb, mrb_value hash, const char *key)
|
||||
option_to_fd(mrb_state *mrb, mrb_value v)
|
||||
{
|
||||
mrb_value opt;
|
||||
if (mrb_undef_p(v)) return -1;
|
||||
if (mrb_nil_p(v)) return -1;
|
||||
|
||||
if (!mrb_hash_p(hash)) return -1;
|
||||
opt = mrb_hash_fetch(mrb, hash, mrb_symbol_value(mrb_intern_static(mrb, key, strlen(key))), mrb_nil_value());
|
||||
if (mrb_nil_p(opt)) return -1;
|
||||
|
||||
switch (mrb_type(opt)) {
|
||||
switch (mrb_type(v)) {
|
||||
case MRB_TT_DATA: /* IO */
|
||||
return mrb_io_fileno(mrb, opt);
|
||||
case MRB_TT_FIXNUM:
|
||||
return (int)mrb_fixnum(opt);
|
||||
return mrb_io_fileno(mrb, v);
|
||||
case MRB_TT_INTEGER:
|
||||
return (int)mrb_integer(v);
|
||||
default:
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong exec redirect action");
|
||||
break;
|
||||
@@ -346,8 +350,14 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
|
||||
{
|
||||
mrb_value cmd, io;
|
||||
mrb_value mode = mrb_str_new_cstr(mrb, "r");
|
||||
mrb_value opt = mrb_hash_new(mrb);
|
||||
|
||||
mrb_value kv[3];
|
||||
mrb_sym knames[3] = {MRB_SYM(in), MRB_SYM(out), MRB_SYM(err)};
|
||||
const mrb_kwargs kw = {
|
||||
3, 0,
|
||||
knames,
|
||||
kv,
|
||||
NULL,
|
||||
};
|
||||
struct mrb_io *fptr;
|
||||
const char *pname;
|
||||
int pid = 0, flags;
|
||||
@@ -359,23 +369,22 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
|
||||
HANDLE ofd[2];
|
||||
|
||||
int doexec;
|
||||
int opt_in, opt_out, opt_err;
|
||||
|
||||
ifd[0] = INVALID_HANDLE_VALUE;
|
||||
ifd[1] = INVALID_HANDLE_VALUE;
|
||||
ofd[0] = INVALID_HANDLE_VALUE;
|
||||
ofd[1] = INVALID_HANDLE_VALUE;
|
||||
|
||||
mrb_get_args(mrb, "S|oH", &cmd, &mode, &opt);
|
||||
mrb_get_args(mrb, "S|o:", &cmd, &mode, &kw, &kv);
|
||||
io = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_ptr(klass), NULL, &mrb_io_type));
|
||||
|
||||
pname = RSTRING_CSTR(mrb, cmd);
|
||||
flags = mrb_io_mode_to_flags(mrb, mode);
|
||||
|
||||
doexec = (strcmp("-", pname) != 0);
|
||||
opt_in = option_to_fd(mrb, opt, "in");
|
||||
opt_out = option_to_fd(mrb, opt, "out");
|
||||
opt_err = option_to_fd(mrb, opt, "err");
|
||||
option_to_fd(mrb, kv[0]);
|
||||
option_to_fd(mrb, kv[1]);
|
||||
option_to_fd(mrb, kv[2]);
|
||||
|
||||
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
saAttr.bInheritHandle = TRUE;
|
||||
@@ -451,8 +460,14 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
|
||||
{
|
||||
mrb_value cmd, io, result;
|
||||
mrb_value mode = mrb_str_new_cstr(mrb, "r");
|
||||
mrb_value opt = mrb_hash_new(mrb);
|
||||
|
||||
mrb_value kv[3];
|
||||
mrb_sym knames[3] = {MRB_SYM(in), MRB_SYM(out), MRB_SYM(err)};
|
||||
const mrb_kwargs kw = {
|
||||
3, 0,
|
||||
knames,
|
||||
kv,
|
||||
NULL,
|
||||
};
|
||||
struct mrb_io *fptr;
|
||||
const char *pname;
|
||||
int pid, flags, fd, write_fd = -1;
|
||||
@@ -462,16 +477,16 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
|
||||
int saved_errno;
|
||||
int opt_in, opt_out, opt_err;
|
||||
|
||||
mrb_get_args(mrb, "S|oH", &cmd, &mode, &opt);
|
||||
mrb_get_args(mrb, "S|o:", &cmd, &mode, &kw);
|
||||
io = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_ptr(klass), NULL, &mrb_io_type));
|
||||
|
||||
pname = RSTRING_CSTR(mrb, cmd);
|
||||
flags = mrb_io_mode_to_flags(mrb, mode);
|
||||
|
||||
doexec = (strcmp("-", pname) != 0);
|
||||
opt_in = option_to_fd(mrb, opt, "in");
|
||||
opt_out = option_to_fd(mrb, opt, "out");
|
||||
opt_err = option_to_fd(mrb, opt, "err");
|
||||
opt_in = option_to_fd(mrb, kv[0]);
|
||||
opt_out = option_to_fd(mrb, kv[1]);
|
||||
opt_err = option_to_fd(mrb, kv[2]);
|
||||
|
||||
if (OPEN_READABLE_P(flags)) {
|
||||
if (pipe(pr) == -1) {
|
||||
@@ -966,10 +981,10 @@ mrb_io_sysseek(mrb_state *mrb, mrb_value io)
|
||||
mrb_sys_fail(mrb, "sysseek");
|
||||
}
|
||||
if (pos > MRB_INT_MAX) {
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
return mrb_float_value(mrb, (mrb_float)pos);
|
||||
#else
|
||||
mrb_raise(mrb, E_IO_ERROR, "sysseek reached too far for MRB_WITHOUT_FLOAT");
|
||||
mrb_raise(mrb, E_IO_ERROR, "sysseek reached too far for MRB_NO_FLOAT");
|
||||
#endif
|
||||
} else {
|
||||
return mrb_fixnum_value(pos);
|
||||
@@ -1069,12 +1084,12 @@ time2timeval(mrb_state *mrb, mrb_value time)
|
||||
struct timeval t = { 0, 0 };
|
||||
|
||||
switch (mrb_type(time)) {
|
||||
case MRB_TT_FIXNUM:
|
||||
t.tv_sec = (ftime_t)mrb_fixnum(time);
|
||||
case MRB_TT_INTEGER:
|
||||
t.tv_sec = (ftime_t)mrb_integer(time);
|
||||
t.tv_usec = 0;
|
||||
break;
|
||||
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
case MRB_TT_FLOAT:
|
||||
t.tv_sec = (ftime_t)mrb_float(time);
|
||||
t.tv_usec = (fsuseconds_t)((mrb_float(time) - t.tv_sec) * 1000000.0);
|
||||
|
||||
@@ -51,6 +51,8 @@ assert('File.extname') do
|
||||
assert_equal '', File.extname('foo/.bar')
|
||||
assert_equal '', File.extname('foo.txt/bar')
|
||||
assert_equal '', File.extname('.foo')
|
||||
assert_equal '.rb', File.extname('.a.rb')
|
||||
assert_equal '.', File.extname('foo.')
|
||||
end
|
||||
|
||||
assert('File#flock') do
|
||||
|
||||
@@ -7,7 +7,7 @@ $cr, $crlf, $cmd = MRubyIOTestUtil.win? ? [1, "\r\n", "cmd /c "] : [0, "\n", ""]
|
||||
def assert_io_open(meth)
|
||||
assert "assert_io_open" do
|
||||
fd = IO.sysopen($mrbtest_io_rfname)
|
||||
assert_equal Fixnum, fd.class
|
||||
assert_equal Integer, fd.class
|
||||
io1 = IO.__send__(meth, fd)
|
||||
begin
|
||||
assert_equal IO, io1.class
|
||||
@@ -27,7 +27,6 @@ def assert_io_open(meth)
|
||||
|
||||
assert_raise(RuntimeError) { IO.__send__(meth, 1023) } # For Windows
|
||||
assert_raise(RuntimeError) { IO.__send__(meth, 1 << 26) }
|
||||
assert_raise(RuntimeError) { IO.__send__(meth, 1 << 32) } if (1 << 32).kind_of?(Integer)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -433,7 +432,7 @@ assert('IO.popen') do
|
||||
$? = nil
|
||||
io = IO.popen("#{$cmd}echo mruby-io")
|
||||
assert_true io.close_on_exec?
|
||||
assert_equal Fixnum, io.pid.class
|
||||
assert_equal Integer, io.pid.class
|
||||
|
||||
out = io.read
|
||||
assert_equal out.class, String
|
||||
|
||||
@@ -57,7 +57,7 @@ mrb_f_caller(mrb_state *mrb, mrb_value self)
|
||||
return mrb_ary_new(mrb);
|
||||
}
|
||||
|
||||
return mrb_funcall(mrb, bt, "[]", 2, mrb_fixnum_value(lev), mrb_fixnum_value(n));
|
||||
return mrb_funcall_id(mrb, bt, MRB_QSYM(aref), 2, mrb_fixnum_value(lev), mrb_fixnum_value(n));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -84,7 +84,7 @@ mrb_f_method(mrb_state *mrb, mrb_value self)
|
||||
* call-seq:
|
||||
* Integer(arg,base=0) -> integer
|
||||
*
|
||||
* Converts <i>arg</i> to a <code>Fixnum</code>.
|
||||
* Converts <i>arg</i> to a <code>Integer</code>.
|
||||
* Numeric types are converted directly (with floating point numbers
|
||||
* being truncated). <i>base</i> (0, or between 2 and 36) is a base for
|
||||
* integer string representation. If <i>arg</i> is a <code>String</code>,
|
||||
@@ -112,7 +112,7 @@ mrb_f_integer(mrb_state *mrb, mrb_value self)
|
||||
return mrb_convert_to_integer(mrb, arg, base);
|
||||
}
|
||||
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
/*
|
||||
* call-seq:
|
||||
* Float(arg) -> float
|
||||
@@ -151,7 +151,7 @@ mrb_f_string(mrb_state *mrb, mrb_value self)
|
||||
mrb_value arg = mrb_get_arg1(mrb);
|
||||
mrb_value tmp;
|
||||
|
||||
tmp = mrb_convert_type(mrb, arg, MRB_TT_STRING, "String", "to_s");
|
||||
tmp = mrb_type_convert(mrb, arg, MRB_TT_STRING, MRB_SYM(to_s));
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ mrb_f_array(mrb_state *mrb, mrb_value self)
|
||||
mrb_value arg = mrb_get_arg1(mrb);
|
||||
mrb_value tmp;
|
||||
|
||||
tmp = mrb_check_convert_type(mrb, arg, MRB_TT_ARRAY, "Array", "to_a");
|
||||
tmp = mrb_type_convert_check(mrb, arg, MRB_TT_ARRAY, MRB_SYM(to_a));
|
||||
if (mrb_nil_p(tmp)) {
|
||||
return mrb_ary_new_from_values(mrb, 1, &arg);
|
||||
}
|
||||
@@ -212,7 +212,7 @@ mrb_mruby_kernel_ext_gem_init(mrb_state *mrb)
|
||||
mrb_define_module_function(mrb, krn, "caller", mrb_f_caller, MRB_ARGS_OPT(2));
|
||||
mrb_define_method(mrb, krn, "__method__", mrb_f_method, MRB_ARGS_NONE());
|
||||
mrb_define_module_function(mrb, krn, "Integer", mrb_f_integer, MRB_ARGS_ARG(1,1));
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
mrb_define_module_function(mrb, krn, "Float", mrb_f_float, MRB_ARGS_REQ(1));
|
||||
#endif
|
||||
mrb_define_module_function(mrb, krn, "String", mrb_f_string, MRB_ARGS_REQ(1));
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
** See Copyright Notice in mruby.h
|
||||
*/
|
||||
|
||||
#ifdef MRB_WITHOUT_FLOAT
|
||||
# error Math conflicts 'MRB_WITHOUT_FLOAT' configuration in your 'build_config.rb'
|
||||
#ifdef MRB_NO_FLOAT
|
||||
# error Math conflicts with 'MRB_NO_FLOAT' configuration
|
||||
#endif
|
||||
|
||||
#include <mruby.h>
|
||||
@@ -16,8 +16,8 @@
|
||||
static void
|
||||
domain_error(mrb_state *mrb, const char *func)
|
||||
{
|
||||
struct RClass *math = mrb_module_get(mrb, "Math");
|
||||
struct RClass *domainerror = mrb_class_get_under(mrb, math, "DomainError");
|
||||
struct RClass *math = mrb_module_get_id(mrb, MRB_SYM(Math));
|
||||
struct RClass *domainerror = mrb_class_get_under_id(mrb, math, MRB_SYM(DomainError));
|
||||
mrb_raisef(mrb, domainerror, "Numerical argument is out of domain - %s", func);
|
||||
}
|
||||
|
||||
@@ -629,7 +629,7 @@ math_cbrt(mrb_state *mrb, mrb_value obj)
|
||||
* Math.frexp(numeric) -> [ fraction, exponent ]
|
||||
*
|
||||
* Returns a two-element array containing the normalized fraction (a
|
||||
* <code>Float</code>) and exponent (a <code>Fixnum</code>) of
|
||||
* <code>Float</code>) and exponent (a <code>Integer</code>) of
|
||||
* <i>numeric</i>.
|
||||
*
|
||||
* fraction, exponent = Math.frexp(1234) #=> [0.6025390625, 11]
|
||||
@@ -730,18 +730,18 @@ mrb_mruby_math_gem_init(mrb_state* mrb)
|
||||
struct RClass *mrb_math;
|
||||
mrb_math = mrb_define_module(mrb, "Math");
|
||||
|
||||
mrb_define_class_under(mrb, mrb_math, "DomainError", mrb->eStandardError_class);
|
||||
mrb_define_class_under_id(mrb, mrb_math, MRB_SYM(DomainError), mrb->eStandardError_class);
|
||||
|
||||
#ifdef M_PI
|
||||
mrb_define_const(mrb, mrb_math, "PI", mrb_float_value(mrb, M_PI));
|
||||
mrb_define_const_id(mrb, mrb_math, MRB_SYM(PI), mrb_float_value(mrb, M_PI));
|
||||
#else
|
||||
mrb_define_const(mrb, mrb_math, "PI", mrb_float_value(mrb, atan(1.0)*4.0));
|
||||
mrb_define_const_id(mrb, mrb_math, MRB_SYM(PI), mrb_float_value(mrb, atan(1.0)*4.0));
|
||||
#endif
|
||||
|
||||
#ifdef M_E
|
||||
mrb_define_const(mrb, mrb_math, "E", mrb_float_value(mrb, M_E));
|
||||
mrb_define_const_id(mrb, mrb_math, MRB_SYM(E), mrb_float_value(mrb, M_E));
|
||||
#else
|
||||
mrb_define_const(mrb, mrb_math, "E", mrb_float_value(mrb, exp(1.0)));
|
||||
mrb_define_const_id(mrb, mrb_math, MRB_SYM(E), mrb_float_value(mrb, exp(1.0)));
|
||||
#endif
|
||||
|
||||
mrb_define_module_function(mrb, mrb_math, "sin", math_sin, MRB_ARGS_REQ(1));
|
||||
|
||||
@@ -209,17 +209,18 @@ assert('Math.atan2') do
|
||||
assert_float(+Math::PI, Math.atan2(+0.0, -0.0))
|
||||
assert_float(-Math::PI, Math.atan2(-0.0, -0.0))
|
||||
|
||||
assert_float(0, Math.atan2(0, 1))
|
||||
assert_float(Math::PI / 4, Math.atan2(1, 1))
|
||||
assert_float(Math::PI / 2, Math.atan2(1, 0))
|
||||
|
||||
inf = Float::INFINITY
|
||||
skip "Math.atan2() return NaN" if Math.atan2(+inf, -inf).nan?
|
||||
expected = 3.0 * Math::PI / 4.0
|
||||
assert_float(+expected, Math.atan2(+inf, -inf))
|
||||
assert_float(-expected, Math.atan2(-inf, -inf))
|
||||
expected = Math::PI / 4.0
|
||||
assert_float(+expected, Math.atan2(+inf, +inf))
|
||||
assert_float(-expected, Math.atan2(-inf, +inf))
|
||||
|
||||
assert_float(0, Math.atan2(0, 1))
|
||||
assert_float(Math::PI / 4, Math.atan2(1, 1))
|
||||
assert_float(Math::PI / 2, Math.atan2(1, 0))
|
||||
end
|
||||
|
||||
assert('Math.ldexp') do
|
||||
|
||||
@@ -132,8 +132,8 @@ mrb_obj_ivar_set(mrb_state *mrb, mrb_value self)
|
||||
static mrb_value
|
||||
mrb_local_variables(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
struct RProc *proc;
|
||||
mrb_irep *irep;
|
||||
const struct RProc *proc;
|
||||
const mrb_irep *irep;
|
||||
mrb_value vars;
|
||||
size_t i;
|
||||
|
||||
@@ -148,8 +148,8 @@ mrb_local_variables(mrb_state *mrb, mrb_value self)
|
||||
irep = proc->body.irep;
|
||||
if (irep->lv) {
|
||||
for (i = 0; i + 1 < irep->nlocals; ++i) {
|
||||
if (irep->lv[i].name) {
|
||||
mrb_sym sym = irep->lv[i].name;
|
||||
if (irep->lv[i]) {
|
||||
mrb_sym sym = irep->lv[i];
|
||||
const char *name = mrb_sym_name(mrb, sym);
|
||||
switch (name[0]) {
|
||||
case '*': case '&':
|
||||
@@ -168,29 +168,50 @@ mrb_local_variables(mrb_state *mrb, mrb_value self)
|
||||
return mrb_hash_keys(mrb, vars);
|
||||
}
|
||||
|
||||
KHASH_DECLARE(st, mrb_sym, char, FALSE)
|
||||
KHASH_DECLARE(st, mrb_sym, char, FALSE);
|
||||
KHASH_DEFINE(st, mrb_sym, char, FALSE, kh_int_hash_func, kh_int_hash_equal);
|
||||
|
||||
union mt_ptr {
|
||||
struct RProc *proc;
|
||||
mrb_func_t func;
|
||||
};
|
||||
|
||||
struct mt_elem {
|
||||
union mt_ptr ptr;
|
||||
size_t func_p:1;
|
||||
mrb_sym key:sizeof(mrb_sym)*8-1;
|
||||
};
|
||||
|
||||
struct mt_set {
|
||||
khash_t(st) *set;
|
||||
khash_t(st) *undef;
|
||||
};
|
||||
|
||||
static int
|
||||
method_entry_i(mrb_state *mrb, mrb_sym mid, struct mt_elem *e, void *p)
|
||||
{
|
||||
struct mt_set *s = (struct mt_set*)p;
|
||||
|
||||
if (e->ptr.proc == 0) {
|
||||
if (s->undef) {
|
||||
kh_put(st, mrb, s->undef, mid);
|
||||
}
|
||||
}
|
||||
else if (s->undef == NULL ||
|
||||
kh_get(st, mrb, s->undef, mid) == kh_end(s->undef)) {
|
||||
kh_put(st, mrb, s->set, mid);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
method_entry_loop(mrb_state *mrb, struct RClass *klass, khash_t(st) *set, khash_t(st) *undef)
|
||||
{
|
||||
khint_t i;
|
||||
struct mt_set s;
|
||||
|
||||
khash_t(mt) *h = klass->mt;
|
||||
if (!h || kh_size(h) == 0) return;
|
||||
for (i=0;i<kh_end(h);i++) {
|
||||
if (kh_exist(h, i)) {
|
||||
mrb_method_t m = kh_value(h, i);
|
||||
if (MRB_METHOD_UNDEF_P(m)) {
|
||||
if (undef) {
|
||||
kh_put(st, mrb, undef, kh_key(h, i));
|
||||
}
|
||||
}
|
||||
else if (undef == NULL ||
|
||||
kh_get(st, mrb, undef, kh_key(h, i)) == kh_end(undef)) {
|
||||
kh_put(st, mrb, set, kh_key(h, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
s.set = set;
|
||||
s.undef = undef;
|
||||
mrb_mt_foreach(mrb, klass, method_entry_i, (void*)&s);
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
@@ -608,28 +629,6 @@ mrb_mod_instance_methods(mrb_state *mrb, mrb_value mod)
|
||||
return mrb_class_instance_method_list(mrb, recur, c, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
remove_method(mrb_state *mrb, mrb_value mod, mrb_sym mid)
|
||||
{
|
||||
struct RClass *c = mrb_class_ptr(mod);
|
||||
khash_t(mt) *h;
|
||||
khiter_t k;
|
||||
|
||||
MRB_CLASS_ORIGIN(c);
|
||||
h = c->mt;
|
||||
|
||||
if (h) {
|
||||
k = kh_get(mt, mrb, h, mid);
|
||||
if (k != kh_end(h)) {
|
||||
kh_del(mt, mrb, h, k);
|
||||
mrb_funcall(mrb, mod, "method_removed", 1, mrb_symbol_value(mid));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mrb_name_error(mrb, mid, "method '%n' not defined in %v", mid, mod);
|
||||
}
|
||||
|
||||
/* 15.2.2.4.41 */
|
||||
/*
|
||||
* call-seq:
|
||||
@@ -644,11 +643,13 @@ mrb_mod_remove_method(mrb_state *mrb, mrb_value mod)
|
||||
{
|
||||
mrb_int argc;
|
||||
mrb_value *argv;
|
||||
struct RClass *c = mrb_class_ptr(mod);
|
||||
|
||||
mrb_get_args(mrb, "*", &argv, &argc);
|
||||
mrb_check_frozen(mrb, mrb_obj_ptr(mod));
|
||||
while (argc--) {
|
||||
remove_method(mrb, mod, mrb_obj_to_sym(mrb, *argv));
|
||||
mrb_remove_method(mrb, c, mrb_obj_to_sym(mrb, *argv));
|
||||
mrb_funcall_id(mrb, mod, MRB_SYM(method_removed), 1, *argv);
|
||||
argv++;
|
||||
}
|
||||
return mod;
|
||||
@@ -664,7 +665,7 @@ mrb_mod_s_constants(mrb_state *mrb, mrb_value mod)
|
||||
static mrb_value
|
||||
mrb_mod_s_nesting(mrb_state *mrb, mrb_value mod)
|
||||
{
|
||||
struct RProc *proc;
|
||||
const struct RProc *proc;
|
||||
mrb_value ary;
|
||||
struct RClass *c = NULL;
|
||||
|
||||
@@ -684,6 +685,9 @@ mrb_mod_s_nesting(mrb_state *mrb, mrb_value mod)
|
||||
return ary;
|
||||
}
|
||||
|
||||
/* implementation of #send method */
|
||||
mrb_value mrb_f_send(mrb_state *mrb, mrb_value self);
|
||||
|
||||
void
|
||||
mrb_mruby_metaprog_gem_init(mrb_state* mrb)
|
||||
{
|
||||
|
||||
@@ -395,15 +395,15 @@ end
|
||||
|
||||
assert('alias_method and remove_method') do
|
||||
begin
|
||||
Fixnum.alias_method :to_s_, :to_s
|
||||
Fixnum.remove_method :to_s
|
||||
Integer.alias_method :to_s_, :to_s
|
||||
Integer.remove_method :to_s
|
||||
|
||||
assert_nothing_raised do
|
||||
# segfaults if mrb_cptr is used
|
||||
1.to_s
|
||||
end
|
||||
ensure
|
||||
Fixnum.alias_method :to_s, :to_s_
|
||||
Fixnum.remove_method :to_s_
|
||||
Integer.alias_method :to_s, :to_s_
|
||||
Integer.remove_method :to_s_
|
||||
end
|
||||
end
|
||||
|
||||
@@ -29,24 +29,24 @@ static mrb_value
|
||||
unbound_method_bind(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
struct RObject *me;
|
||||
mrb_value owner = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_owner"));
|
||||
mrb_value name = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_name"));
|
||||
mrb_value proc = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_proc"));
|
||||
mrb_value klass = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_klass"));
|
||||
mrb_value owner = mrb_iv_get(mrb, self, MRB_SYM(_owner));
|
||||
mrb_value name = mrb_iv_get(mrb, self, MRB_SYM(_name));
|
||||
mrb_value proc = mrb_iv_get(mrb, self, MRB_SYM(_proc));
|
||||
mrb_value klass = mrb_iv_get(mrb, self, MRB_SYM(_klass));
|
||||
mrb_value recv = mrb_get_arg1(mrb);
|
||||
|
||||
bind_check(mrb, recv, owner);
|
||||
me = method_object_alloc(mrb, mrb_class_get(mrb, "Method"));
|
||||
mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_owner"), owner);
|
||||
mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_recv"), recv);
|
||||
mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_name"), name);
|
||||
mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_proc"), proc);
|
||||
mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_klass"), klass);
|
||||
me = method_object_alloc(mrb, mrb_class_get_id(mrb, MRB_SYM(Method)));
|
||||
mrb_obj_iv_set(mrb, me, MRB_SYM(_owner), owner);
|
||||
mrb_obj_iv_set(mrb, me, MRB_SYM(_recv), recv);
|
||||
mrb_obj_iv_set(mrb, me, MRB_SYM(_name), name);
|
||||
mrb_obj_iv_set(mrb, me, MRB_SYM(_proc), proc);
|
||||
mrb_obj_iv_set(mrb, me, MRB_SYM(_klass), klass);
|
||||
|
||||
return mrb_obj_value(me);
|
||||
}
|
||||
|
||||
#define IV_GET(value, name) mrb_iv_get(mrb, value, mrb_intern_lit(mrb, name))
|
||||
#define IV_GET(value, name) mrb_iv_get(mrb, value, name)
|
||||
static mrb_value
|
||||
method_eql(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
@@ -61,22 +61,22 @@ method_eql(mrb_state *mrb, mrb_value self)
|
||||
if (mrb_class(mrb, self) != mrb_class(mrb, other))
|
||||
return mrb_false_value();
|
||||
|
||||
klass = mrb_class_ptr(IV_GET(self, "_klass"));
|
||||
if (klass != mrb_class_ptr(IV_GET(other, "_klass")))
|
||||
klass = mrb_class_ptr(IV_GET(self, MRB_SYM(_klass)));
|
||||
if (klass != mrb_class_ptr(IV_GET(other, MRB_SYM(_klass))))
|
||||
return mrb_false_value();
|
||||
|
||||
owner = mrb_class_ptr(IV_GET(self, "_owner"));
|
||||
if (owner != mrb_class_ptr(IV_GET(other, "_owner")))
|
||||
owner = mrb_class_ptr(IV_GET(self, MRB_SYM(_owner)));
|
||||
if (owner != mrb_class_ptr(IV_GET(other, MRB_SYM(_owner))))
|
||||
return mrb_false_value();
|
||||
|
||||
receiver = IV_GET(self, "_recv");
|
||||
if (!mrb_obj_equal(mrb, receiver, IV_GET(other, "_recv")))
|
||||
receiver = IV_GET(self, MRB_SYM(_recv));
|
||||
if (!mrb_obj_equal(mrb, receiver, IV_GET(other, MRB_SYM(_recv))))
|
||||
return mrb_false_value();
|
||||
|
||||
orig_proc = IV_GET(self, "_proc");
|
||||
other_proc = IV_GET(other, "_proc");
|
||||
orig_proc = IV_GET(self, MRB_SYM(_proc));
|
||||
other_proc = IV_GET(other, MRB_SYM(_proc));
|
||||
if (mrb_nil_p(orig_proc) && mrb_nil_p(other_proc)) {
|
||||
if (mrb_symbol(IV_GET(self, "_name")) == mrb_symbol(IV_GET(other, "_name")))
|
||||
if (mrb_symbol(IV_GET(self, MRB_SYM(_name))) == mrb_symbol(IV_GET(other, MRB_SYM(_name))))
|
||||
return mrb_true_value();
|
||||
else
|
||||
return mrb_false_value();
|
||||
@@ -118,7 +118,7 @@ mcall(mrb_state *mrb, mrb_value recv, mrb_value proc, mrb_value name, struct RCl
|
||||
if (mrb_nil_p(proc)) {
|
||||
mrb_value missing_argv = mrb_ary_new_from_values(mrb, argc, argv);
|
||||
mrb_ary_unshift(mrb, missing_argv, name);
|
||||
ret = mrb_funcall_argv(mrb, recv, mrb_intern_lit(mrb, "method_missing"), argc + 1, RARRAY_PTR(missing_argv));
|
||||
ret = mrb_funcall_argv(mrb, recv, MRB_SYM(method_missing), argc + 1, RARRAY_PTR(missing_argv));
|
||||
}
|
||||
else if (!mrb_nil_p(block)) {
|
||||
/*
|
||||
@@ -137,10 +137,10 @@ mcall(mrb_state *mrb, mrb_value recv, mrb_value proc, mrb_value name, struct RCl
|
||||
static mrb_value
|
||||
method_call(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value proc = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_proc"));
|
||||
mrb_value name = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_name"));
|
||||
mrb_value recv = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_recv"));
|
||||
struct RClass *owner = mrb_class_ptr(mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_owner")));
|
||||
mrb_value proc = mrb_iv_get(mrb, self, MRB_SYM(_proc));
|
||||
mrb_value name = mrb_iv_get(mrb, self, MRB_SYM(_name));
|
||||
mrb_value recv = mrb_iv_get(mrb, self, MRB_SYM(_recv));
|
||||
struct RClass *owner = mrb_class_ptr(mrb_iv_get(mrb, self, MRB_SYM(_owner)));
|
||||
mrb_int argc;
|
||||
mrb_value *argv, block;
|
||||
|
||||
@@ -151,10 +151,10 @@ method_call(mrb_state *mrb, mrb_value self)
|
||||
static mrb_value
|
||||
method_bcall(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value proc = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_proc"));
|
||||
mrb_value name = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_name"));
|
||||
mrb_value recv = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_recv"));
|
||||
mrb_value owner = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_owner"));
|
||||
mrb_value proc = mrb_iv_get(mrb, self, MRB_SYM(_proc));
|
||||
mrb_value name = mrb_iv_get(mrb, self, MRB_SYM(_name));
|
||||
mrb_value recv = mrb_iv_get(mrb, self, MRB_SYM(_recv));
|
||||
mrb_value owner = mrb_iv_get(mrb, self, MRB_SYM(_owner));
|
||||
mrb_int argc;
|
||||
mrb_value *argv, block;
|
||||
|
||||
@@ -167,17 +167,17 @@ static mrb_value
|
||||
method_unbind(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
struct RObject *ume;
|
||||
mrb_value owner = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_owner"));
|
||||
mrb_value name = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_name"));
|
||||
mrb_value proc = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_proc"));
|
||||
mrb_value klass = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_klass"));
|
||||
mrb_value owner = mrb_iv_get(mrb, self, MRB_SYM(_owner));
|
||||
mrb_value name = mrb_iv_get(mrb, self, MRB_SYM(_name));
|
||||
mrb_value proc = mrb_iv_get(mrb, self, MRB_SYM(_proc));
|
||||
mrb_value klass = mrb_iv_get(mrb, self, MRB_SYM(_klass));
|
||||
|
||||
ume = method_object_alloc(mrb, mrb_class_get(mrb, "UnboundMethod"));
|
||||
mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "_owner"), owner);
|
||||
mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "_recv"), mrb_nil_value());
|
||||
mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "_name"), name);
|
||||
mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "_proc"), proc);
|
||||
mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "_klass"), klass);
|
||||
mrb_obj_iv_set(mrb, ume, MRB_SYM(_owner), owner);
|
||||
mrb_obj_iv_set(mrb, ume, MRB_SYM(_recv), mrb_nil_value());
|
||||
mrb_obj_iv_set(mrb, ume, MRB_SYM(_name), name);
|
||||
mrb_obj_iv_set(mrb, ume, MRB_SYM(_proc), proc);
|
||||
mrb_obj_iv_set(mrb, ume, MRB_SYM(_klass), klass);
|
||||
|
||||
return mrb_obj_value(ume);
|
||||
}
|
||||
@@ -196,10 +196,10 @@ method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid)
|
||||
static mrb_value
|
||||
method_super_method(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value recv = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_recv"));
|
||||
mrb_value klass = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_klass"));
|
||||
mrb_value owner = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_owner"));
|
||||
mrb_value name = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_name"));
|
||||
mrb_value recv = mrb_iv_get(mrb, self, MRB_SYM(_recv));
|
||||
mrb_value klass = mrb_iv_get(mrb, self, MRB_SYM(_klass));
|
||||
mrb_value owner = mrb_iv_get(mrb, self, MRB_SYM(_owner));
|
||||
mrb_value name = mrb_iv_get(mrb, self, MRB_SYM(_name));
|
||||
struct RClass *super, *rklass;
|
||||
struct RProc *proc;
|
||||
struct RObject *me;
|
||||
@@ -225,11 +225,11 @@ method_super_method(mrb_state *mrb, mrb_value self)
|
||||
super = super->c;
|
||||
|
||||
me = method_object_alloc(mrb, mrb_obj_class(mrb, self));
|
||||
mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_owner"), mrb_obj_value(super));
|
||||
mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_recv"), recv);
|
||||
mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_name"), name);
|
||||
mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_proc"), mrb_obj_value(proc));
|
||||
mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_klass"), mrb_obj_value(rklass));
|
||||
mrb_obj_iv_set(mrb, me, MRB_SYM(_owner), mrb_obj_value(super));
|
||||
mrb_obj_iv_set(mrb, me, MRB_SYM(_recv), recv);
|
||||
mrb_obj_iv_set(mrb, me, MRB_SYM(_name), name);
|
||||
mrb_obj_iv_set(mrb, me, MRB_SYM(_proc), mrb_obj_value(proc));
|
||||
mrb_obj_iv_set(mrb, me, MRB_SYM(_klass), mrb_obj_value(rklass));
|
||||
|
||||
return mrb_obj_value(me);
|
||||
}
|
||||
@@ -237,7 +237,7 @@ method_super_method(mrb_state *mrb, mrb_value self)
|
||||
static mrb_value
|
||||
method_arity(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value proc = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_proc"));
|
||||
mrb_value proc = mrb_iv_get(mrb, self, MRB_SYM(_proc));
|
||||
mrb_int arity = mrb_nil_p(proc) ? -1 : mrb_proc_arity(mrb_proc_ptr(proc));
|
||||
return mrb_fixnum_value(arity);
|
||||
}
|
||||
@@ -245,7 +245,7 @@ method_arity(mrb_state *mrb, mrb_value self)
|
||||
static mrb_value
|
||||
method_source_location(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value proc = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_proc"));
|
||||
mrb_value proc = mrb_iv_get(mrb, self, MRB_SYM(_proc));
|
||||
struct RProc *rproc;
|
||||
struct RClass *orig;
|
||||
mrb_value ret;
|
||||
@@ -256,7 +256,7 @@ method_source_location(mrb_state *mrb, mrb_value self)
|
||||
rproc = mrb_proc_ptr(proc);
|
||||
orig = rproc->c;
|
||||
rproc->c = mrb->proc_class;
|
||||
ret = mrb_funcall(mrb, proc, "source_location", 0);
|
||||
ret = mrb_funcall_id(mrb, proc, MRB_SYM(source_location), 0);
|
||||
rproc->c = orig;
|
||||
return ret;
|
||||
}
|
||||
@@ -264,13 +264,13 @@ method_source_location(mrb_state *mrb, mrb_value self)
|
||||
static mrb_value
|
||||
method_parameters(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value proc = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_proc"));
|
||||
mrb_value proc = mrb_iv_get(mrb, self, MRB_SYM(_proc));
|
||||
struct RProc *rproc;
|
||||
struct RClass *orig;
|
||||
mrb_value ret;
|
||||
|
||||
if (mrb_nil_p(proc)) {
|
||||
mrb_value rest = mrb_symbol_value(mrb_intern_lit(mrb, "rest"));
|
||||
mrb_value rest = mrb_symbol_value(MRB_SYM(rest));
|
||||
mrb_value arest = mrb_ary_new_from_values(mrb, 1, &rest);
|
||||
return mrb_ary_new_from_values(mrb, 1, &arest);
|
||||
}
|
||||
@@ -278,7 +278,7 @@ method_parameters(mrb_state *mrb, mrb_value self)
|
||||
rproc = mrb_proc_ptr(proc);
|
||||
orig = rproc->c;
|
||||
rproc->c = mrb->proc_class;
|
||||
ret = mrb_funcall(mrb, proc, "parameters", 0);
|
||||
ret = mrb_funcall_id(mrb, proc, MRB_SYM(parameters), 0);
|
||||
rproc->c = orig;
|
||||
return ret;
|
||||
}
|
||||
@@ -286,9 +286,9 @@ method_parameters(mrb_state *mrb, mrb_value self)
|
||||
static mrb_value
|
||||
method_to_s(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value owner = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_owner"));
|
||||
mrb_value klass = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_klass"));
|
||||
mrb_value name = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_name"));
|
||||
mrb_value owner = mrb_iv_get(mrb, self, MRB_SYM(_owner));
|
||||
mrb_value klass = mrb_iv_get(mrb, self, MRB_SYM(_klass));
|
||||
mrb_value name = mrb_iv_get(mrb, self, MRB_SYM(_name));
|
||||
mrb_value str = mrb_str_new_lit(mrb, "#<");
|
||||
struct RClass *rklass;
|
||||
|
||||
@@ -322,10 +322,10 @@ mrb_search_method_owner(mrb_state *mrb, struct RClass *c, mrb_value obj, mrb_sym
|
||||
if (unbound) {
|
||||
goto name_error;
|
||||
}
|
||||
if (!mrb_respond_to(mrb, obj, mrb_intern_lit(mrb, "respond_to_missing?"))) {
|
||||
if (!mrb_respond_to(mrb, obj, MRB_QSYM(respond_to_missing_p))) {
|
||||
goto name_error;
|
||||
}
|
||||
ret = mrb_funcall(mrb, obj, "respond_to_missing?", 2, mrb_symbol_value(name), mrb_true_value());
|
||||
ret = mrb_funcall_id(mrb, obj, MRB_QSYM(respond_to_missing_p), 2, mrb_symbol_value(name), mrb_true_value());
|
||||
if (!mrb_test(ret)) {
|
||||
goto name_error;
|
||||
}
|
||||
@@ -354,11 +354,11 @@ mrb_kernel_method(mrb_state *mrb, mrb_value self)
|
||||
mrb_search_method_owner(mrb, mrb_class(mrb, self), self, name, &owner, &proc, FALSE);
|
||||
|
||||
me = method_object_alloc(mrb, mrb_class_get(mrb, "Method"));
|
||||
mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_owner"), mrb_obj_value(owner));
|
||||
mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_recv"), self);
|
||||
mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_name"), mrb_symbol_value(name));
|
||||
mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_proc"), proc ? mrb_obj_value(proc) : mrb_nil_value());
|
||||
mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_klass"), mrb_obj_value(mrb_class(mrb, self)));
|
||||
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(_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)));
|
||||
|
||||
return mrb_obj_value(me);
|
||||
}
|
||||
@@ -376,11 +376,11 @@ mrb_module_instance_method(mrb_state *mrb, mrb_value self)
|
||||
mrb_search_method_owner(mrb, mrb_class_ptr(self), self, name, &owner, &proc, TRUE);
|
||||
|
||||
ume = method_object_alloc(mrb, mrb_class_get(mrb, "UnboundMethod"));
|
||||
mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "_owner"), mrb_obj_value(owner));
|
||||
mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "_recv"), mrb_nil_value());
|
||||
mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "_name"), mrb_symbol_value(name));
|
||||
mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "_proc"), proc ? mrb_obj_value(proc) : mrb_nil_value());
|
||||
mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "_klass"), self);
|
||||
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);
|
||||
|
||||
return mrb_obj_value(ume);
|
||||
}
|
||||
@@ -388,19 +388,19 @@ mrb_module_instance_method(mrb_state *mrb, mrb_value self)
|
||||
static mrb_value
|
||||
method_owner(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
return mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_owner"));
|
||||
return mrb_iv_get(mrb, self, MRB_SYM(_owner));
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
method_receiver(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
return mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_recv"));
|
||||
return mrb_iv_get(mrb, self, MRB_SYM(_recv));
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
method_name(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
return mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_name"));
|
||||
return mrb_iv_get(mrb, self, MRB_SYM(_name));
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -77,7 +77,7 @@ end
|
||||
|
||||
assert 'instance' do
|
||||
assert_kind_of Method, 1.method(:+)
|
||||
assert_kind_of UnboundMethod, Fixnum.instance_method(:+)
|
||||
assert_kind_of UnboundMethod, Integer.instance_method(:+)
|
||||
end
|
||||
|
||||
assert 'Method#call' do
|
||||
@@ -404,9 +404,9 @@ assert 'UnboundMethod#arity' do
|
||||
end
|
||||
|
||||
assert 'UnboundMethod#==' do
|
||||
assert_false(Fixnum.instance_method(:+) == Fixnum.instance_method(:-))
|
||||
assert_true(Fixnum.instance_method(:+) == Fixnum.instance_method(:+))
|
||||
assert_false(Fixnum.instance_method(:+) == Float.instance_method(:+))
|
||||
assert_false(Integer.instance_method(:+) == Integer.instance_method(:-))
|
||||
assert_true(Integer.instance_method(:+) == Integer.instance_method(:+))
|
||||
assert_false(Integer.instance_method(:+) == Float.instance_method(:+))
|
||||
assert_true(UnboundMethod.instance_method(:==) == UnboundMethod.instance_method(:eql?))
|
||||
end
|
||||
|
||||
|
||||
@@ -53,24 +53,24 @@ mrb_int_nobits(mrb_state *mrb, mrb_value self)
|
||||
void
|
||||
mrb_mruby_numeric_ext_gem_init(mrb_state* mrb)
|
||||
{
|
||||
struct RClass *i = mrb_module_get(mrb, "Integral");
|
||||
struct RClass *i = mrb_class_get(mrb, "Integer");
|
||||
|
||||
mrb_define_method(mrb, i, "allbits?", mrb_int_allbits, MRB_ARGS_REQ(1));
|
||||
mrb_define_method(mrb, i, "anybits?", mrb_int_anybits, MRB_ARGS_REQ(1));
|
||||
mrb_define_method(mrb, i, "nobits?", mrb_int_nobits, MRB_ARGS_REQ(1));
|
||||
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
mrb_define_const(mrb, mrb->float_class, "RADIX", mrb_fixnum_value(MRB_FLT_RADIX));
|
||||
mrb_define_const(mrb, mrb->float_class, "MANT_DIG", mrb_fixnum_value(MRB_FLT_MANT_DIG));
|
||||
mrb_define_const(mrb, mrb->float_class, "EPSILON", mrb_float_value(mrb, MRB_FLT_EPSILON));
|
||||
mrb_define_const(mrb, mrb->float_class, "DIG", mrb_fixnum_value(MRB_FLT_DIG));
|
||||
mrb_define_const(mrb, mrb->float_class, "MIN_EXP", mrb_fixnum_value(MRB_FLT_MIN_EXP));
|
||||
mrb_define_const(mrb, mrb->float_class, "MIN", mrb_float_value(mrb, MRB_FLT_MIN));
|
||||
mrb_define_const(mrb, mrb->float_class, "MIN_10_EXP", mrb_fixnum_value(MRB_FLT_MIN_10_EXP));
|
||||
mrb_define_const(mrb, mrb->float_class, "MAX_EXP", mrb_fixnum_value(MRB_FLT_MAX_EXP));
|
||||
mrb_define_const(mrb, mrb->float_class, "MAX", mrb_float_value(mrb, MRB_FLT_MAX));
|
||||
mrb_define_const(mrb, mrb->float_class, "MAX_10_EXP", mrb_fixnum_value(MRB_FLT_MAX_10_EXP));
|
||||
#endif /* MRB_WITHOUT_FLOAT */
|
||||
#ifndef MRB_NO_FLOAT
|
||||
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));
|
||||
#endif /* MRB_NO_FLOAT */
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -17,7 +17,7 @@ nil_to_a(mrb_state *mrb, mrb_value obj)
|
||||
return mrb_ary_new(mrb);
|
||||
}
|
||||
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
/*
|
||||
* call-seq:
|
||||
* nil.to_f -> 0.0
|
||||
@@ -115,7 +115,7 @@ mrb_mruby_object_ext_gem_init(mrb_state* mrb)
|
||||
struct RClass * n = mrb->nil_class;
|
||||
|
||||
mrb_define_method(mrb, n, "to_a", nil_to_a, MRB_ARGS_NONE());
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
mrb_define_method(mrb, n, "to_f", nil_to_f, MRB_ARGS_NONE());
|
||||
#endif
|
||||
mrb_define_method(mrb, n, "to_h", nil_to_h, MRB_ARGS_NONE());
|
||||
@@ -123,7 +123,7 @@ mrb_mruby_object_ext_gem_init(mrb_state* mrb)
|
||||
|
||||
mrb_define_method(mrb, mrb->kernel_module, "itself", mrb_f_itself, MRB_ARGS_NONE());
|
||||
|
||||
mrb_define_method(mrb, mrb_class_get(mrb, "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", mrb_obj_instance_exec, MRB_ARGS_ANY() | MRB_ARGS_BLOCK());
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -2,6 +2,14 @@
|
||||
#include <mruby/gc.h>
|
||||
#include <mruby/hash.h>
|
||||
#include <mruby/class.h>
|
||||
#include <mruby/object.h>
|
||||
#include <mruby/numeric.h>
|
||||
#include <mruby/string.h>
|
||||
#include <mruby/array.h>
|
||||
#include <mruby/variable.h>
|
||||
#include <mruby/proc.h>
|
||||
#include <mruby/value.h>
|
||||
#include <mruby/range.h>
|
||||
|
||||
struct os_count_struct {
|
||||
mrb_int total;
|
||||
@@ -63,8 +71,8 @@ os_count_objects(mrb_state *mrb, mrb_value self)
|
||||
|
||||
mrb_objspace_each_objects(mrb, os_count_object_type, &obj_count);
|
||||
|
||||
mrb_hash_set(mrb, hash, mrb_symbol_value(mrb_intern_lit(mrb, "TOTAL")), mrb_fixnum_value(obj_count.total));
|
||||
mrb_hash_set(mrb, hash, mrb_symbol_value(mrb_intern_lit(mrb, "FREE")), mrb_fixnum_value(obj_count.freed));
|
||||
mrb_hash_set(mrb, hash, mrb_symbol_value(MRB_SYM(TOTAL)), mrb_fixnum_value(obj_count.total));
|
||||
mrb_hash_set(mrb, hash, mrb_symbol_value(MRB_SYM(FREE)), mrb_fixnum_value(obj_count.freed));
|
||||
|
||||
for (i = MRB_TT_FALSE; i < MRB_TT_MAXDEFINE; i++) {
|
||||
mrb_value type;
|
||||
@@ -73,7 +81,7 @@ os_count_objects(mrb_state *mrb, mrb_value self)
|
||||
COUNT_TYPE(T_FALSE);
|
||||
COUNT_TYPE(T_FREE);
|
||||
COUNT_TYPE(T_TRUE);
|
||||
COUNT_TYPE(T_FIXNUM);
|
||||
COUNT_TYPE(T_INTEGER);
|
||||
COUNT_TYPE(T_SYMBOL);
|
||||
COUNT_TYPE(T_UNDEF);
|
||||
COUNT_TYPE(T_FLOAT);
|
||||
@@ -92,6 +100,7 @@ os_count_objects(mrb_state *mrb, mrb_value self)
|
||||
COUNT_TYPE(T_ENV);
|
||||
COUNT_TYPE(T_DATA);
|
||||
COUNT_TYPE(T_FIBER);
|
||||
COUNT_TYPE(T_ISTRUCT);
|
||||
#undef COUNT_TYPE
|
||||
default:
|
||||
type = mrb_fixnum_value(i); break;
|
||||
@@ -104,9 +113,9 @@ os_count_objects(mrb_state *mrb, mrb_value self)
|
||||
}
|
||||
|
||||
struct os_each_object_data {
|
||||
mrb_value block;
|
||||
struct RClass *target_module;
|
||||
mrb_int count;
|
||||
mrb_value block;
|
||||
};
|
||||
|
||||
static int
|
||||
@@ -121,8 +130,8 @@ os_each_object_cb(mrb_state *mrb, struct RBasic *obj, void *ud)
|
||||
|
||||
/* filter internal objects */
|
||||
switch (obj->tt) {
|
||||
case MRB_TT_ENV:
|
||||
case MRB_TT_ICLASS:
|
||||
case MRB_TT_FREE: case MRB_TT_ENV:
|
||||
case MRB_TT_BREAK: case MRB_TT_ICLASS:
|
||||
return MRB_EACH_OBJ_OK;
|
||||
default:
|
||||
break;
|
||||
@@ -158,12 +167,8 @@ os_each_object_cb(mrb_state *mrb, struct RBasic *obj, void *ud)
|
||||
static mrb_value
|
||||
os_each_object(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value cls = mrb_nil_value();
|
||||
struct os_each_object_data d;
|
||||
mrb_get_args(mrb, "&!|C", &d.block, &cls);
|
||||
|
||||
d.target_module = mrb_nil_p(cls) ? NULL : mrb_class_ptr(cls);
|
||||
d.count = 0;
|
||||
struct os_each_object_data d = {0};
|
||||
mrb_get_args(mrb, "&!|c", &d.block, &d.target_module);
|
||||
mrb_objspace_each_objects(mrb, os_each_object_cb, &d);
|
||||
return mrb_fixnum_value(d.count);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
MRuby::Gem::Specification.new('mruby-os-memsize') do |spec|
|
||||
spec.license = 'MIT'
|
||||
spec.author = 'mruby developers'
|
||||
spec.summary = 'ObjectSpace memsize_of method'
|
||||
|
||||
spec.add_dependency('mruby-objectspace')
|
||||
spec.add_test_dependency('mruby-metaprog')
|
||||
spec.add_test_dependency('mruby-method')
|
||||
spec.add_test_dependency('mruby-fiber')
|
||||
end
|
||||
@@ -0,0 +1,236 @@
|
||||
#include <mruby.h>
|
||||
#include <mruby/gc.h>
|
||||
#include <mruby/hash.h>
|
||||
#include <mruby/class.h>
|
||||
#include <mruby/object.h>
|
||||
#include <mruby/numeric.h>
|
||||
#include <mruby/string.h>
|
||||
#include <mruby/array.h>
|
||||
#include <mruby/variable.h>
|
||||
#include <mruby/proc.h>
|
||||
#include <mruby/value.h>
|
||||
#include <mruby/range.h>
|
||||
|
||||
static size_t
|
||||
os_memsize_of_ivars(mrb_state* mrb, mrb_value obj)
|
||||
{
|
||||
return mrb_obj_iv_tbl_memsize(mrb, obj);
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
for(i = 0; i < irep->rlen; i++) {
|
||||
size += os_memsize_of_irep(state, irep->reps[i]);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
static size_t
|
||||
os_memsize_of_method(mrb_state* mrb, mrb_value method_obj)
|
||||
{
|
||||
size_t size;
|
||||
mrb_value proc_value = mrb_obj_iv_get(mrb, mrb_obj_ptr(method_obj),
|
||||
mrb_intern_lit(mrb, "_proc"));
|
||||
struct RProc *proc = mrb_proc_ptr(proc_value);
|
||||
|
||||
size = sizeof(struct RProc);
|
||||
if (!MRB_PROC_CFUNC_P(proc)) size += os_memsize_of_irep(mrb, proc->body.irep);
|
||||
return size;
|
||||
}
|
||||
|
||||
static mrb_bool
|
||||
obj_is_kind_of_checked(mrb_state *mrb, mrb_value obj, const char *classname)
|
||||
{
|
||||
mrb_value objclass = mrb_obj_value(mrb->object_class);
|
||||
|
||||
if (mrb_const_defined(mrb, objclass, mrb_intern_cstr(mrb, classname))) {
|
||||
struct RClass *klass = mrb_class_get(mrb, classname);
|
||||
return mrb_obj_is_kind_of(mrb, obj, klass);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static size_t
|
||||
os_memsize_of_object(mrb_state* mrb, mrb_value obj)
|
||||
{
|
||||
size_t size = 0;
|
||||
|
||||
switch(mrb_type(obj)) {
|
||||
case MRB_TT_STRING:
|
||||
size += mrb_objspace_page_slot_size();
|
||||
if (!RSTR_EMBED_P(RSTRING(obj)) && !RSTR_SHARED_P(RSTRING(obj))) {
|
||||
size += RSTRING_CAPA(obj);
|
||||
size++; /* NUL terminator */
|
||||
}
|
||||
break;
|
||||
case MRB_TT_CLASS:
|
||||
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);
|
||||
/* fall through */
|
||||
case MRB_TT_EXCEPTION:
|
||||
case MRB_TT_OBJECT: {
|
||||
size += mrb_objspace_page_slot_size();
|
||||
size += os_memsize_of_ivars(mrb, obj);
|
||||
if (obj_is_kind_of_checked(mrb, obj, "UnboundMethod") ||
|
||||
obj_is_kind_of_checked(mrb, obj, "Method")) {
|
||||
size += os_memsize_of_method(mrb, obj);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MRB_TT_HASH: {
|
||||
size += mrb_objspace_page_slot_size() +
|
||||
mrb_os_memsize_of_hash_table(obj);
|
||||
break;
|
||||
}
|
||||
case MRB_TT_ARRAY: {
|
||||
mrb_int len = RARRAY_LEN(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;
|
||||
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);
|
||||
break;
|
||||
}
|
||||
case MRB_TT_RANGE:
|
||||
#ifndef MRB_RANGE_EMBED
|
||||
size += mrb_objspace_page_slot_size() +
|
||||
sizeof(struct mrb_range_edges);
|
||||
#endif
|
||||
break;
|
||||
case MRB_TT_FIBER: {
|
||||
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;
|
||||
|
||||
size += mrb_objspace_page_slot_size() +
|
||||
sizeof(struct mrb_context) +
|
||||
sizeof(mrb_value) * stack_size +
|
||||
sizeof(mrb_callinfo) * ci_size;
|
||||
break;
|
||||
}
|
||||
#ifndef MRB_NO_FLOAT
|
||||
case MRB_TT_FLOAT:
|
||||
#endif
|
||||
case MRB_TT_INTEGER:
|
||||
if (mrb_immediate_p(obj))
|
||||
break;
|
||||
case MRB_TT_DATA:
|
||||
case MRB_TT_ISTRUCT:
|
||||
size += mrb_objspace_page_slot_size();
|
||||
break;
|
||||
/* zero heap size types.
|
||||
* immediate VM stack values, contained within mrb_state, or on C stack */
|
||||
case MRB_TT_TRUE:
|
||||
case MRB_TT_FALSE:
|
||||
case MRB_TT_BREAK:
|
||||
case MRB_TT_CPTR:
|
||||
case MRB_TT_SYMBOL:
|
||||
case MRB_TT_FREE:
|
||||
case MRB_TT_UNDEF:
|
||||
case MRB_TT_ENV:
|
||||
/* never used, silences compiler warning
|
||||
* not having a default: clause lets the compiler tell us when there is a new
|
||||
* TT not accounted for */
|
||||
case MRB_TT_MAXDEFINE:
|
||||
break;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* ObjectSpace.memsize_of(obj) -> Numeric
|
||||
*
|
||||
* Returns the amount of heap memory allocated for object in size_t units.
|
||||
*
|
||||
* The return value depends on the definition of size_t on that platform,
|
||||
* therefore the value is not comparable across platform types.
|
||||
*
|
||||
* Immediate values such as integers, booleans, symbols and unboxed float numbers
|
||||
* return 0. Additionally special objects which are small enough to fit inside an
|
||||
* object pointer, termed embedded objects, will return the size of the object pointer.
|
||||
* Strings and arrays below a compile-time defined size may be embedded.
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
os_memsize_of(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
size_t total;
|
||||
mrb_value obj;
|
||||
|
||||
mrb_get_args(mrb, "o", &obj);
|
||||
|
||||
total = os_memsize_of_object(mrb, obj);
|
||||
return mrb_fixnum_value((mrb_int)total);
|
||||
}
|
||||
|
||||
struct os_memsize_of_all_cb_data {
|
||||
size_t t;
|
||||
struct RClass *type;
|
||||
};
|
||||
|
||||
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;
|
||||
switch (obj->tt) {
|
||||
case MRB_TT_FREE: case MRB_TT_ENV:
|
||||
case MRB_TT_BREAK: case MRB_TT_ICLASS:
|
||||
/* internal objects that should not be counted */
|
||||
return MRB_EACH_OBJ_OK;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* skip Proc objects for methods */
|
||||
if (obj->c == NULL) return 0;
|
||||
if (data->type == NULL || mrb_obj_is_kind_of(mrb, mrb_obj_value(obj), data->type))
|
||||
data->t += os_memsize_of_object(mrb, mrb_obj_value(obj));
|
||||
return MRB_EACH_OBJ_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* ObjectSpace.memsize_of_all([klass]) -> Numeric
|
||||
*
|
||||
* Return consuming memory size of all living objects of type klass.
|
||||
*
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
os_memsize_of_all(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
struct os_memsize_of_all_cb_data data = { 0 };
|
||||
mrb_get_args(mrb, "|c", &data.type);
|
||||
mrb_objspace_each_objects(mrb, os_memsize_of_all_cb, &data);
|
||||
return mrb_fixnum_value((mrb_int)data.t);
|
||||
}
|
||||
|
||||
void
|
||||
mrb_mruby_os_memsize_gem_init(mrb_state *mrb)
|
||||
{
|
||||
struct RClass *os = mrb_module_get(mrb, "ObjectSpace");
|
||||
mrb_define_class_method(mrb, os, "memsize_of", os_memsize_of, MRB_ARGS_REQ(1));
|
||||
mrb_define_class_method(mrb, os, "memsize_of_all", os_memsize_of_all, MRB_ARGS_OPT(1));
|
||||
}
|
||||
|
||||
void
|
||||
mrb_mruby_os_memsize_gem_final(mrb_state *mrb)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
assert 'ObjectSpace.memsize_of' do
|
||||
# immediate literals
|
||||
int_size = ObjectSpace.memsize_of 1
|
||||
assert_equal int_size, 0, 'int zero'
|
||||
|
||||
sym_size = ObjectSpace.memsize_of :foo
|
||||
assert_equal sym_size, 0, 'sym zero'
|
||||
|
||||
assert_equal ObjectSpace.memsize_of(true), int_size
|
||||
assert_equal ObjectSpace.memsize_of(false), int_size
|
||||
|
||||
assert_not_equal ObjectSpace.memsize_of('a'), 0, 'memsize of str'
|
||||
|
||||
if __ENCODING__ == "UTF-8"
|
||||
assert_not_equal ObjectSpace.memsize_of("こんにちは世界"), 0, 'memsize of utf8 str'
|
||||
end
|
||||
|
||||
# class defs
|
||||
class_obj_size = ObjectSpace.memsize_of Class
|
||||
assert_not_equal class_obj_size, 0, 'Class obj not zero'
|
||||
|
||||
empty_class_def_size = ObjectSpace.memsize_of Class.new
|
||||
assert_not_equal empty_class_def_size, 0, 'Class def not zero'
|
||||
|
||||
proc_size = ObjectSpace.memsize_of Proc.new { x = 1; x }
|
||||
assert_not_equal proc_size, 0
|
||||
|
||||
class_with_methods = Class.new do
|
||||
def foo
|
||||
a = 0
|
||||
a + 1
|
||||
end
|
||||
end
|
||||
|
||||
m_size = ObjectSpace.memsize_of class_with_methods.instance_method(:foo)
|
||||
assert_not_equal m_size, 0, 'method size not zero'
|
||||
|
||||
# collections
|
||||
empty_array_size = ObjectSpace.memsize_of []
|
||||
assert_not_equal empty_array_size, 0, 'empty array size not zero'
|
||||
assert_operator empty_array_size, :<, ObjectSpace.memsize_of(Array.new(16)), 'large array size greater than embed'
|
||||
|
||||
# fiber
|
||||
empty_fiber_size = ObjectSpace.memsize_of(Fiber.new {})
|
||||
assert_not_equal empty_fiber_size, 0, 'empty fiber not zero'
|
||||
|
||||
#hash
|
||||
assert_not_equal ObjectSpace.memsize_of({}), 0, 'empty hash size not zero'
|
||||
end
|
||||
|
||||
assert 'ObjectSpace.memsize_of_all' do
|
||||
foo_class = Class.new do
|
||||
def initialize
|
||||
@a = 'a'
|
||||
@b = 'b'
|
||||
end
|
||||
end
|
||||
|
||||
foos = Array.new(10) { foo_class.new }
|
||||
foo_size = ObjectSpace.memsize_of(foos.first)
|
||||
|
||||
assert_equal ObjectSpace.memsize_of_all(foo_class), foo_size * foos.size, 'Memsize of all instance'
|
||||
end
|
||||
@@ -9,10 +9,10 @@
|
||||
#include "mruby/numeric.h"
|
||||
#include "mruby/string.h"
|
||||
#include "mruby/variable.h"
|
||||
#include "mruby/endian.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
struct tmpl {
|
||||
@@ -63,36 +63,6 @@ const static unsigned char base64chars[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
static unsigned char base64_dec_tab[128];
|
||||
|
||||
#if !defined(BYTE_ORDER) && defined(__BYTE_ORDER__)
|
||||
# define BYTE_ORDER __BYTE_ORDER__
|
||||
#endif
|
||||
#if !defined(BIG_ENDIAN) && defined(__ORDER_BIG_ENDIAN__)
|
||||
# define BIG_ENDIAN __ORDER_BIG_ENDIAN__
|
||||
#endif
|
||||
#if !defined(LITTLE_ENDIAN) && defined(__ORDER_LITTLE_ENDIAN__)
|
||||
# define LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__
|
||||
#endif
|
||||
|
||||
#ifdef BYTE_ORDER
|
||||
# if BYTE_ORDER == BIG_ENDIAN
|
||||
# define littleendian 0
|
||||
# define check_little_endian() (void)0
|
||||
# elif BYTE_ORDER == LITTLE_ENDIAN
|
||||
# define littleendian 1
|
||||
# define check_little_endian() (void)0
|
||||
# endif
|
||||
#endif
|
||||
#ifndef littleendian
|
||||
/* can't distinguish endian in compile time */
|
||||
static int littleendian = 0;
|
||||
static void
|
||||
check_little_endian(void)
|
||||
{
|
||||
unsigned int n = 1;
|
||||
littleendian = (*(unsigned char *)&n == 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
static unsigned int
|
||||
hex2int(unsigned char ch)
|
||||
{
|
||||
@@ -143,7 +113,7 @@ static int
|
||||
pack_c(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int flags)
|
||||
{
|
||||
str = str_len_ensure(mrb, str, sidx + 1);
|
||||
RSTRING_PTR(str)[sidx] = (char)mrb_fixnum(o);
|
||||
RSTRING_PTR(str)[sidx] = (char)mrb_integer(o);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -163,7 +133,7 @@ pack_s(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int fl
|
||||
uint16_t n;
|
||||
|
||||
str = str_len_ensure(mrb, str, sidx + 2);
|
||||
n = (uint16_t)mrb_fixnum(o);
|
||||
n = (uint16_t)mrb_integer(o);
|
||||
if (flags & PACK_FLAG_LITTLEENDIAN) {
|
||||
RSTRING_PTR(str)[sidx+0] = n % 256;
|
||||
RSTRING_PTR(str)[sidx+1] = n / 256;
|
||||
@@ -197,7 +167,7 @@ pack_l(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int fl
|
||||
uint32_t n;
|
||||
|
||||
str = str_len_ensure(mrb, str, sidx + 4);
|
||||
n = (uint32_t)mrb_fixnum(o);
|
||||
n = (uint32_t)mrb_integer(o);
|
||||
if (flags & PACK_FLAG_LITTLEENDIAN) {
|
||||
RSTRING_PTR(str)[sidx+0] = (char)(n & 0xff);
|
||||
RSTRING_PTR(str)[sidx+1] = (char)(n >> 8);
|
||||
@@ -290,7 +260,7 @@ unpack_l(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, un
|
||||
#ifndef MRB_INT64
|
||||
if (!FIXABLE(sl)) {
|
||||
i32tostr(msg, sizeof(msg), sl);
|
||||
mrb_raisef(mrb, E_RANGE_ERROR, "cannot unpack to Fixnum: %s", msg);
|
||||
mrb_raisef(mrb, E_RANGE_ERROR, "cannot unpack to Integer: %s", msg);
|
||||
}
|
||||
#endif
|
||||
n = sl;
|
||||
@@ -298,7 +268,7 @@ unpack_l(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, un
|
||||
#ifndef MRB_INT64
|
||||
if (!POSFIXABLE(ul)) {
|
||||
u32tostr(msg, sizeof(msg), ul);
|
||||
mrb_raisef(mrb, E_RANGE_ERROR, "cannot unpack to Fixnum: %s", msg);
|
||||
mrb_raisef(mrb, E_RANGE_ERROR, "cannot unpack to Integer: %s", msg);
|
||||
}
|
||||
#endif
|
||||
n = ul;
|
||||
@@ -313,7 +283,7 @@ pack_q(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int fl
|
||||
uint64_t n;
|
||||
|
||||
str = str_len_ensure(mrb, str, sidx + 8);
|
||||
n = (uint64_t)mrb_fixnum(o);
|
||||
n = (uint64_t)mrb_integer(o);
|
||||
if (flags & PACK_FLAG_LITTLEENDIAN) {
|
||||
RSTRING_PTR(str)[sidx+0] = (char)(n & 0xff);
|
||||
RSTRING_PTR(str)[sidx+1] = (char)(n >> 8);
|
||||
@@ -411,21 +381,21 @@ unpack_q(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, un
|
||||
int64_t sll = ull;
|
||||
if (!FIXABLE(sll)) {
|
||||
i64tostr(msg, sizeof(msg), sll);
|
||||
mrb_raisef(mrb, E_RANGE_ERROR, "cannot unpack to Fixnum: %s", msg);
|
||||
mrb_raisef(mrb, E_RANGE_ERROR, "cannot unpack to Integer: %s", msg);
|
||||
}
|
||||
n = sll;
|
||||
n = (mrb_int)sll;
|
||||
} else {
|
||||
if (!POSFIXABLE(ull)) {
|
||||
u64tostr(msg, sizeof(msg), ull);
|
||||
mrb_raisef(mrb, E_RANGE_ERROR, "cannot unpack to Fixnum: %s", msg);
|
||||
mrb_raisef(mrb, E_RANGE_ERROR, "cannot unpack to Integer: %s", msg);
|
||||
}
|
||||
n = ull;
|
||||
n = (mrb_int)ull;
|
||||
}
|
||||
mrb_ary_push(mrb, ary, mrb_fixnum_value(n));
|
||||
return 8;
|
||||
}
|
||||
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
static int
|
||||
pack_double(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int flags)
|
||||
{
|
||||
@@ -560,7 +530,7 @@ pack_utf8(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, long count,
|
||||
int len = 0;
|
||||
uint32_t c = 0;
|
||||
|
||||
c = (uint32_t)mrb_fixnum(o);
|
||||
c = (uint32_t)mrb_integer(o);
|
||||
|
||||
/* Unicode character */
|
||||
/* from mruby-compiler gem */
|
||||
@@ -828,7 +798,7 @@ unpack_h(mrb_state *mrb, const void *src, int slen, mrb_value ary, int count, un
|
||||
}
|
||||
}
|
||||
|
||||
dst = mrb_str_resize(mrb, dst, dptr - dptr0);
|
||||
dst = mrb_str_resize(mrb, dst, (mrb_int)(dptr - dptr0));
|
||||
mrb_ary_push(mrb, ary, dst);
|
||||
return (int)(sptr - sptr0);
|
||||
}
|
||||
@@ -951,7 +921,7 @@ unpack_m(mrb_state *mrb, const void *src, int slen, mrb_value ary, unsigned int
|
||||
}
|
||||
|
||||
done:
|
||||
dst = mrb_str_resize(mrb, dst, dptr - dptr0);
|
||||
dst = mrb_str_resize(mrb, dst, (mrb_int)(dptr - dptr0));
|
||||
mrb_ary_push(mrb, ary, dst);
|
||||
return (int)(sptr - sptr0);
|
||||
}
|
||||
@@ -1248,7 +1218,7 @@ mrb_pack_pack(mrb_state *mrb, mrb_value ary)
|
||||
if (type == PACK_TYPE_INTEGER) {
|
||||
o = mrb_to_int(mrb, o);
|
||||
}
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
else if (type == PACK_TYPE_FLOAT) {
|
||||
if (!mrb_float_p(o)) {
|
||||
mrb_float f = mrb_to_flo(mrb, o);
|
||||
@@ -1284,7 +1254,7 @@ mrb_pack_pack(mrb_state *mrb, mrb_value ary)
|
||||
case PACK_DIR_STR:
|
||||
ridx += pack_a(mrb, o, result, ridx, count, flags);
|
||||
break;
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
case PACK_DIR_DOUBLE:
|
||||
ridx += pack_double(mrb, o, result, ridx, flags);
|
||||
break;
|
||||
@@ -1298,7 +1268,8 @@ mrb_pack_pack(mrb_state *mrb, mrb_value ary)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (dir == PACK_DIR_STR || dir == PACK_DIR_BASE64) { /* always consumes 1 entry */
|
||||
if (dir == PACK_DIR_STR || dir == PACK_DIR_BASE64 || dir == PACK_DIR_HEX) {
|
||||
/* always consumes 1 entry */
|
||||
aidx++;
|
||||
break;
|
||||
}
|
||||
@@ -1380,7 +1351,7 @@ pack_unpack(mrb_state *mrb, mrb_value str, int single)
|
||||
case PACK_DIR_QUAD:
|
||||
srcidx += unpack_q(mrb, sptr, srclen - srcidx, result, flags);
|
||||
break;
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
#ifndef MRB_NO_FLOAT
|
||||
case PACK_DIR_FLOAT:
|
||||
srcidx += unpack_float(mrb, sptr, srclen - srcidx, result, flags);
|
||||
break;
|
||||
@@ -1425,7 +1396,6 @@ mrb_pack_unpack1(mrb_state *mrb, mrb_value str)
|
||||
void
|
||||
mrb_mruby_pack_gem_init(mrb_state *mrb)
|
||||
{
|
||||
check_little_endian();
|
||||
make_base64_dec_tab();
|
||||
|
||||
mrb_define_method(mrb, mrb->array_class, "pack", mrb_pack_pack, MRB_ARGS_REQ(1));
|
||||
|
||||
@@ -3,39 +3,10 @@
|
||||
#
|
||||
# ISO 15.3.1
|
||||
module Kernel
|
||||
##
|
||||
# Invoke method +print+ on STDOUT and passing +*args+
|
||||
#
|
||||
# ISO 15.3.1.2.10
|
||||
def print(*args)
|
||||
i = 0
|
||||
len = args.size
|
||||
while i < len
|
||||
__printstr__ args[i].to_s
|
||||
i += 1
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Invoke method +puts+ on STDOUT and passing +*args*+
|
||||
#
|
||||
# ISO 15.3.1.2.11
|
||||
def puts(*args)
|
||||
i = 0
|
||||
len = args.size
|
||||
while i < len
|
||||
s = args[i].to_s
|
||||
__printstr__ s
|
||||
__printstr__ "\n" if (s[-1] != "\n")
|
||||
i += 1
|
||||
end
|
||||
__printstr__ "\n" if len == 0
|
||||
nil
|
||||
end
|
||||
|
||||
##
|
||||
# Print human readable object description
|
||||
#
|
||||
# ISO 15.3.1.2.9
|
||||
# ISO 15.3.1.3.34
|
||||
def p(*args)
|
||||
i = 0
|
||||
|
||||
@@ -17,39 +17,73 @@
|
||||
#endif
|
||||
|
||||
static void
|
||||
printstr(mrb_state *mrb, mrb_value obj)
|
||||
printstr(mrb_state *mrb, const char *p, mrb_int len)
|
||||
{
|
||||
if (mrb_string_p(obj)) {
|
||||
#if defined(_WIN32)
|
||||
if (isatty(fileno(stdout))) {
|
||||
DWORD written;
|
||||
int mlen = (int)RSTRING_LEN(obj);
|
||||
char* utf8 = RSTRING_PTR(obj);
|
||||
int wlen = MultiByteToWideChar(CP_UTF8, 0, utf8, mlen, NULL, 0);
|
||||
wchar_t* utf16 = (wchar_t*)mrb_malloc(mrb, (wlen+1) * sizeof(wchar_t));
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, utf8, mlen, utf16, wlen) > 0) {
|
||||
utf16[wlen] = 0;
|
||||
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE),
|
||||
utf16, wlen, &written, NULL);
|
||||
}
|
||||
mrb_free(mrb, utf16);
|
||||
} else
|
||||
if (isatty(fileno(stdout))) {
|
||||
DWORD written;
|
||||
int wlen = MultiByteToWideChar(CP_UTF8, 0, p, (int)len, NULL, 0);
|
||||
wchar_t* utf16 = (wchar_t*)mrb_malloc(mrb, (wlen+1) * sizeof(wchar_t));
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, p, (int)len, utf16, wlen) > 0) {
|
||||
utf16[wlen] = 0;
|
||||
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE),
|
||||
utf16, (DWORD)wlen, &written, NULL);
|
||||
}
|
||||
mrb_free(mrb, utf16);
|
||||
} else
|
||||
#endif
|
||||
fwrite(RSTRING_PTR(obj), RSTRING_LEN(obj), 1, stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
fwrite(p, (size_t)len, 1, stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
/* 15.3.1.2.9 */
|
||||
/* 15.3.1.3.34 */
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_printstr(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value argv = mrb_get_arg1(mrb);
|
||||
mrb_value s = mrb_get_arg1(mrb);
|
||||
|
||||
printstr(mrb, argv);
|
||||
if (mrb_string_p(s)) {
|
||||
printstr(mrb, RSTRING_PTR(s), RSTRING_LEN(s));
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
return argv;
|
||||
/* 15.3.1.2.10 */
|
||||
/* 15.3.1.3.35 */
|
||||
static mrb_value
|
||||
mrb_print(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_int argc, i;
|
||||
mrb_value *argv;
|
||||
|
||||
mrb_get_args(mrb, "*", &argv, &argc);
|
||||
for (i=0; i<argc; i++) {
|
||||
mrb_value s = mrb_obj_as_string(mrb, argv[i]);
|
||||
printstr(mrb, RSTRING_PTR(s), RSTRING_LEN(s));
|
||||
}
|
||||
return mrb_nil_value();
|
||||
}
|
||||
|
||||
/* 15.3.1.2.11 */
|
||||
/* 15.3.1.3.39 */
|
||||
static mrb_value
|
||||
mrb_puts(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_int argc, i;
|
||||
mrb_value *argv;
|
||||
|
||||
mrb_get_args(mrb, "*", &argv, &argc);
|
||||
for (i=0; i<argc; i++) {
|
||||
mrb_value s = mrb_obj_as_string(mrb, argv[i]);
|
||||
mrb_int len = RSTRING_LEN(s);
|
||||
printstr(mrb, RSTRING_PTR(s), len);
|
||||
if (len == 0 || RSTRING_PTR(s)[len-1] != '\n') {
|
||||
printstr(mrb, "\n", 1);
|
||||
}
|
||||
}
|
||||
if (argc == 0) {
|
||||
printstr(mrb, "\n", 1);
|
||||
}
|
||||
return mrb_nil_value();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -58,6 +92,8 @@ mrb_mruby_print_gem_init(mrb_state* mrb)
|
||||
struct RClass *krn;
|
||||
krn = mrb->kernel_module;
|
||||
mrb_define_method(mrb, krn, "__printstr__", mrb_printstr, MRB_ARGS_REQ(1));
|
||||
mrb_define_method(mrb, krn, "print", mrb_print, MRB_ARGS_ANY());
|
||||
mrb_define_method(mrb, krn, "puts", mrb_puts, MRB_ARGS_ANY());
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -21,7 +21,7 @@ mrb_proc_source_location(mrb_state *mrb, mrb_value self)
|
||||
return mrb_nil_value();
|
||||
}
|
||||
else {
|
||||
mrb_irep *irep = p->body.irep;
|
||||
const mrb_irep *irep = p->body.irep;
|
||||
int32_t line;
|
||||
const char *filename;
|
||||
|
||||
@@ -41,7 +41,7 @@ mrb_proc_inspect(mrb_state *mrb, mrb_value self)
|
||||
mrb_str_cat_str(mrb, str, mrb_ptr_to_str(mrb, mrb_cptr(self)));
|
||||
|
||||
if (!MRB_PROC_CFUNC_P(p)) {
|
||||
mrb_irep *irep = p->body.irep;
|
||||
const mrb_irep *irep = p->body.irep;
|
||||
const char *filename;
|
||||
int32_t line;
|
||||
mrb_str_cat_lit(mrb, str, "@");
|
||||
@@ -91,21 +91,24 @@ static mrb_value
|
||||
mrb_proc_parameters(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
struct parameters_type {
|
||||
size_t len;
|
||||
const char *name;
|
||||
mrb_sym name;
|
||||
int size;
|
||||
} *p, parameters_list [] = {
|
||||
{sizeof("req") - 1, "req", 0},
|
||||
{sizeof("opt") - 1, "opt", 0},
|
||||
{sizeof("rest") - 1, "rest", 0},
|
||||
{sizeof("req") - 1, "req", 0},
|
||||
{sizeof("block") - 1, "block", 0},
|
||||
{0, NULL, 0}
|
||||
{MRB_SYM(req), 0},
|
||||
{MRB_SYM(opt), 0},
|
||||
{MRB_SYM(rest), 0},
|
||||
{MRB_SYM(req), 0},
|
||||
{MRB_SYM(keyrest), 0},
|
||||
{MRB_SYM(block), 0},
|
||||
{MRB_SYM(key), 0},
|
||||
{0, 0}
|
||||
};
|
||||
const struct RProc *proc = mrb_proc_ptr(self);
|
||||
const struct mrb_irep *irep = proc->body.irep;
|
||||
mrb_aspec aspec;
|
||||
mrb_value parameters;
|
||||
mrb_value krest = mrb_nil_value();
|
||||
mrb_value block = mrb_nil_value();
|
||||
int i, j;
|
||||
int max = -1;
|
||||
|
||||
@@ -124,10 +127,8 @@ mrb_proc_parameters(mrb_state *mrb, mrb_value self)
|
||||
}
|
||||
|
||||
if (!MRB_PROC_STRICT_P(proc)) {
|
||||
parameters_list[0].len = sizeof("opt") - 1;
|
||||
parameters_list[0].name = "opt";
|
||||
parameters_list[3].len = sizeof("opt") - 1;
|
||||
parameters_list[3].name = "opt";
|
||||
parameters_list[0].name = MRB_SYM(opt);
|
||||
parameters_list[3].name = MRB_SYM(opt);
|
||||
}
|
||||
|
||||
aspec = PEEK_W(irep->iseq+1);
|
||||
@@ -135,21 +136,23 @@ mrb_proc_parameters(mrb_state *mrb, mrb_value self)
|
||||
parameters_list[1].size = MRB_ASPEC_OPT(aspec);
|
||||
parameters_list[2].size = MRB_ASPEC_REST(aspec);
|
||||
parameters_list[3].size = MRB_ASPEC_POST(aspec);
|
||||
parameters_list[4].size = MRB_ASPEC_BLOCK(aspec);
|
||||
parameters_list[4].size = MRB_ASPEC_KDICT(aspec);
|
||||
parameters_list[5].size = MRB_ASPEC_BLOCK(aspec);
|
||||
parameters_list[6].size = MRB_ASPEC_KEY(aspec);
|
||||
|
||||
parameters = mrb_ary_new_capa(mrb, irep->nlocals-1);
|
||||
|
||||
max = irep->nlocals-1;
|
||||
for (i = 0, p = parameters_list; p->name; p++) {
|
||||
mrb_value sname = mrb_symbol_value(mrb_intern_static(mrb, p->name, p->len));
|
||||
mrb_value sname = mrb_symbol_value(p->name);
|
||||
|
||||
for (j = 0; j < p->size; i++, j++) {
|
||||
mrb_value a;
|
||||
|
||||
a = mrb_ary_new(mrb);
|
||||
mrb_ary_push(mrb, a, sname);
|
||||
if (i < max && irep->lv[i].name) {
|
||||
mrb_sym sym = irep->lv[i].name;
|
||||
if (i < max && irep->lv[i]) {
|
||||
mrb_sym sym = irep->lv[i];
|
||||
const char *name = mrb_sym_name(mrb, sym);
|
||||
switch (name[0]) {
|
||||
case '*': case '&':
|
||||
@@ -159,9 +162,17 @@ mrb_proc_parameters(mrb_state *mrb, mrb_value self)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (p->name == MRB_SYM(block)) {
|
||||
block = a; continue;
|
||||
}
|
||||
if (p->name == MRB_SYM(keyrest)) {
|
||||
krest = a; continue;
|
||||
}
|
||||
mrb_ary_push(mrb, parameters, a);
|
||||
}
|
||||
}
|
||||
if (!mrb_nil_p(krest)) mrb_ary_push(mrb, parameters, krest);
|
||||
if (!mrb_nil_p(block)) mrb_ary_push(mrb, parameters, block);
|
||||
return parameters;
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user