mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Compare commits
623 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 | |||
| 112120969d | |||
| 63956036e1 | |||
| cdf45438f0 | |||
| 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 | |||
| b6b9c57f24 | |||
| aa578c346d | |||
| 612e5d6aad | |||
| ba9f81db8b | |||
| 5b9f7c0b93 | |||
| ce167d70b7 | |||
| 0ed623c442 | |||
| 206f7ce272 | |||
| b59283a03f | |||
| 3cf48713a2 | |||
| 6d5652114e | |||
| ac8360003e | |||
| b1017b2651 | |||
| b8d896e56a | |||
| db296e9593 | |||
| 233cb49903 | |||
| 9cdf439db5 | |||
| 95360a17f2 | |||
| 9dfe50f1d9 | |||
| c07f24cd18 | |||
| 03c2b8656b | |||
| ea6e1b003c | |||
| c2b37e76b3 | |||
| d40b922c98 | |||
| 28e793496a | |||
| 33c8d6af1e | |||
| 49ae2a69f2 | |||
| 2ffb77586a | |||
| dad99afae8 | |||
| f93dffb5ee | |||
| 742117e7a3 | |||
| 15ceb35e05 | |||
| f0bad600e0 | |||
| a8aeba89ef | |||
| 7f593893e8 | |||
| 5d5b1d1f3c | |||
| bb6846468a | |||
| 960c82e396 | |||
| 5be33b82c7 | |||
| 4cd858f93d | |||
| 2098acee7d | |||
| 3157efa57c | |||
| 613e0bee5e | |||
| 78c9c71bdf | |||
| aa30b13b36 | |||
| 6ba542cd53 | |||
| 106f4c4e9d | |||
| f1523d2404 | |||
| 00f6271e3b | |||
| b0e49ef79e | |||
| 81d340e042 | |||
| 4e40169ed6 | |||
| 49f1c0e94d | |||
| dcfebc6eed | |||
| f9d113f764 | |||
| 3d2d9f8a9b | |||
| 07129c76d9 | |||
| 6fe03f3b39 | |||
| 41f3456a28 | |||
| 7a420d4bba | |||
| d2b9c90f28 | |||
| ce12ef7e5c | |||
| 8bca11a64e | |||
| 14e325e45d | |||
| f85906b679 | |||
| 1fc9345b45 | |||
| 0a5983dd5e | |||
| aec40d10b8 | |||
| 89ceb3e7ba | |||
| fc80e4b651 | |||
| 52ab095ccf | |||
| d5cca2bdb2 | |||
| ebbb4fd7fb | |||
| b717cc7830 | |||
| a476c83caf | |||
| 15c63688e3 | |||
| 69c62415c0 | |||
| 690b2aa761 | |||
| 69311fa4c9 | |||
| ab9be1b48a | |||
| 5a682bfc7b | |||
| 53ea8abea6 | |||
| 6445e4683f | |||
| 6d49ec25a9 | |||
| a3ec6ede76 | |||
| 6803ddb8e2 | |||
| 4ce3997ca4 | |||
| 93e78fcde1 | |||
| 6f4c585bd7 | |||
| 47ea60814b | |||
| 86223b6eca | |||
| d79147fe5d | |||
| ac68c90800 | |||
| 82194c01ca | |||
| 69bc477b43 | |||
| 3655d4e0f4 | |||
| bc929656fb | |||
| 4aba93c969 | |||
| 49d97d6051 | |||
| 484577670f | |||
| d64c4d64e6 | |||
| 846af371c0 | |||
| 38b4483f9d | |||
| bb2512641f | |||
| bd60ad98eb | |||
| 7826af38ac | |||
| 84d842ea5c | |||
| f6c2662632 | |||
| e2aecacaeb | |||
| 8cdf6a87ed | |||
| 181f7b97d6 | |||
| 3491372a1d | |||
| 03b0741994 | |||
| a87f0b158d | |||
| e82b8b7bf8 | |||
| 91368c117c | |||
| 87576b819e | |||
| 48c473a0c4 | |||
| 87d77c13f5 | |||
| 4188219620 | |||
| fa8668c77d | |||
| 47f5f887e8 | |||
| c143d87e7c | |||
| 2fcdd3f8eb | |||
| 8c0dc55af8 | |||
| 8c04379a4c | |||
| a5bfe548d7 | |||
| 84aad39940 | |||
| c89ca5ebb8 | |||
| 1a4b86233f | |||
| 69a487c407 | |||
| f32c73ad1f | |||
| a343439973 | |||
| aeb86d953e | |||
| 49bba6c997 | |||
| 49b2e8c3a9 | |||
| 9c1220e14d | |||
| e2ac2a82a5 | |||
| bb6290a5d5 | |||
| 312411dea0 | |||
| 7277682cfb | |||
| 0f229bfbbf | |||
| 28b23b44ec | |||
| 8627157298 | |||
| b87268f130 | |||
| a395f8e2c8 | |||
| 3ce459f23a | |||
| e51923778f | |||
| 468578113a | |||
| 2c32154115 | |||
| 47d99457d9 | |||
| 88b756b39f | |||
| 462ff4cc84 | |||
| 18274e717a | |||
| 7870f74c21 | |||
| 8dee2e3984 | |||
| 8e86e64d78 | |||
| e79e972255 | |||
| 682a31f92b | |||
| 17974aa285 | |||
| 0a7fd86d59 | |||
| d95d46dee6 | |||
| 81c8352179 | |||
| 6d80c9505d | |||
| 1b0cf6a91b | |||
| 954ce5379c | |||
| 8b5c19218d | |||
| f6408c7b11 | |||
| 095aae5e2c | |||
| 26eb29547b | |||
| d3a02a297f | |||
| ab508e1e7f | |||
| 87d1bbe947 | |||
| 2e661e82d1 | |||
| 61c6832b48 | |||
| ed0038fdf2 | |||
| c181d89c9d | |||
| c91c9e2429 | |||
| 7add524041 | |||
| 72928f201c | |||
| 81a9210091 | |||
| e9877bc72a | |||
| ea632ab8a4 | |||
| d0501c69b0 | |||
| 3c03385e2e | |||
| 191ccbf660 | |||
| d983269908 | |||
| 2ceab2d270 | |||
| 8ce3664305 | |||
| ccd8485111 | |||
| 70caf4ed6d | |||
| b7c8bf7781 | |||
| 9840e5352b | |||
| 0aa5aa1de2 | |||
| 25d9370f97 | |||
| 2bab6e197d | |||
| 893cc2780c | |||
| 6af555b394 | |||
| ad6c58972c |
@@ -0,0 +1,106 @@
|
||||
name: Build & Test
|
||||
|
||||
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 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 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 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 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
|
||||
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
|
||||
with:
|
||||
path: C:\Users\runneradmin\AppData\Local\Temp\chocolatey
|
||||
key: ${{ runner.os }}-cygwin-chocolatey-${{ matrix.os }}-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-cygwin-chocolatey-${{ matrix.os }}-
|
||||
${{ runner.os }}-cygwin-chocolatey-
|
||||
- name: chocolatey
|
||||
run: choco install -y cygwin
|
||||
- name: Install cygwin packages
|
||||
shell: cmd
|
||||
run: C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -l C:/tools/cygwin/package -s http://mirrors.kernel.org/sourceware/cygwin/ -P gcc-core,gcc-g++,make,gperf,ruby
|
||||
- name: Set ENV
|
||||
run: |
|
||||
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 -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
|
||||
run: choco install -y ruby gperf
|
||||
- name: build and test
|
||||
shell: cmd
|
||||
run: |
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
|
||||
rake -E "STDOUT.sync=true" gensym all test
|
||||
@@ -0,0 +1,51 @@
|
||||
name: "Code scanning - action"
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: '0 19 * * 4'
|
||||
|
||||
jobs:
|
||||
CodeQL-Build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
# We must fetch at least the immediate parents so that if this is
|
||||
# a pull request then we can checkout the head.
|
||||
fetch-depth: 2
|
||||
|
||||
# If this run was triggered by a pull request event, then checkout
|
||||
# the head of the pull request instead of the merge commit.
|
||||
- run: git checkout HEAD^2
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
# Override language selection by uncommenting this and choosing your languages
|
||||
# with:
|
||||
# languages: go, javascript, csharp, python, cpp, java
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
||||
@@ -17,6 +17,9 @@
|
||||
.svn
|
||||
.vscode
|
||||
.yardoc
|
||||
.ccls*
|
||||
compile_flags.txt
|
||||
compile_commands.json
|
||||
cscope.files
|
||||
cscope.out
|
||||
tags
|
||||
|
||||
+10
-10
@@ -1,14 +1,14 @@
|
||||
language: c
|
||||
|
||||
sudo: false
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
sudo: false
|
||||
- os: osx
|
||||
osx_image: xcode7.1
|
||||
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
|
||||
script: "rake -m && rake test"
|
||||
- MRUBY_TARGET=travis
|
||||
|
||||
script:
|
||||
- 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.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
DOXYFILE_ENCODING = UTF-8
|
||||
PROJECT_NAME = "mruby"
|
||||
PROJECT_NUMBER = 2.1.1
|
||||
PROJECT_NUMBER = 2.1.2
|
||||
|
||||
PROJECT_BRIEF = "mruby is the lightweight implementation of the Ruby language"
|
||||
|
||||
|
||||
@@ -17,7 +17,9 @@ of the Ministry of Economy, Trade and Industry of Japan.
|
||||
|
||||
## How to get mruby
|
||||
|
||||
The stable version 2.1.1 of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/archive/2.1.1.zip](https://github.com/mruby/mruby/archive/2.1.1.zip)
|
||||
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,17 @@ 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
|
||||
the `$PATH` to compile `mruby`.
|
||||
|
||||
## Building documentation
|
||||
|
||||
|
||||
@@ -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
-34
@@ -1,50 +1,46 @@
|
||||
version: "{build}"
|
||||
|
||||
os: Visual Studio 2017
|
||||
|
||||
shallow_clone: true
|
||||
|
||||
|
||||
cache:
|
||||
- win_flex_bison
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
install:
|
||||
- if not exist win_flex_bison (
|
||||
appveyor DownloadFile "https://github.com/lexxmark/winflexbison/releases/download/v.2.5.10/win_flex_bison-2.5.10.zip" &
|
||||
7z x -y -owin_flex_bison win_flex_bison-2.5.10.zip
|
||||
)
|
||||
|
||||
build_script:
|
||||
- set YACC=.\win_flex_bison\win_bison.exe
|
||||
- set MRUBY_CONFIG=appveyor_config.rb
|
||||
- set MRUBY_TARGET=appveyor
|
||||
- rake gensym
|
||||
- rake -m all
|
||||
- rake -E $stdout.sync=true test
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
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)
|
||||
|
||||
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
|
||||
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
|
||||
conf.enable_bintest
|
||||
conf.enable_test
|
||||
|
||||
enable_cxx_abi
|
||||
|
||||
build_mrbc_exec
|
||||
end
|
||||
+74
-33
@@ -6,41 +6,61 @@ binaries.
|
||||
## Prerequisites
|
||||
|
||||
To compile mruby out of the source code you need the following tools:
|
||||
* C Compiler (e.g. `gcc`)
|
||||
* Linker (e.g. `gcc`)
|
||||
* C Compiler (e.g. `gcc` or `clang`)
|
||||
* Linker (e.g. `gcc` or `clang`)
|
||||
* Archive utility (e.g. `ar`)
|
||||
* Parser generator (e.g. `bison`)
|
||||
* Ruby 2.0 or later (e.g. `ruby` or `jruby`)
|
||||
|
||||
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`. 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
|
||||
|
||||
@@ -84,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
|
||||
|
||||
@@ -205,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
|
||||
@@ -323,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)
|
||||
@@ -374,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.1 (2020-04-20)
|
||||
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`
|
||||
|
||||
+34
-28
@@ -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.1 (2020-04-20)]
|
||||
#### mruby [2.1.2 (2020-08-06)]
|
||||
|
||||
```
|
||||
[1, 2, 3]
|
||||
@@ -61,10 +61,17 @@ end
|
||||
|
||||
`ZeroDivisionError` is raised.
|
||||
|
||||
#### mruby [2.1.1 (2020-04-20)]
|
||||
#### 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.1 (2020-04-20)]
|
||||
#### mruby [2.1.2 (2020-08-06)]
|
||||
|
||||
`ArgumentError` is raised.
|
||||
|
||||
@@ -119,7 +126,7 @@ false
|
||||
true
|
||||
```
|
||||
|
||||
#### mruby [2.1.1 (2020-04-20)]
|
||||
#### mruby [2.1.2 (2020-08-06)]
|
||||
|
||||
```
|
||||
true
|
||||
@@ -156,7 +163,7 @@ p 'ok'
|
||||
ok
|
||||
```
|
||||
|
||||
#### mruby [2.1.1 (2020-04-20)]
|
||||
#### 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.1 (2020-04-20)]
|
||||
#### mruby [2.1.2 (2020-08-06)]
|
||||
|
||||
`NameError` is raised.
|
||||
|
||||
@@ -195,7 +202,7 @@ alias $a $__a__
|
||||
|
||||
` nil `
|
||||
|
||||
#### mruby [2.1.1 (2020-04-20)]
|
||||
#### 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.1 (2020-04-20)]
|
||||
#### 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.1 (2020-04-20)]
|
||||
#### 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)]
|
||||
|
||||
@@ -255,7 +261,7 @@ $ ruby -e 'def m(*r,**k) p [r,k] end; m("a"=>1,:b=>2)'
|
||||
[[{"a"=>1}], {:b=>2}]
|
||||
```
|
||||
|
||||
#### mruby [mruby 2.1.1]
|
||||
#### mruby [mruby 2.1.2]
|
||||
|
||||
```
|
||||
$ ./bin/mruby -e 'def m(*r,**k) p [r,k] end; m("a"=>1,:b=>2)'
|
||||
@@ -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.
|
||||
+102
-103
@@ -16,112 +16,111 @@ In the table.1 below, the second field describes the size (and
|
||||
sign) of operands.
|
||||
|
||||
* B: 8bit
|
||||
* sB: signed 8bit
|
||||
* S: 16bit
|
||||
* 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 | - | |
|
||||
| OP_MOVE" | BB | R(a) = R(b)
|
||||
| OP_LOADL" | BB | R(a) = Pool(b)
|
||||
| OP_LOADI" | BsB | R(a) = mrb_int(b)
|
||||
| OP_LOADI_0' | B | R(a) = 0
|
||||
| OP_LOADI_1' | B | R(a) = 1
|
||||
| OP_LOADI_2' | B | R(a) = 2
|
||||
| OP_LOADI_3' | B | R(a) = 3
|
||||
| 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[b]
|
||||
| OP_SETSV" | BB | Special[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' | SB | if R(b) pc+=a
|
||||
| OP_JMPNOT' | SB | if !R(b) pc+=a
|
||||
| OP_ONERR | sS | rescue_push(pc+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(Bx),R(a+1),...,R(a+c),&R(a+c+1))
|
||||
| OP_CALL' | B | R(a) = 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_ENTER | W | arg setup according to flags (23=5:5:1:5:5:1:1)
|
||||
| OP_KARG" | BB | R(a) = kdict[Syms(Bx)] # todo
|
||||
| OP_KARG2" | BB | R(a) = kdict[Syms(Bx)]; kdict.rm(Syms(b)) # todo
|
||||
| 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" | BB | R(a) = R(a)+R(a+1)
|
||||
| OP_ADDI" | BBB | R(a) = R(a)+mrb_int(c)
|
||||
| OP_SUB" | BB | R(a) = R(a)-R(a+1)
|
||||
| OP_SUBI" | BB | R(a) = R(a)-C
|
||||
| OP_MUL" | BB | R(a) = R(a)*R(a+1)
|
||||
| OP_DIV" | BB | R(a) = R(a)/R(a+1)
|
||||
| OP_EQ" | BB | R(a) = R(a)==R(a+1)
|
||||
| OP_LT" | BB | R(a) = R(a)<R(a+1)
|
||||
| OP_LE" | BB | R(a) = R(a)<=R(a+1)
|
||||
| OP_GT" | BB | R(a) = R(a)>R(a+1)
|
||||
| OP_GE" | BB | R(a) = R(a)>=R(a+1)
|
||||
| OP_ARRAY' | BB | R(a) = ary_new(R(a),R(a+1)..R(a+b))
|
||||
| OP_ARRAY2" | BB | 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_AREF' | BB | R(a) = R(a)[b]
|
||||
| OP_ASET' | BB | R(a)[b] = R(a+1)
|
||||
| OP_APOST' | BB | *R(a),R(A+1)..R(A+C) = R(a)[B..]
|
||||
| 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_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' | B | alias_method(R(a),R(a+1),R(a+2))
|
||||
| OP_UNDEF" | BB | undef_method(R(a),Syms(b))
|
||||
| OP_SCLASS' | B | R(a) = R(a).singleton_class
|
||||
| OP_TCLASS' | B | R(a) = target_class
|
||||
| OP_ERR' | B | raise(RuntimeError, Lit(Bx))
|
||||
| OP_EXT1 | - | make 1st operand 16bit
|
||||
| OP_EXT2 | - | make 2nd operand 16bit
|
||||
| OP_EXT3 | - | make 1st and 2nd operands 16bit
|
||||
| OP_STOP | - | stop VM
|
||||
| Instruction Name | Operand type | Semantics |
|
||||
|------------------|--------------|--------------------------------------------------------|
|
||||
| OP_NOP | - | no operation |
|
||||
| OP_MOVE | BB | R(a) = R(b) |
|
||||
| OP_LOADL | BB | R(a) = Pool(b) |
|
||||
| OP_LOADI | BB | R(a) = mrb_int(b) |
|
||||
| OP_LOADINEG | BB | R(a) = mrb_int(-b) |
|
||||
| OP_LOADI__1 | B | R(a) = mrb_int(-1) |
|
||||
| OP_LOADI_0 | B | R(a) = mrb_int(0) |
|
||||
| OP_LOADI_1 | B | R(a) = mrb_int(1) |
|
||||
| OP_LOADI_2 | B | R(a) = mrb_int(2) |
|
||||
| OP_LOADI_3 | B | R(a) = mrb_int(3) |
|
||||
| OP_LOADI_4 | B | R(a) = mrb_int(4) |
|
||||
| OP_LOADI_5 | B | R(a) = mrb_int(5) |
|
||||
| OP_LOADI_6 | B | R(a) = mrb_int(6) |
|
||||
| OP_LOADI_7 | B | R(a) = mrb_int(7) |
|
||||
| OP_LOADI16 | 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_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_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_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_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
|
||||
+56
-34
@@ -25,32 +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
|
||||
// can't use highest 2 bits of function pointers on 32bit Windows.
|
||||
# if defined(_WIN32) && !defined(_WIN64)
|
||||
# define 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_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 */
|
||||
@@ -64,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
|
||||
@@ -159,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
|
||||
@@ -176,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
|
||||
@@ -194,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
|
||||
|
||||
+131
-82
@@ -62,20 +62,38 @@
|
||||
#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)
|
||||
#endif
|
||||
@@ -86,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
|
||||
@@ -129,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;
|
||||
|
||||
@@ -159,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;
|
||||
mrb_bool vmexec;
|
||||
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
|
||||
|
||||
/**
|
||||
@@ -188,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 {
|
||||
@@ -200,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;
|
||||
@@ -234,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;
|
||||
@@ -246,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
|
||||
|
||||
@@ -259,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
|
||||
@@ -283,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;
|
||||
|
||||
/**
|
||||
@@ -308,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.
|
||||
@@ -317,7 +328,10 @@ 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);
|
||||
|
||||
/**
|
||||
* Include a module in another class or module.
|
||||
@@ -370,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.
|
||||
@@ -397,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
|
||||
@@ -404,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.
|
||||
@@ -431,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.
|
||||
@@ -459,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.
|
||||
@@ -549,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.
|
||||
@@ -650,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.
|
||||
@@ -657,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.
|
||||
@@ -665,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.
|
||||
@@ -697,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.
|
||||
@@ -706,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.
|
||||
@@ -714,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.
|
||||
@@ -723,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 */
|
||||
@@ -791,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.
|
||||
@@ -857,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` |
|
||||
@@ -899,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); }
|
||||
@@ -910,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);
|
||||
@@ -924,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) */
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -956,8 +986,21 @@ mrb_get_mid(mrb_state *mrb) /* get method symbol */
|
||||
*/
|
||||
MRB_API mrb_int mrb_get_argc(mrb_state *mrb);
|
||||
|
||||
/**
|
||||
* Retrieve an array of arguments from mrb_state.
|
||||
*
|
||||
* Correctly handles *splat arguments.
|
||||
*/
|
||||
MRB_API mrb_value* mrb_get_argv(mrb_state *mrb);
|
||||
|
||||
/**
|
||||
* Retrieve the first and only argument from mrb_state.
|
||||
* Raises ArgumentError unless the number of arguments is exactly one.
|
||||
*
|
||||
* Correctly handles *splat arguments.
|
||||
*/
|
||||
MRB_API mrb_value mrb_get_arg1(mrb_state *mrb);
|
||||
|
||||
/* `strlen` for character string literals (use with caution or `strlen` instead)
|
||||
Adjacent string literals are concatenated in C/C++ in translation phase 6.
|
||||
If `lit` is not one, the compiler will report a syntax error:
|
||||
@@ -985,6 +1028,7 @@ MRB_API mrb_value* mrb_get_argv(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);
|
||||
* }
|
||||
@@ -997,6 +1041,7 @@ MRB_API mrb_value* mrb_get_argv(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.
|
||||
*
|
||||
@@ -1006,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);
|
||||
* }
|
||||
@@ -1032,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:
|
||||
*
|
||||
@@ -1040,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
|
||||
@@ -1049,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);
|
||||
@@ -1148,10 +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_run(mrb_state *mrb, struct RProc* proc, mrb_value self);
|
||||
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)
|
||||
@@ -1166,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);
|
||||
@@ -1199,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);
|
||||
@@ -1245,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);
|
||||
@@ -1282,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);
|
||||
@@ -1292,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);
|
||||
|
||||
@@ -1336,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 */
|
||||
|
||||
+25
-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))
|
||||
@@ -239,6 +256,7 @@ MRB_API mrb_value mrb_ary_entry(mrb_value ary, mrb_int offset);
|
||||
* @param head Beginning position of a replacement subsequence.
|
||||
* @param len Length of a replacement subsequence.
|
||||
* @param rpl The array of replacement elements.
|
||||
* It is possible to pass `mrb_undef_value()` instead of an empty array.
|
||||
* @return The receiver array.
|
||||
*/
|
||||
MRB_API mrb_value mrb_ary_splice(mrb_state *mrb, mrb_value self, mrb_int head, mrb_int len, mrb_value rpl);
|
||||
@@ -291,6 +309,9 @@ MRB_API mrb_value mrb_ary_join(mrb_state *mrb, mrb_value ary, mrb_value sep);
|
||||
*/
|
||||
MRB_API mrb_value mrb_ary_resize(mrb_state *mrb, mrb_value ary, mrb_int new_len);
|
||||
|
||||
/* helper functions */
|
||||
mrb_value mrb_ary_subseq(mrb_state *mrb, mrb_value ary, mrb_int beg, mrb_int len);
|
||||
|
||||
MRB_END_DECL
|
||||
|
||||
#endif /* MRUBY_ARRAY_H */
|
||||
|
||||
+70
-46
@@ -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,67 +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;
|
||||
};
|
||||
)
|
||||
};
|
||||
} value;
|
||||
typedef uint64_t mrb_value;
|
||||
|
||||
union mrb_value_ {
|
||||
mrb_float f;
|
||||
uint64_t u;
|
||||
#ifdef MRB_64BIT
|
||||
void *p;
|
||||
#endif
|
||||
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_cptr(o) mrb_ptr(o)
|
||||
#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
|
||||
#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_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))
|
||||
#define SET_CPTR_VALUE(mrb,r,v) BOXNAN_SET_OBJ_VALUE(r, MRB_TT_CPTR, v)
|
||||
#define SET_UNDEF_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_UNDEF, value.i, 0)
|
||||
#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, p, v)
|
||||
#endif
|
||||
#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))
|
||||
|
||||
+70
-53
@@ -11,16 +11,16 @@
|
||||
#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 RCptr {
|
||||
struct RInteger {
|
||||
MRB_OBJECT_HEADER;
|
||||
void *p;
|
||||
mrb_int i;
|
||||
};
|
||||
|
||||
enum mrb_special_consts {
|
||||
@@ -52,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:
|
||||
@@ -71,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)
|
||||
@@ -142,39 +154,44 @@ MRB_API mrb_value mrb_word_boxing_float_pool(struct mrb_state*, mrb_float);
|
||||
#define mrb_sclass_p(o) BOXWORD_OBJ_TYPE_P(o, SCLASS)
|
||||
#define mrb_proc_p(o) BOXWORD_OBJ_TYPE_P(o, PROC)
|
||||
#define mrb_range_p(o) BOXWORD_OBJ_TYPE_P(o, RANGE)
|
||||
#define mrb_file_p(o) BOXWORD_OBJ_TYPE_P(o, FILE)
|
||||
#define mrb_env_p(o) BOXWORD_OBJ_TYPE_P(o, ENV)
|
||||
#define mrb_data_p(o) BOXWORD_OBJ_TYPE_P(o, DATA)
|
||||
#define mrb_fiber_p(o) BOXWORD_OBJ_TYPE_P(o, FIBER)
|
||||
#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
|
||||
|
||||
+12
-3
@@ -33,7 +33,7 @@ typedef struct mrbc_context {
|
||||
mrb_bool no_exec:1;
|
||||
mrb_bool keep_lv:1;
|
||||
mrb_bool no_optimize:1;
|
||||
mrb_bool on_eval:1;
|
||||
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 {
|
||||
@@ -151,8 +152,8 @@ struct mrb_parser_state {
|
||||
mrb_ast_node *tree;
|
||||
|
||||
mrb_bool no_optimize:1;
|
||||
mrb_bool on_eval:1;
|
||||
mrb_bool capture_errors:1;
|
||||
const struct RProc *upper;
|
||||
struct mrb_parser_message error_buffer[10];
|
||||
struct mrb_parser_message warn_buffer[10];
|
||||
|
||||
@@ -180,7 +181,15 @@ MRB_API struct mrb_parser_state* mrb_parse_nstring(mrb_state*,const char*,size_t
|
||||
MRB_API struct RProc* mrb_generate_code(mrb_state*, struct mrb_parser_state*);
|
||||
MRB_API mrb_value mrb_load_exec(mrb_state *mrb, struct mrb_parser_state *p, mrbc_context *c);
|
||||
|
||||
/* program load functions */
|
||||
/** program load functions
|
||||
* Please note! Currently due to interactions with the GC calling these functions will
|
||||
* leak one RProc object per function call.
|
||||
* To prevent this save the current memory arena before calling and restore the arena
|
||||
* right after, like so
|
||||
* int ai = mrb_gc_arena_save(mrb);
|
||||
* mrb_value status = mrb_load_string(mrb, buffer);
|
||||
* mrb_gc_arena_restore(mrb, ai);
|
||||
*/
|
||||
#ifndef MRB_DISABLE_STDIO
|
||||
MRB_API mrb_value mrb_load_file(mrb_state*,FILE*);
|
||||
MRB_API mrb_value mrb_load_file_cxt(mrb_state*,FILE*, mrbc_context *cxt);
|
||||
|
||||
@@ -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
-41
@@ -17,15 +17,12 @@
|
||||
MRB_BEGIN_DECL
|
||||
|
||||
#define DUMP_DEBUG_INFO 1
|
||||
#define DUMP_ENDIAN_BIG 2
|
||||
#define DUMP_ENDIAN_LIL 4
|
||||
#define DUMP_ENDIAN_NAT 6
|
||||
#define DUMP_ENDIAN_MASK 6
|
||||
|
||||
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*);
|
||||
@@ -52,12 +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_IDENT_LIL "ETIR"
|
||||
#define RITE_BINARY_FORMAT_VER "0006"
|
||||
/* 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"
|
||||
@@ -70,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 */
|
||||
@@ -106,17 +108,6 @@ struct rite_binary_footer {
|
||||
RITE_SECTION_HEADER;
|
||||
};
|
||||
|
||||
static inline int
|
||||
bigendian_p()
|
||||
{
|
||||
int i;
|
||||
char *p;
|
||||
|
||||
i = 1;
|
||||
p = (char*)&i;
|
||||
return p[0]?0:1;
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
uint8_to_bin(uint8_t s, uint8_t *bin)
|
||||
{
|
||||
@@ -142,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)
|
||||
{
|
||||
@@ -161,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
|
||||
|
||||
+63
-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,9 +76,21 @@ 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);
|
||||
|
||||
/** load mruby bytecode functions
|
||||
* Please note! Currently due to interactions with the GC calling these functions will
|
||||
* leak one RProc object per function call.
|
||||
* To prevent this save the current memory arena before calling and restore the arena
|
||||
* right after, like so
|
||||
* int ai = mrb_gc_arena_save(mrb);
|
||||
* mrb_value status = mrb_load_irep(mrb, buffer);
|
||||
* mrb_gc_arena_restore(mrb, ai);
|
||||
*/
|
||||
|
||||
/* @param [const uint8_t*] irep code, expected as a literal */
|
||||
MRB_API mrb_value mrb_load_irep(mrb_state*, const uint8_t*);
|
||||
|
||||
@@ -82,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 */
|
||||
|
||||
@@ -21,7 +21,10 @@ MRB_BEGIN_DECL
|
||||
|
||||
struct RIStruct {
|
||||
MRB_OBJECT_HEADER;
|
||||
char inline_data[ISTRUCT_DATA_SIZE];
|
||||
union {
|
||||
intptr_t inline_alignment[3];
|
||||
char inline_data[ISTRUCT_DATA_SIZE];
|
||||
};
|
||||
};
|
||||
|
||||
#define RISTRUCT(obj) ((struct RIStruct*)(mrb_ptr(obj)))
|
||||
|
||||
+18
-8
@@ -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; \
|
||||
@@ -95,16 +94,25 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
|
||||
__hash_equal: hash comparation function
|
||||
*/
|
||||
#define KHASH_DEFINE(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
|
||||
void kh_alloc_##name(mrb_state *mrb, kh_##name##_t *h) \
|
||||
mrb_noreturn void mrb_raise_nomemory(mrb_state *mrb); \
|
||||
int kh_alloc_simple_##name(mrb_state *mrb, kh_##name##_t *h) \
|
||||
{ \
|
||||
khint_t sz = h->n_buckets; \
|
||||
size_t len = sizeof(khkey_t) + (kh_is_map ? sizeof(khval_t) : 0); \
|
||||
uint8_t *p = (uint8_t*)mrb_malloc(mrb, sizeof(uint8_t)*sz/4+len*sz); \
|
||||
h->size = h->n_occupied = 0; \
|
||||
uint8_t *p = (uint8_t*)mrb_malloc_simple(mrb, sizeof(uint8_t)*sz/4+len*sz); \
|
||||
if (!p) { return 1; } \
|
||||
h->size = 0; \
|
||||
h->keys = (khkey_t *)p; \
|
||||
h->vals = kh_is_map ? (khval_t *)(p+sizeof(khkey_t)*sz) : NULL; \
|
||||
h->ed_flags = p+len*sz; \
|
||||
kh_fill_flags(h->ed_flags, 0xaa, sz/4); \
|
||||
return 0; \
|
||||
} \
|
||||
void kh_alloc_##name(mrb_state *mrb, kh_##name##_t *h) \
|
||||
{ \
|
||||
if (kh_alloc_simple_##name(mrb, h)) { \
|
||||
mrb_raise_nomemory(mrb); \
|
||||
} \
|
||||
} \
|
||||
kh_##name##_t *kh_init_##name##_size(mrb_state *mrb, khint_t size) { \
|
||||
kh_##name##_t *h = (kh_##name##_t*)mrb_calloc(mrb, 1, sizeof(kh_##name##_t)); \
|
||||
@@ -112,7 +120,10 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
|
||||
size = KHASH_MIN_SIZE; \
|
||||
khash_power2(size); \
|
||||
h->n_buckets = size; \
|
||||
kh_alloc_##name(mrb, h); \
|
||||
if (kh_alloc_simple_##name(mrb, h)) { \
|
||||
mrb_free(mrb, h); \
|
||||
mrb_raise_nomemory(mrb); \
|
||||
} \
|
||||
return h; \
|
||||
} \
|
||||
kh_##name##_t *kh_init_##name(mrb_state *mrb) { \
|
||||
@@ -130,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) \
|
||||
@@ -174,7 +185,7 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
|
||||
khint_t kh_put_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key, int *ret) \
|
||||
{ \
|
||||
khint_t k, del_k, step = 0; \
|
||||
if (h->n_occupied >= khash_upper_bound(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); \
|
||||
@@ -204,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; \
|
||||
} \
|
||||
|
||||
+16
-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,15 +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);
|
||||
@@ -136,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;
|
||||
}
|
||||
}
|
||||
@@ -160,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
|
||||
@@ -177,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
|
||||
@@ -187,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 */
|
||||
|
||||
+5
-10
@@ -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)) */
|
||||
@@ -92,8 +90,8 @@ OPCODE(APOST, BBB) /* *R(a),R(a+1)..R(a+c) = R(a)[b..] */
|
||||
OPCODE(INTERN, B) /* R(a) = intern(R(a)) */
|
||||
OPCODE(STRING, BB) /* R(a) = str_dup(Lit(b)) */
|
||||
OPCODE(STRCAT, B) /* str_cat(R(a),R(a+1)) */
|
||||
OPCODE(HASH, BB) /* R(a) = hash_new(R(a),R(a+1)..R(a+b)) */
|
||||
OPCODE(HASHADD, BB) /* R(a) = hash_push(R(a),R(a+1)..R(a+b)) */
|
||||
OPCODE(HASH, BB) /* R(a) = hash_new(R(a),R(a+1)..R(a+b*2-1)) */
|
||||
OPCODE(HASHADD, BB) /* R(a) = hash_push(R(a),R(a+1)..R(a+b*2)) */
|
||||
OPCODE(HASHCAT, B) /* R(a) = hash_cat(R(a),R(a+1)) */
|
||||
OPCODE(LAMBDA, BB) /* R(a) = lambda(SEQ[b],L_LAMBDA) */
|
||||
OPCODE(BLOCK, BB) /* R(a) = lambda(SEQ[b],L_BLOCK) */
|
||||
@@ -111,7 +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 */
|
||||
|
||||
@@ -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 */
|
||||
+23
-18
@@ -22,24 +22,29 @@ struct REnv {
|
||||
mrb_sym mid;
|
||||
};
|
||||
|
||||
/* flags (21bits): 1(shared flag):10(cioff/bidx):10(stack_len) */
|
||||
#define MRB_ENV_SET_STACK_LEN(e,len) ((e)->flags = (((e)->flags & ~0x3ff)|((unsigned int)(len) & 0x3ff)))
|
||||
#define MRB_ENV_STACK_LEN(e) ((mrb_int)((e)->flags & 0x3ff))
|
||||
#define MRB_ENV_STACK_UNSHARED (1<<20)
|
||||
#define MRB_ENV_UNSHARE_STACK(e) ((e)->flags |= MRB_ENV_STACK_UNSHARED)
|
||||
#define MRB_ENV_STACK_SHARED_P(e) (((e)->flags & MRB_ENV_STACK_UNSHARED) == 0)
|
||||
#define MRB_ENV_BIDX(e) (((e)->flags >> 10) & 0x3ff)
|
||||
#define MRB_ENV_SET_BIDX(e,idx) ((e)->flags = (((e)->flags & ~(0x3ff<<10))|((unsigned int)(idx) & 0x3ff)<<10))
|
||||
/* flags (21bits): 1(close):1(touched):1(heap):8(cioff/bidx):8(stack_len) */
|
||||
#define MRB_ENV_SET_LEN(e,len) ((e)->flags = (((e)->flags & ~0xff)|((unsigned int)(len) & 0xff)))
|
||||
#define MRB_ENV_LEN(e) ((mrb_int)((e)->flags & 0xff))
|
||||
#define MRB_ENV_CLOSED (1<<20)
|
||||
#define MRB_ENV_TOUCHED (1<<19)
|
||||
#define MRB_ENV_HEAPED (1<<18)
|
||||
#define MRB_ENV_CLOSE(e) ((e)->flags |= MRB_ENV_CLOSED)
|
||||
#define MRB_ENV_TOUCH(e) ((e)->flags |= MRB_ENV_TOUCHED)
|
||||
#define MRB_ENV_HEAP(e) ((e)->flags |= MRB_ENV_HEAPED)
|
||||
#define MRB_ENV_HEAP_P(e) ((e)->flags & MRB_ENV_HEAPED)
|
||||
#define MRB_ENV_ONSTACK_P(e) (((e)->flags & MRB_ENV_CLOSED) == 0)
|
||||
#define MRB_ENV_BIDX(e) (((e)->flags >> 8) & 0xff)
|
||||
#define MRB_ENV_SET_BIDX(e,idx) ((e)->flags = (((e)->flags & ~(0xff<<8))|((unsigned int)(idx) & 0xff)<<8))
|
||||
|
||||
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;
|
||||
@@ -52,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
|
||||
@@ -81,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);
|
||||
@@ -99,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)
|
||||
@@ -123,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))
|
||||
@@ -132,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
|
||||
};
|
||||
|
||||
|
||||
+61
-43
@@ -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
|
||||
@@ -103,34 +107,36 @@ static const unsigned int IEEE754_INFINITY_BITS_SINGLE = 0x7F800000;
|
||||
#endif
|
||||
|
||||
enum mrb_vtype {
|
||||
MRB_TT_FALSE = 0, /* 0 */
|
||||
MRB_TT_TRUE, /* 1 */
|
||||
MRB_TT_FLOAT, /* 2 */
|
||||
MRB_TT_FIXNUM, /* 3 */
|
||||
MRB_TT_SYMBOL, /* 4 */
|
||||
MRB_TT_UNDEF, /* 5 */
|
||||
MRB_TT_CPTR, /* 6 */
|
||||
MRB_TT_FREE, /* 7 */
|
||||
MRB_TT_OBJECT, /* 8 */
|
||||
MRB_TT_CLASS, /* 9 */
|
||||
MRB_TT_MODULE, /* 10 */
|
||||
MRB_TT_ICLASS, /* 11 */
|
||||
MRB_TT_SCLASS, /* 12 */
|
||||
MRB_TT_PROC, /* 13 */
|
||||
MRB_TT_ARRAY, /* 14 */
|
||||
MRB_TT_HASH, /* 15 */
|
||||
MRB_TT_STRING, /* 16 */
|
||||
MRB_TT_RANGE, /* 17 */
|
||||
MRB_TT_EXCEPTION, /* 18 */
|
||||
MRB_TT_FILE, /* 19 */
|
||||
MRB_TT_ENV, /* 20 */
|
||||
MRB_TT_DATA, /* 21 */
|
||||
MRB_TT_FIBER, /* 22 */
|
||||
MRB_TT_ISTRUCT, /* 23 */
|
||||
MRB_TT_BREAK, /* 24 */
|
||||
MRB_TT_MAXDEFINE /* 25 */
|
||||
MRB_TT_FALSE = 0,
|
||||
MRB_TT_TRUE,
|
||||
MRB_TT_FLOAT,
|
||||
MRB_TT_INTEGER,
|
||||
MRB_TT_SYMBOL,
|
||||
MRB_TT_UNDEF,
|
||||
MRB_TT_CPTR,
|
||||
MRB_TT_FREE,
|
||||
MRB_TT_OBJECT,
|
||||
MRB_TT_CLASS,
|
||||
MRB_TT_MODULE,
|
||||
MRB_TT_ICLASS,
|
||||
MRB_TT_SCLASS,
|
||||
MRB_TT_PROC,
|
||||
MRB_TT_ARRAY,
|
||||
MRB_TT_HASH,
|
||||
MRB_TT_STRING,
|
||||
MRB_TT_RANGE,
|
||||
MRB_TT_EXCEPTION,
|
||||
MRB_TT_ENV,
|
||||
MRB_TT_DATA,
|
||||
MRB_TT_FIBER,
|
||||
MRB_TT_ISTRUCT,
|
||||
MRB_TT_BREAK,
|
||||
MRB_TT_MAXDEFINE
|
||||
};
|
||||
|
||||
/* for compatibility */
|
||||
#define MRB_TT_FIXNUM MRB_TT_INTEGER
|
||||
|
||||
#include <mruby/object.h>
|
||||
|
||||
#ifdef MRB_DOCUMENTATION_BLOCK
|
||||
@@ -149,6 +155,13 @@ typedef void mrb_value;
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(MRB_WORD_BOXING) || (defined(MRB_NAN_BOXING) && defined(MRB_64BIT))
|
||||
struct RCptr {
|
||||
MRB_OBJECT_HEADER;
|
||||
void *p;
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(MRB_NAN_BOXING)
|
||||
#include "boxing_nan.h"
|
||||
#elif defined(MRB_WORD_BOXING)
|
||||
@@ -171,8 +184,11 @@ typedef void mrb_value;
|
||||
#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)
|
||||
@@ -189,7 +205,7 @@ typedef void mrb_value;
|
||||
#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
|
||||
@@ -233,9 +249,6 @@ typedef void mrb_value;
|
||||
#ifndef mrb_range_p
|
||||
#define mrb_range_p(o) (mrb_type(o) == MRB_TT_RANGE)
|
||||
#endif
|
||||
#ifndef mrb_file_p
|
||||
#define mrb_file_p(o) (mrb_type(o) == MRB_TT_FILE)
|
||||
#endif
|
||||
#ifndef mrb_env_p
|
||||
#define mrb_env_p(o) (mrb_type(o) == MRB_TT_ENV)
|
||||
#endif
|
||||
@@ -261,7 +274,7 @@ typedef void mrb_value;
|
||||
*
|
||||
* 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;
|
||||
@@ -281,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 1
|
||||
#define MRUBY_RELEASE_TEENY 0
|
||||
|
||||
/*
|
||||
* The mruby version.
|
||||
@@ -67,12 +67,12 @@ MRB_BEGIN_DECL
|
||||
/*
|
||||
* Release month.
|
||||
*/
|
||||
#define MRUBY_RELEASE_MONTH 4
|
||||
#define MRUBY_RELEASE_MONTH 10
|
||||
|
||||
/*
|
||||
* Release day.
|
||||
*/
|
||||
#define MRUBY_RELEASE_DAY 20
|
||||
#define MRUBY_RELEASE_DAY 16
|
||||
|
||||
/*
|
||||
* Release date as a string.
|
||||
|
||||
+27
-32
@@ -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
|
||||
@@ -336,7 +339,8 @@ EOS
|
||||
puts " Binaries: #{@bins.join(', ')}" unless @bins.empty?
|
||||
unless @gems.empty?
|
||||
puts " Included Gems:"
|
||||
@gems.map do |gem|
|
||||
gems = @gems.sort_by { |gem| gem.name }
|
||||
gems.each do |gem|
|
||||
gem_version = " - #{gem.version}" if gem.version != '0.0.0'
|
||||
gem_summary = " - #{gem.summary}" if gem.summary
|
||||
puts " #{gem.name}#{gem_version}#{gem_summary}"
|
||||
@@ -368,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
|
||||
@@ -387,26 +403,5 @@ EOS
|
||||
@test_runner.run(mrbtest)
|
||||
end
|
||||
end
|
||||
|
||||
def big_endian
|
||||
if @endian
|
||||
puts "Endian has already specified as #{@endian}."
|
||||
return
|
||||
end
|
||||
@endian = :big
|
||||
@mrbc.compile_options += ' -E'
|
||||
compilers.each do |c|
|
||||
c.defines += %w(MRB_ENDIAN_BIG)
|
||||
end
|
||||
end
|
||||
|
||||
def little_endian
|
||||
if @endian
|
||||
puts "Endian has already specified as #{@endian}."
|
||||
return
|
||||
end
|
||||
@endian = :little
|
||||
@mrbc.compile_options += ' -e'
|
||||
end
|
||||
end # CrossBuild
|
||||
end # MRuby
|
||||
|
||||
+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
|
||||
|
||||
+3
-1
@@ -6,7 +6,9 @@ module MRuby
|
||||
ROOT = Pathname.new(File.expand_path('../../../',__FILE__))
|
||||
|
||||
# Reads a constant defined at version.h
|
||||
MRUBY_READ_VERSION_CONSTANT = Proc.new { |name| ROOT.join('include','mruby','version.h').read.match(/^#define #{name} +"?([\w\. ]+)"?$/)[1] }
|
||||
MRUBY_READ_VERSION_CONSTANT = Proc.new do |name|
|
||||
ROOT.join('include','mruby','version.h').read.match(/^#define #{name} +"?([\w\. ]+)"?\r?$/)[1]
|
||||
end
|
||||
|
||||
MRUBY_RUBY_VERSION = MRUBY_READ_VERSION_CONSTANT['MRUBY_RUBY_VERSION']
|
||||
MRUBY_RUBY_ENGINE = MRUBY_READ_VERSION_CONSTANT['MRUBY_RUBY_ENGINE']
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -71,6 +74,10 @@ MRuby::GemBox.new do |conf|
|
||||
# Use toplevel object (main) methods extension
|
||||
conf.gem :core => "mruby-toplevel-ext"
|
||||
|
||||
# Use Rational/Complex numbers
|
||||
conf.gem :core => "mruby-rational"
|
||||
conf.gem :core => "mruby-complex"
|
||||
|
||||
# Generate mirb command
|
||||
conf.gem :core => "mruby-bin-mirb"
|
||||
|
||||
@@ -80,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"
|
||||
|
||||
@@ -89,6 +99,9 @@ MRuby::GemBox.new do |conf|
|
||||
# Use Method/UnboundMethod class
|
||||
conf.gem :core => "mruby-method"
|
||||
|
||||
# Use eval()
|
||||
conf.gem :core => "mruby-eval"
|
||||
|
||||
# Use mruby-compiler to build other mrbgems
|
||||
conf.gem :core => "mruby-compiler"
|
||||
end
|
||||
|
||||
@@ -28,9 +28,8 @@ static mrb_value
|
||||
mrb_ary_assoc(mrb_state *mrb, mrb_value ary)
|
||||
{
|
||||
mrb_int i;
|
||||
mrb_value v, k;
|
||||
|
||||
mrb_get_args(mrb, "o", &k);
|
||||
mrb_value v;
|
||||
mrb_value k = mrb_get_arg1(mrb);
|
||||
|
||||
for (i = 0; i < RARRAY_LEN(ary); ++i) {
|
||||
v = mrb_check_array_type(mrb, RARRAY_PTR(ary)[i]);
|
||||
@@ -59,9 +58,8 @@ static mrb_value
|
||||
mrb_ary_rassoc(mrb_state *mrb, mrb_value ary)
|
||||
{
|
||||
mrb_int i;
|
||||
mrb_value v, value;
|
||||
|
||||
mrb_get_args(mrb, "o", &value);
|
||||
mrb_value v;
|
||||
mrb_value value = mrb_get_arg1(mrb);
|
||||
|
||||
for (i = 0; i < RARRAY_LEN(ary); ++i) {
|
||||
v = RARRAY_PTR(ary)[i];
|
||||
@@ -140,9 +138,8 @@ mrb_ary_slice_bang(mrb_state *mrb, mrb_value self)
|
||||
mrb_ary_modify(mrb, a);
|
||||
|
||||
if (mrb_get_argc(mrb) == 1) {
|
||||
mrb_value index;
|
||||
mrb_value index = mrb_get_arg1(mrb);
|
||||
|
||||
mrb_get_args(mrb, "o|i", &index, &len);
|
||||
switch (mrb_type(index)) {
|
||||
case MRB_TT_RANGE:
|
||||
if (mrb_range_beg_len(mrb, index, &i, &len, ARY_LEN(a), TRUE) == MRB_RANGE_OK) {
|
||||
@@ -151,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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,13 +5,16 @@ unless MRuby::Build.current.kind_of?(MRuby::CrossBuild)
|
||||
spec.author = 'mruby developers'
|
||||
spec.summary = "#{name} command"
|
||||
|
||||
mruby_config_dir = "#{build.build_dir}/bin"
|
||||
mruby_config = name + (ENV['OS'] == 'Windows_NT' ? '.bat' : '')
|
||||
mruby_config_path = "#{build.build_dir}/bin/#{mruby_config}"
|
||||
mruby_config_path = "#{mruby_config_dir}/#{mruby_config}"
|
||||
make_cfg = "#{build.build_dir}/lib/libmruby.flags.mak"
|
||||
tmplt_path = "#{__dir__}/#{mruby_config}"
|
||||
build.bins << mruby_config
|
||||
|
||||
file mruby_config_path => [make_cfg, tmplt_path] do |t|
|
||||
directory mruby_config_dir
|
||||
|
||||
file mruby_config_path => [mruby_config_dir, make_cfg, tmplt_path] do |t|
|
||||
config = Hash[File.readlines(make_cfg).map!(&:chomp).map! {|l|
|
||||
l.gsub('\\"', '"').split(' = ', 2).map! {|s| s.sub(/^(?=.)/, 'echo ')}
|
||||
}]
|
||||
|
||||
@@ -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;
|
||||
@@ -649,8 +651,8 @@ main(int argc, char **argv)
|
||||
/* adjust stack length of toplevel environment */
|
||||
if (mrb->c->cibase->env) {
|
||||
struct REnv *e = mrb->c->cibase->env;
|
||||
if (e && MRB_ENV_STACK_LEN(e) < proc->body.irep->nlocals) {
|
||||
MRB_ENV_SET_STACK_LEN(e, proc->body.irep->nlocals);
|
||||
if (e && MRB_ENV_LEN(e) < proc->body.irep->nlocals) {
|
||||
MRB_ENV_SET_LEN(e, proc->body.irep->nlocals);
|
||||
}
|
||||
}
|
||||
/* pass a proc for evaluation */
|
||||
@@ -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,12 +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",
|
||||
"-e generate little endian iseq data",
|
||||
"-E generate big endian iseq data",
|
||||
"-S dump C struct (requires -B)",
|
||||
"--remove-lv remove local variables",
|
||||
"--verbose run at verbose mode",
|
||||
"--version print the version",
|
||||
@@ -46,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++);
|
||||
}
|
||||
@@ -54,19 +54,26 @@ usage(const char *name)
|
||||
static char *
|
||||
get_outfilename(mrb_state *mrb, char *infile, const char *ext)
|
||||
{
|
||||
size_t infilelen;
|
||||
size_t extlen;
|
||||
size_t ilen, flen, elen;
|
||||
char *outfile;
|
||||
char *p;
|
||||
char *p = NULL;
|
||||
|
||||
infilelen = strlen(infile);
|
||||
extlen = strlen(ext);
|
||||
outfile = (char*)mrb_malloc(mrb, infilelen + extlen + 1);
|
||||
memcpy(outfile, infile, infilelen + 1);
|
||||
ilen = strlen(infile);
|
||||
flen = ilen;
|
||||
if (*ext) {
|
||||
if ((p = strrchr(outfile, '.')) == NULL)
|
||||
p = outfile + infilelen;
|
||||
memcpy(p, ext, extlen + 1);
|
||||
elen = strlen(ext);
|
||||
if ((p = strrchr(infile, '.'))) {
|
||||
ilen = p - infile;
|
||||
}
|
||||
flen += elen;
|
||||
}
|
||||
else {
|
||||
flen = ilen;
|
||||
}
|
||||
outfile = (char*)mrb_malloc(mrb, flen+1);
|
||||
strncpy(outfile, infile, ilen+1);
|
||||
if (p) {
|
||||
strncpy(outfile+ilen, ext, elen+1);
|
||||
}
|
||||
|
||||
return outfile;
|
||||
@@ -100,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++;
|
||||
@@ -124,10 +134,8 @@ parse_args(mrb_state *mrb, int argc, char **argv, struct mrbc_args *args)
|
||||
args->flags |= DUMP_DEBUG_INFO;
|
||||
break;
|
||||
case 'E':
|
||||
args->flags = DUMP_ENDIAN_BIG | (args->flags & ~DUMP_ENDIAN_MASK);
|
||||
break;
|
||||
case 'e':
|
||||
args->flags = DUMP_ENDIAN_LIL | (args->flags & ~DUMP_ENDIAN_MASK);
|
||||
fprintf(stderr, "%s: -e/-E option no longer needed.\n", args->prog);
|
||||
break;
|
||||
case 'h':
|
||||
return -1;
|
||||
@@ -160,10 +168,6 @@ parse_args(mrb_state *mrb, int argc, char **argv, struct mrbc_args *args)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (args->verbose && args->initname && (args->flags & DUMP_ENDIAN_MASK) == 0) {
|
||||
fprintf(stderr, "%s: generating %s endian C file. specify -e/-E for cross compiling.\n",
|
||||
args->prog, bigendian_p() ? "big" : "little");
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
@@ -239,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
|
||||
|
||||
@@ -4,7 +4,6 @@ MRuby::Gem::Specification.new('mruby-bin-mruby') do |spec|
|
||||
spec.summary = 'mruby command'
|
||||
spec.bins = %w(mruby)
|
||||
spec.add_dependency('mruby-compiler', :core => 'mruby-compiler')
|
||||
spec.add_dependency('mruby-error', :core => 'mruby-error')
|
||||
spec.add_test_dependency('mruby-print', :core => 'mruby-print')
|
||||
|
||||
if build.cxx_exception_enabled?
|
||||
|
||||
@@ -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
|
||||
@@ -43,10 +43,15 @@ mrb_mod_module_exec(mrb_state *mrb, mrb_value self)
|
||||
const mrb_value *argv;
|
||||
mrb_int argc;
|
||||
mrb_value blk;
|
||||
struct RClass *c;
|
||||
|
||||
mrb_get_args(mrb, "*&!", &argv, &argc, &blk);
|
||||
|
||||
mrb->c->ci->target_class = mrb_class_ptr(self);
|
||||
c = mrb_class_ptr(self);
|
||||
if (mrb->c->ci->acc < 0) {
|
||||
return mrb_yield_with_class(mrb, blk, argc, argv, self, c);
|
||||
}
|
||||
mrb->c->ci->target_class = c;
|
||||
return mrb_yield_cont(mrb, blk, self, argc, argv);
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+285
-115
@@ -9,7 +9,6 @@
|
||||
#ifdef PARSER_DEBUG
|
||||
# define YYDEBUG 1
|
||||
#endif
|
||||
#define YYERROR_VERBOSE 1
|
||||
#define YYSTACK_USE_ALLOCA 1
|
||||
|
||||
#include <ctype.h>
|
||||
@@ -266,6 +265,7 @@ local_unnest(parser_state *p)
|
||||
static mrb_bool
|
||||
local_var_p(parser_state *p, mrb_sym sym)
|
||||
{
|
||||
const struct RProc *u;
|
||||
node *l = p->locals;
|
||||
|
||||
while (l) {
|
||||
@@ -276,6 +276,20 @@ local_var_p(parser_state *p, mrb_sym sym)
|
||||
}
|
||||
l = l->cdr;
|
||||
}
|
||||
|
||||
u = p->upper;
|
||||
while (u && !MRB_PROC_CFUNC_P(u)) {
|
||||
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;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -299,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*
|
||||
@@ -718,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)) */
|
||||
@@ -726,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) */
|
||||
@@ -827,6 +865,13 @@ new_kw_arg(parser_state *p, mrb_sym kw, node *def_arg)
|
||||
return list3((node*)NODE_KW_ARG, nsym(kw), def_arg);
|
||||
}
|
||||
|
||||
/* (:kw_rest_args . a) */
|
||||
static node*
|
||||
new_kw_rest_args(parser_state *p, node *a)
|
||||
{
|
||||
return cons((node*)NODE_KW_REST_ARGS, a);
|
||||
}
|
||||
|
||||
/* (:block_arg . a) */
|
||||
static node*
|
||||
new_block_arg(parser_state *p, node *a)
|
||||
@@ -913,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) */
|
||||
@@ -936,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)
|
||||
@@ -1323,7 +1368,8 @@ heredoc_end(parser_state *p)
|
||||
|
||||
%}
|
||||
|
||||
%pure-parser
|
||||
%define parse.error verbose
|
||||
%define api.pure
|
||||
%parse-param {parser_state *p}
|
||||
%lex-param {parser_state *p}
|
||||
|
||||
@@ -1395,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
|
||||
@@ -1405,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
|
||||
@@ -1638,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);
|
||||
@@ -1651,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
|
||||
{
|
||||
@@ -1706,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);
|
||||
@@ -1882,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
|
||||
{
|
||||
@@ -1921,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
|
||||
{
|
||||
@@ -2009,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__
|
||||
@@ -2065,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
|
||||
{
|
||||
@@ -2098,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);
|
||||
@@ -2226,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;
|
||||
@@ -2265,6 +2401,30 @@ paren_args : '(' opt_call_args ')'
|
||||
{
|
||||
$$ = $2;
|
||||
}
|
||||
| '(' tDOT3 rparen
|
||||
{
|
||||
#if 1
|
||||
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_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))))),
|
||||
new_block_arg(p, new_lvar(p, b)));
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
yyerror(p, "unexpected argument forwarding ...");
|
||||
$$ = 0;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
opt_paren_args : none
|
||||
@@ -2601,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
|
||||
{
|
||||
@@ -2966,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
|
||||
{
|
||||
@@ -2982,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, '.');
|
||||
}
|
||||
;
|
||||
|
||||
@@ -3355,12 +3491,33 @@ superclass : /* term */
|
||||
} */
|
||||
;
|
||||
|
||||
f_arglist : '(' f_args rparen
|
||||
f_arglist_paren : '(' f_args rparen
|
||||
{
|
||||
$$ = $2;
|
||||
p->lstate = EXPR_BEG;
|
||||
p->cmd_start = TRUE;
|
||||
}
|
||||
| '(' tDOT3 rparen
|
||||
{
|
||||
#if 1
|
||||
/* til real keyword args implemented */
|
||||
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_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;
|
||||
@@ -3424,11 +3581,11 @@ kwrest_mark : tPOW
|
||||
|
||||
f_kwrest : kwrest_mark tIDENTIFIER
|
||||
{
|
||||
$$ = cons((node*)NODE_KW_REST_ARGS, nsym($2));
|
||||
$$ = new_kw_rest_args(p, nsym($2));
|
||||
}
|
||||
| kwrest_mark
|
||||
{
|
||||
$$ = cons((node*)NODE_KW_REST_ARGS, 0);
|
||||
$$ = new_kw_rest_args(p, 0);
|
||||
}
|
||||
;
|
||||
|
||||
@@ -3518,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);
|
||||
}
|
||||
;
|
||||
@@ -3642,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;
|
||||
}
|
||||
;
|
||||
@@ -3743,7 +3900,7 @@ assoc : arg tASSOC arg
|
||||
| tDSTAR arg
|
||||
{
|
||||
void_expr_error(p, $2);
|
||||
$$ = cons(cons((node*)NODE_KW_REST_ARGS, 0), $2);
|
||||
$$ = cons(new_kw_rest_args(p, 0), $2);
|
||||
}
|
||||
;
|
||||
|
||||
@@ -3807,7 +3964,7 @@ term : ';' {yyerrok;}
|
||||
|
||||
nl : '\n'
|
||||
{
|
||||
p->lineno++;
|
||||
p->lineno += $<num>1;
|
||||
p->column = 0;
|
||||
}
|
||||
;
|
||||
@@ -4795,6 +4952,7 @@ static int
|
||||
parser_yylex(parser_state *p)
|
||||
{
|
||||
int32_t c;
|
||||
int nlines = 1;
|
||||
int space_seen = 0;
|
||||
int cmd_state;
|
||||
enum mrb_lex_state_enum last_state;
|
||||
@@ -4852,6 +5010,7 @@ parser_yylex(parser_state *p)
|
||||
break;
|
||||
}
|
||||
if (p->parsing_heredoc != NULL) {
|
||||
pylval.num = nlines;
|
||||
return '\n';
|
||||
}
|
||||
while ((c = nextc(p))) {
|
||||
@@ -4861,13 +5020,13 @@ parser_yylex(parser_state *p)
|
||||
space_seen = 1;
|
||||
break;
|
||||
case '#': /* comment as a whitespace */
|
||||
pushback(p, '#');
|
||||
p->lineno++;
|
||||
goto retry;
|
||||
skip(p, '\n');
|
||||
nlines++;
|
||||
break;
|
||||
case '.':
|
||||
if (!peek(p, '.')) {
|
||||
pushback(p, '.');
|
||||
p->lineno++;
|
||||
p->lineno+=nlines; nlines=1;
|
||||
goto retry;
|
||||
}
|
||||
pushback(p, c);
|
||||
@@ -4875,7 +5034,7 @@ parser_yylex(parser_state *p)
|
||||
case '&':
|
||||
if (peek(p, '.')) {
|
||||
pushback(p, '&');
|
||||
p->lineno++;
|
||||
p->lineno+=nlines; nlines=1;
|
||||
goto retry;
|
||||
}
|
||||
pushback(p, c);
|
||||
@@ -4891,12 +5050,13 @@ parser_yylex(parser_state *p)
|
||||
normal_newline:
|
||||
p->cmd_start = TRUE;
|
||||
p->lstate = EXPR_BEG;
|
||||
pylval.num = nlines;
|
||||
return '\n';
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -4914,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;
|
||||
}
|
||||
@@ -4973,7 +5133,7 @@ parser_yylex(parser_state *p)
|
||||
c = nextc(p);
|
||||
} while (!(c < 0 || ISSPACE(c)));
|
||||
if (c != '\n') skip(p, '\n');
|
||||
p->lineno++;
|
||||
p->lineno+=nlines; nlines=1;
|
||||
p->column = 0;
|
||||
goto retry;
|
||||
}
|
||||
@@ -5030,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;
|
||||
}
|
||||
@@ -5052,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;
|
||||
}
|
||||
@@ -5160,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;
|
||||
}
|
||||
@@ -5172,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;
|
||||
}
|
||||
@@ -5199,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;
|
||||
}
|
||||
@@ -5207,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;
|
||||
}
|
||||
@@ -5231,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;
|
||||
}
|
||||
@@ -5259,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;
|
||||
}
|
||||
@@ -5509,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;
|
||||
@@ -5579,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;
|
||||
}
|
||||
@@ -5598,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;
|
||||
}
|
||||
@@ -5695,7 +5855,7 @@ parser_yylex(parser_state *p)
|
||||
case '\\':
|
||||
c = nextc(p);
|
||||
if (c == '\n') {
|
||||
p->lineno++;
|
||||
p->lineno+=nlines; nlines=1;
|
||||
p->column = 0;
|
||||
space_seen = 1;
|
||||
goto retry; /* skip \\n */
|
||||
@@ -5775,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;
|
||||
}
|
||||
@@ -6140,7 +6300,7 @@ parser_init_cxt(parser_state *p, mrbc_context *cxt)
|
||||
}
|
||||
p->capture_errors = cxt->capture_errors;
|
||||
p->no_optimize = cxt->no_optimize;
|
||||
p->on_eval = cxt->on_eval;
|
||||
p->upper = cxt->upper;
|
||||
if (cxt->partial_hook) {
|
||||
p->cxt = cxt;
|
||||
}
|
||||
@@ -6311,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);
|
||||
@@ -6324,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;
|
||||
}
|
||||
}
|
||||
@@ -6393,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();
|
||||
@@ -6413,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();
|
||||
@@ -6423,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();
|
||||
}
|
||||
@@ -6559,7 +6729,7 @@ dump_args(mrb_state *mrb, node *n, int offset)
|
||||
static const char*
|
||||
str_dump(mrb_state *mrb, const char *str, int len)
|
||||
{
|
||||
mrb_int ai = mrb_gc_arena_save(mrb);
|
||||
int ai = mrb_gc_arena_save(mrb);
|
||||
mrb_value s;
|
||||
# if INT_MAX > MRB_INT_MAX / 4
|
||||
/* check maximum length with "\xNN" charactor */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,35 +3,33 @@ MRuby::Gem::Specification.new 'mruby-compiler' do |spec|
|
||||
spec.author = 'mruby developers'
|
||||
spec.summary = 'mruby compiler library'
|
||||
|
||||
current_dir = spec.dir
|
||||
current_build_dir = spec.build_dir
|
||||
|
||||
lex_def = "#{current_dir}/core/lex.def"
|
||||
core_objs = Dir.glob("#{current_dir}/core/*.c").map { |f|
|
||||
lex_def = "#{dir}/core/lex.def"
|
||||
core_objs = Dir.glob("#{dir}/core/*.c").map { |f|
|
||||
next nil if build.cxx_exception_enabled? and f =~ /(codegen).c$/
|
||||
objfile(f.pathmap("#{current_build_dir}/core/%n"))
|
||||
objfile(f.pathmap("#{build_dir}/core/%n"))
|
||||
}.compact
|
||||
|
||||
if build.cxx_exception_enabled?
|
||||
core_objs <<
|
||||
build.compile_as_cxx("#{current_build_dir}/core/y.tab.c", "#{current_build_dir}/core/y.tab.cxx",
|
||||
objfile("#{current_build_dir}/y.tab"), ["#{current_dir}/core"]) <<
|
||||
build.compile_as_cxx("#{current_dir}/core/codegen.c", "#{current_build_dir}/core/codegen.cxx")
|
||||
build.compile_as_cxx("#{dir}/core/y.tab.c", "#{build_dir}/core/y.tab.cxx",
|
||||
objfile("#{build_dir}/y.tab"), ["#{dir}/core"]) <<
|
||||
build.compile_as_cxx("#{dir}/core/codegen.c", "#{build_dir}/core/codegen.cxx")
|
||||
else
|
||||
core_objs << objfile("#{current_build_dir}/core/y.tab")
|
||||
file objfile("#{current_build_dir}/core/y.tab") => "#{current_build_dir}/core/y.tab.c" do |t|
|
||||
cc.run t.name, t.prerequisites.first, [], ["#{current_dir}/core"]
|
||||
core_objs << objfile("#{build_dir}/core/y.tab")
|
||||
file objfile("#{build_dir}/core/y.tab") => "#{dir}/core/y.tab.c" do |t|
|
||||
cc.run t.name, t.prerequisites.first, [], ["#{dir}/core"]
|
||||
end
|
||||
end
|
||||
|
||||
# Parser
|
||||
file "#{current_build_dir}/core/y.tab.c" => ["#{current_dir}/core/parse.y", lex_def] do |t|
|
||||
mkdir_p File.dirname t.name
|
||||
file "#{dir}/core/y.tab.c" => ["#{dir}/core/parse.y", lex_def] do |t|
|
||||
yacc.run t.name, t.prerequisites.first
|
||||
content = File.read(t.name).gsub(/^#line +\d+ +"\K.*$/){$&.relative_path}
|
||||
File.write(t.name, content)
|
||||
end
|
||||
|
||||
# Lexical analyzer
|
||||
file lex_def => "#{current_dir}/core/keywords" do |t|
|
||||
file lex_def => "#{dir}/core/keywords" do |t|
|
||||
gperf.run t.name, t.prerequisites.first
|
||||
end
|
||||
|
||||
|
||||
@@ -104,10 +104,10 @@ 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"
|
||||
original_operator_name = :"__original_operator_#{op}_complex"
|
||||
alias_method original_operator_name, op
|
||||
define_method op do |rhs|
|
||||
if rhs.is_a? 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
|
||||
@@ -174,7 +174,7 @@ div_pair(struct float_pair *q, struct float_pair const *a,
|
||||
static mrb_value
|
||||
complex_div(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value rhs;
|
||||
mrb_value rhs = mrb_get_arg1(mrb);
|
||||
struct mrb_complex *a, *b;
|
||||
struct float_pair ar, ai, br, bi;
|
||||
struct float_pair br2, bi2;
|
||||
@@ -183,7 +183,6 @@ complex_div(mrb_state *mrb, mrb_value self)
|
||||
struct float_pair ai_br, ar_bi;
|
||||
struct float_pair zr, zi;
|
||||
|
||||
mrb_get_args(mrb, "o", &rhs);
|
||||
a = complex_ptr(mrb, self);
|
||||
b = complex_ptr(mrb, rhs);
|
||||
|
||||
@@ -225,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 = []
|
||||
|
||||
+10
-221
@@ -9,221 +9,10 @@
|
||||
mrb_value mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p);
|
||||
mrb_value mrb_obj_instance_eval(mrb_state *mrb, mrb_value self);
|
||||
|
||||
static struct mrb_irep *
|
||||
get_closure_irep(mrb_state *mrb, int level)
|
||||
{
|
||||
struct RProc *proc = mrb->c->ci[-1].proc;
|
||||
|
||||
while (level--) {
|
||||
if (!proc) return NULL;
|
||||
proc = proc->upper;
|
||||
}
|
||||
if (!proc) return NULL;
|
||||
if (MRB_PROC_CFUNC_P(proc)) {
|
||||
return NULL;
|
||||
}
|
||||
return proc->body.irep;
|
||||
}
|
||||
|
||||
/* search for irep lev above the bottom */
|
||||
static mrb_irep*
|
||||
search_irep(mrb_irep *top, int bnest, int lev, mrb_irep *bottom)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<top->rlen; i++) {
|
||||
mrb_irep* tmp = top->reps[i];
|
||||
|
||||
if (tmp == bottom) return top;
|
||||
tmp = search_irep(tmp, bnest-1, lev, bottom);
|
||||
if (tmp) {
|
||||
if (bnest == lev) return top;
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
search_variable(mrb_state *mrb, mrb_sym vsym, int bnest)
|
||||
{
|
||||
mrb_irep *virep;
|
||||
int level;
|
||||
int pos;
|
||||
|
||||
for (level = 0; (virep = get_closure_irep(mrb, level)); level++) {
|
||||
if (virep->lv == NULL) {
|
||||
continue;
|
||||
}
|
||||
for (pos = 0; pos < virep->nlocals - 1; pos++) {
|
||||
if (vsym == virep->lv[pos].name) {
|
||||
return (pos+1)<<8 | (level+bnest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
irep_argc(mrb_irep *irep)
|
||||
{
|
||||
mrb_code c;
|
||||
|
||||
c = irep->iseq[0];
|
||||
if (c == OP_ENTER) {
|
||||
mrb_aspec ax = PEEK_W(irep->iseq+1);
|
||||
/* extra 1 means a slot for block */
|
||||
return MRB_ASPEC_REQ(ax)+MRB_ASPEC_OPT(ax)+MRB_ASPEC_REST(ax)+MRB_ASPEC_POST(ax)+1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static mrb_bool
|
||||
potential_upvar_p(struct mrb_locals *lv, uint16_t v, int argc, uint16_t nlocals)
|
||||
{
|
||||
if (v >= nlocals) return FALSE;
|
||||
/* skip arguments */
|
||||
if (v < argc+1) return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
extern uint8_t mrb_insn_size[];
|
||||
extern uint8_t mrb_insn_size1[];
|
||||
extern uint8_t mrb_insn_size2[];
|
||||
extern uint8_t mrb_insn_size3[];
|
||||
|
||||
static void
|
||||
patch_irep(mrb_state *mrb, mrb_irep *irep, int bnest, mrb_irep *top)
|
||||
{
|
||||
int i;
|
||||
uint32_t a;
|
||||
uint16_t b;
|
||||
uint8_t c;
|
||||
mrb_code insn;
|
||||
int argc = irep_argc(irep);
|
||||
mrb_code *iseq = (mrb_code *)irep->iseq;
|
||||
|
||||
mrb_assert((irep->flags & MRB_ISEQ_NO_FREE) == 0);
|
||||
|
||||
for (i = 0; i < irep->ilen; ) {
|
||||
insn = iseq[i];
|
||||
switch(insn){
|
||||
case OP_EPUSH:
|
||||
a = PEEK_B(iseq+i+1);
|
||||
patch_irep(mrb, irep->reps[a], bnest + 1, top);
|
||||
break;
|
||||
|
||||
case OP_LAMBDA:
|
||||
case OP_BLOCK:
|
||||
a = PEEK_B(iseq+i+1);
|
||||
b = PEEK_B(iseq+i+2);
|
||||
patch_irep(mrb, irep->reps[b], bnest + 1, top);
|
||||
break;
|
||||
|
||||
case OP_SEND:
|
||||
b = PEEK_B(iseq+i+2);
|
||||
c = PEEK_B(iseq+i+3);
|
||||
if (c != 0) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
uint16_t arg = search_variable(mrb, irep->syms[b], bnest);
|
||||
if (arg != 0) {
|
||||
/* must replace */
|
||||
iseq[i] = OP_GETUPVAR;
|
||||
iseq[i+2] = arg >> 8;
|
||||
iseq[i+3] = arg & 0xff;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_MOVE:
|
||||
a = PEEK_B(iseq+i+1);
|
||||
b = PEEK_B(iseq+i+2);
|
||||
/* src part */
|
||||
if (potential_upvar_p(irep->lv, b, argc, irep->nlocals)) {
|
||||
uint16_t arg = search_variable(mrb, irep->lv[b - 1].name, bnest);
|
||||
if (arg != 0) {
|
||||
/* must replace */
|
||||
iseq[i] = insn = OP_GETUPVAR;
|
||||
iseq[i+2] = arg >> 8;
|
||||
iseq[i+3] = arg & 0xff;
|
||||
}
|
||||
}
|
||||
/* dst part */
|
||||
if (potential_upvar_p(irep->lv, a, argc, irep->nlocals)) {
|
||||
uint16_t arg = search_variable(mrb, irep->lv[a - 1].name, bnest);
|
||||
if (arg != 0) {
|
||||
/* must replace */
|
||||
iseq[i] = insn = OP_SETUPVAR;
|
||||
iseq[i+1] = (mrb_code)b;
|
||||
iseq[i+2] = arg >> 8;
|
||||
iseq[i+3] = arg & 0xff;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_GETUPVAR:
|
||||
a = PEEK_B(iseq+i+1);
|
||||
b = PEEK_B(iseq+i+2);
|
||||
c = PEEK_B(iseq+i+3);
|
||||
{
|
||||
int lev = c+1;
|
||||
mrb_irep *tmp = search_irep(top, bnest, lev, irep);
|
||||
if (potential_upvar_p(tmp->lv, b, irep_argc(tmp), tmp->nlocals)) {
|
||||
uint16_t arg = search_variable(mrb, tmp->lv[b-1].name, bnest);
|
||||
if (arg != 0) {
|
||||
/* must replace */
|
||||
iseq[i] = OP_GETUPVAR;
|
||||
iseq[i+2] = arg >> 8;
|
||||
iseq[i+3] = arg & 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_SETUPVAR:
|
||||
a = PEEK_B(iseq+i+1);
|
||||
b = PEEK_B(iseq+i+2);
|
||||
c = PEEK_B(iseq+i+3);
|
||||
{
|
||||
int lev = c+1;
|
||||
mrb_irep *tmp = search_irep(top, bnest, lev, irep);
|
||||
if (potential_upvar_p(tmp->lv, b, irep_argc(tmp), tmp->nlocals)) {
|
||||
uint16_t arg = search_variable(mrb, tmp->lv[b-1].name, bnest);
|
||||
if (arg != 0) {
|
||||
/* must replace */
|
||||
iseq[i] = OP_SETUPVAR;
|
||||
iseq[i+1] = a;
|
||||
iseq[i+2] = arg >> 8;
|
||||
iseq[i+3] = arg & 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_EXT1:
|
||||
insn = PEEK_B(iseq+i+1);
|
||||
i += mrb_insn_size1[insn]+1;
|
||||
continue;
|
||||
case OP_EXT2:
|
||||
insn = PEEK_B(iseq+i+1);
|
||||
i += mrb_insn_size2[insn]+1;
|
||||
continue;
|
||||
case OP_EXT3:
|
||||
insn = PEEK_B(iseq+i+1);
|
||||
i += mrb_insn_size3[insn]+1;
|
||||
continue;
|
||||
}
|
||||
i+=mrb_insn_size[insn];
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -231,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.");
|
||||
@@ -243,7 +32,8 @@ create_proc_from_string(mrb_state *mrb, char *s, mrb_int len, mrb_value binding,
|
||||
mrbc_filename(mrb, cxt, file ? file : "(eval)");
|
||||
cxt->capture_errors = TRUE;
|
||||
cxt->no_optimize = TRUE;
|
||||
cxt->on_eval = TRUE;
|
||||
ci = (mrb->c->ci > mrb->c->cibase) ? mrb->c->ci - 1 : mrb->c->cibase;
|
||||
cxt->upper = ci->proc && MRB_PROC_CFUNC_P(ci->proc) ? NULL : ci->proc;
|
||||
|
||||
p = mrb_parse_nstring(mrb, s, len, cxt);
|
||||
|
||||
@@ -298,7 +88,7 @@ create_proc_from_string(mrb_state *mrb, char *s, mrb_int len, mrb_value binding,
|
||||
e->mid = ci->mid;
|
||||
e->stack = ci[1].stackent;
|
||||
e->cxt = mrb->c;
|
||||
MRB_ENV_SET_STACK_LEN(e, ci->proc->body.irep->nlocals);
|
||||
MRB_ENV_SET_LEN(e, ci->proc->body.irep->nlocals);
|
||||
bidx = ci->argc;
|
||||
if (ci->argc < 0) bidx = 2;
|
||||
else bidx += 1;
|
||||
@@ -311,7 +101,6 @@ create_proc_from_string(mrb_state *mrb, char *s, mrb_int len, mrb_value binding,
|
||||
}
|
||||
proc->upper = ci->proc;
|
||||
mrb->c->ci->target_class = target_class;
|
||||
patch_irep(mrb, proc->body.irep, 0, proc->body.irep);
|
||||
/* mrb_codedump_all(mrb, proc); */
|
||||
|
||||
mrb_parser_free(p);
|
||||
@@ -342,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;
|
||||
|
||||
@@ -365,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;
|
||||
@@ -390,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
|
||||
|
||||
@@ -130,3 +130,24 @@ Proc.new { foo }
|
||||
EOS
|
||||
}
|
||||
end
|
||||
|
||||
assert('Calling the same method as the variable name') do
|
||||
hoge = Object.new
|
||||
def hoge.fuga
|
||||
"Hit!"
|
||||
end
|
||||
assert_equal("Hit!") { fuga = "Miss!"; eval "hoge.fuga" }
|
||||
assert_equal("Hit!") { fuga = "Miss!"; -> { eval "hoge.fuga" }.call }
|
||||
assert_equal("Hit!") { -> { fuga = "Miss!"; eval "hoge.fuga" }.call }
|
||||
assert_equal("Hit!") { fuga = "Miss!"; eval("-> { hoge.fuga }").call }
|
||||
end
|
||||
|
||||
assert('Access numbered parameter from eval') do
|
||||
hoge = Object.new
|
||||
def hoge.fuga(a, &b)
|
||||
b.call(a)
|
||||
end
|
||||
assert_equal(6) {
|
||||
hoge.fuga(3) { _1 + eval("_1") }
|
||||
}
|
||||
end
|
||||
|
||||
@@ -291,8 +291,7 @@ mrb_fiber_alive_p(mrb_state *mrb, mrb_value self)
|
||||
static mrb_value
|
||||
fiber_eq(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value other;
|
||||
mrb_get_args(mrb, "o", &other);
|
||||
mrb_value other = mrb_get_arg1(mrb);
|
||||
|
||||
if (!mrb_fiber_p(other)) {
|
||||
return mrb_false_value();
|
||||
|
||||
@@ -8,13 +8,12 @@ istruct_test_initialize(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
char *string = (char*)mrb_istruct_ptr(self);
|
||||
mrb_int size = mrb_istruct_size();
|
||||
mrb_value object;
|
||||
mrb_get_args(mrb, "o", &object);
|
||||
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);
|
||||
}
|
||||
@@ -45,8 +44,8 @@ istruct_test_length(mrb_state *mrb, mrb_value self)
|
||||
static mrb_value
|
||||
istruct_test_test_receive(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value object;
|
||||
mrb_get_args(mrb, "o", &object);
|
||||
mrb_value object = mrb_get_arg1(mrb);
|
||||
|
||||
if (mrb_obj_class(mrb, object) != mrb_class_get(mrb, "InlineStructTest"))
|
||||
{
|
||||
mrb_raise(mrb, E_TYPE_ERROR, "Expected InlineStructTest");
|
||||
|
||||
@@ -18,7 +18,7 @@ extern "C" {
|
||||
#if defined(MRB_WITHOUT_IO_PREAD_PWRITE)
|
||||
# undef MRB_WITH_IO_PREAD_PWRITE
|
||||
#elif !defined(MRB_WITH_IO_PREAD_PWRITE)
|
||||
# if defined(__unix__)
|
||||
# if defined(__unix__) || defined(__MACH__)
|
||||
# define MRB_WITH_IO_PREAD_PWRITE
|
||||
# endif
|
||||
#endif
|
||||
@@ -50,8 +50,8 @@ struct mrb_io {
|
||||
#define MRB_O_SHARE_DELETE 0x1000
|
||||
#define MRB_O_TMPFILE 0x2000
|
||||
#define MRB_O_NOATIME 0x4000
|
||||
#define MRB_O_DSYNC 0x00008000 /* Ignored with MRB_INT16 and MRB_WITHOUT_FLOAT */
|
||||
#define MRB_O_RSYNC 0x00010000 /* Ignored with MRB_INT16 and MRB_WITHOUT_FLOAT */
|
||||
#define MRB_O_DSYNC 0x00008000
|
||||
#define MRB_O_RSYNC 0x00010000
|
||||
|
||||
#define MRB_O_RDONLY_P(f) ((mrb_bool)(((f) & MRB_O_ACCMODE) == MRB_O_RDONLY))
|
||||
#define MRB_O_WRONLY_P(f) ((mrb_bool)(((f) & MRB_O_ACCMODE) == MRB_O_WRONLY))
|
||||
|
||||
@@ -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
|
||||
|
||||
+50
-69
@@ -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
|
||||
@@ -89,7 +93,7 @@ flock(int fd, int operation) {
|
||||
}
|
||||
#endif
|
||||
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_file_s_umask(mrb_state *mrb, mrb_value klass)
|
||||
{
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
@@ -265,7 +269,7 @@ mrb_file_realpath(mrb_state *mrb, mrb_value klass)
|
||||
return result;
|
||||
}
|
||||
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_file__getwd(mrb_state *mrb, mrb_value klass)
|
||||
{
|
||||
mrb_value path;
|
||||
@@ -390,18 +394,15 @@ 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);
|
||||
}
|
||||
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_file_flock(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
#if defined(sun)
|
||||
@@ -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
|
||||
@@ -458,7 +459,7 @@ mrb_file_size(mrb_state *mrb, mrb_value self)
|
||||
}
|
||||
|
||||
static int
|
||||
mrb_ftruncate(int fd, int64_t length)
|
||||
mrb_ftruncate(int fd, mrb_int length)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
return ftruncate(fd, (off_t)length);
|
||||
@@ -491,32 +492,11 @@ static mrb_value
|
||||
mrb_file_truncate(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
int fd;
|
||||
int64_t length;
|
||||
mrb_value lenv;
|
||||
mrb_int length;
|
||||
mrb_value lenv = mrb_get_arg1(mrb);
|
||||
|
||||
fd = mrb_io_fileno(mrb, self);
|
||||
mrb_get_args(mrb, "o", &lenv);
|
||||
switch (mrb_type(lenv)) {
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
case MRB_TT_FLOAT:
|
||||
{
|
||||
mrb_float lenf = mrb_float(lenv);
|
||||
if (lenf > INT64_MAX) {
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "length too large");
|
||||
}
|
||||
length = (int64_t)lenf;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case MRB_TT_FIXNUM:
|
||||
default:
|
||||
{
|
||||
mrb_int leni = mrb_int(mrb, lenv);
|
||||
length = (int64_t)leni;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
length = mrb_int(mrb, lenv);
|
||||
if (mrb_ftruncate(fd, length) != 0) {
|
||||
mrb_raise(mrb, E_IO_ERROR, "ftruncate failed");
|
||||
}
|
||||
@@ -577,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;
|
||||
@@ -629,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?
|
||||
@@ -85,7 +87,7 @@ mrb_lstat(mrb_state *mrb, mrb_value obj, struct stat *st)
|
||||
* File.directory?(".")
|
||||
*/
|
||||
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_filetest_s_directory_p(mrb_state *mrb, mrb_value klass)
|
||||
{
|
||||
#ifndef S_ISDIR
|
||||
@@ -93,9 +95,7 @@ mrb_filetest_s_directory_p(mrb_state *mrb, mrb_value klass)
|
||||
#endif
|
||||
|
||||
struct stat st;
|
||||
mrb_value obj;
|
||||
|
||||
mrb_get_args(mrb, "o", &obj);
|
||||
mrb_value obj = mrb_get_arg1(mrb);
|
||||
|
||||
if (mrb_stat(mrb, obj, &st) < 0)
|
||||
return mrb_false_value();
|
||||
@@ -112,7 +112,7 @@ mrb_filetest_s_directory_p(mrb_state *mrb, mrb_value klass)
|
||||
* Returns <code>true</code> if the named file is a pipe.
|
||||
*/
|
||||
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_filetest_s_pipe_p(mrb_state *mrb, mrb_value klass)
|
||||
{
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
@@ -124,9 +124,7 @@ mrb_filetest_s_pipe_p(mrb_state *mrb, mrb_value klass)
|
||||
# endif
|
||||
|
||||
struct stat st;
|
||||
mrb_value obj;
|
||||
|
||||
mrb_get_args(mrb, "o", &obj);
|
||||
mrb_value obj = mrb_get_arg1(mrb);
|
||||
|
||||
if (mrb_stat(mrb, obj, &st) < 0)
|
||||
return mrb_false_value();
|
||||
@@ -145,7 +143,7 @@ mrb_filetest_s_pipe_p(mrb_state *mrb, mrb_value klass)
|
||||
* Returns <code>true</code> if the named file is a symbolic link.
|
||||
*/
|
||||
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_filetest_s_symlink_p(mrb_state *mrb, mrb_value klass)
|
||||
{
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
@@ -167,9 +165,7 @@ mrb_filetest_s_symlink_p(mrb_state *mrb, mrb_value klass)
|
||||
|
||||
#ifdef S_ISLNK
|
||||
struct stat st;
|
||||
mrb_value obj;
|
||||
|
||||
mrb_get_args(mrb, "o", &obj);
|
||||
mrb_value obj = mrb_get_arg1(mrb);
|
||||
|
||||
if (mrb_lstat(mrb, obj, &st) == -1)
|
||||
return mrb_false_value();
|
||||
@@ -188,7 +184,7 @@ mrb_filetest_s_symlink_p(mrb_state *mrb, mrb_value klass)
|
||||
* Returns <code>true</code> if the named file is a socket.
|
||||
*/
|
||||
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_filetest_s_socket_p(mrb_state *mrb, mrb_value klass)
|
||||
{
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
@@ -210,9 +206,7 @@ mrb_filetest_s_socket_p(mrb_state *mrb, mrb_value klass)
|
||||
|
||||
#ifdef S_ISSOCK
|
||||
struct stat st;
|
||||
mrb_value obj;
|
||||
|
||||
mrb_get_args(mrb, "o", &obj);
|
||||
mrb_value obj = mrb_get_arg1(mrb);
|
||||
|
||||
if (mrb_stat(mrb, obj, &st) < 0)
|
||||
return mrb_false_value();
|
||||
@@ -232,13 +226,12 @@ mrb_filetest_s_socket_p(mrb_state *mrb, mrb_value klass)
|
||||
* Return <code>true</code> if the named file exists.
|
||||
*/
|
||||
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_filetest_s_exist_p(mrb_state *mrb, mrb_value klass)
|
||||
{
|
||||
struct stat st;
|
||||
mrb_value obj;
|
||||
mrb_value obj = mrb_get_arg1(mrb);
|
||||
|
||||
mrb_get_args(mrb, "o", &obj);
|
||||
if (mrb_stat(mrb, obj, &st) < 0)
|
||||
return mrb_false_value();
|
||||
|
||||
@@ -253,7 +246,7 @@ mrb_filetest_s_exist_p(mrb_state *mrb, mrb_value klass)
|
||||
* regular file.
|
||||
*/
|
||||
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_filetest_s_file_p(mrb_state *mrb, mrb_value klass)
|
||||
{
|
||||
#ifndef S_ISREG
|
||||
@@ -261,9 +254,7 @@ mrb_filetest_s_file_p(mrb_state *mrb, mrb_value klass)
|
||||
#endif
|
||||
|
||||
struct stat st;
|
||||
mrb_value obj;
|
||||
|
||||
mrb_get_args(mrb, "o", &obj);
|
||||
mrb_value obj = mrb_get_arg1(mrb);
|
||||
|
||||
if (mrb_stat(mrb, obj, &st) < 0)
|
||||
return mrb_false_value();
|
||||
@@ -281,13 +272,11 @@ mrb_filetest_s_file_p(mrb_state *mrb, mrb_value klass)
|
||||
* a zero size.
|
||||
*/
|
||||
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_filetest_s_zero_p(mrb_state *mrb, mrb_value klass)
|
||||
{
|
||||
struct stat st;
|
||||
mrb_value obj;
|
||||
|
||||
mrb_get_args(mrb, "o", &obj);
|
||||
mrb_value obj = mrb_get_arg1(mrb);
|
||||
|
||||
if (mrb_stat(mrb, obj, &st) < 0)
|
||||
return mrb_false_value();
|
||||
@@ -306,18 +295,16 @@ mrb_filetest_s_zero_p(mrb_state *mrb, mrb_value klass)
|
||||
* _file_name_ can be an IO object.
|
||||
*/
|
||||
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_filetest_s_size(mrb_state *mrb, mrb_value klass)
|
||||
{
|
||||
struct stat st;
|
||||
mrb_value obj;
|
||||
|
||||
mrb_get_args(mrb, "o", &obj);
|
||||
mrb_value obj = mrb_get_arg1(mrb);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -328,20 +315,18 @@ mrb_filetest_s_size(mrb_state *mrb, mrb_value klass)
|
||||
* file otherwise.
|
||||
*/
|
||||
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_filetest_s_size_p(mrb_state *mrb, mrb_value klass)
|
||||
{
|
||||
struct stat st;
|
||||
mrb_value obj;
|
||||
|
||||
mrb_get_args(mrb, "o", &obj);
|
||||
mrb_value obj = mrb_get_arg1(mrb);
|
||||
|
||||
if (mrb_stat(mrb, obj, &st) < 0)
|
||||
return mrb_nil_value();
|
||||
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
|
||||
|
||||
+115
-74
@@ -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;
|
||||
@@ -341,13 +345,19 @@ option_to_fd(mrb_state *mrb, mrb_value hash, const char *key)
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
mrb_value
|
||||
static mrb_value
|
||||
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;
|
||||
@@ -439,20 +448,26 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
|
||||
return io;
|
||||
}
|
||||
#elif defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
|
||||
{
|
||||
mrb_raise(mrb, E_NOTIMP_ERROR, "IO#popen is not supported on the platform");
|
||||
return mrb_false_value();
|
||||
}
|
||||
#else
|
||||
mrb_value
|
||||
static mrb_value
|
||||
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) {
|
||||
@@ -596,16 +611,15 @@ mrb_dup(mrb_state *mrb, int fd, mrb_bool *failed)
|
||||
return new_fd;
|
||||
}
|
||||
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_io_initialize_copy(mrb_state *mrb, mrb_value copy)
|
||||
{
|
||||
mrb_value orig;
|
||||
mrb_value orig = mrb_get_arg1(mrb);
|
||||
mrb_value buf;
|
||||
struct mrb_io *fptr_copy;
|
||||
struct mrb_io *fptr_orig;
|
||||
mrb_bool failed = TRUE;
|
||||
|
||||
mrb_get_args(mrb, "o", &orig);
|
||||
fptr_orig = io_get_open_fptr(mrb, orig);
|
||||
fptr_copy = (struct mrb_io *)DATA_PTR(copy);
|
||||
if (fptr_orig == fptr_copy) return copy;
|
||||
@@ -645,7 +659,44 @@ mrb_io_initialize_copy(mrb_state *mrb, mrb_value copy)
|
||||
return copy;
|
||||
}
|
||||
|
||||
mrb_value
|
||||
static void
|
||||
check_file_descriptor(mrb_state *mrb, mrb_int fd)
|
||||
{
|
||||
struct stat sb;
|
||||
int fdi = (int)fd;
|
||||
|
||||
#if MRB_INT_MIN < INT_MIN || MRB_INT_MAX > INT_MAX
|
||||
if (fdi != fd) {
|
||||
goto badfd;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
{
|
||||
DWORD err;
|
||||
int len = sizeof(err);
|
||||
|
||||
if (getsockopt(fdi, SOL_SOCKET, SO_ERROR, (char*)&err, &len) == 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (fdi < 0 || fdi > _getmaxstdio()) {
|
||||
goto badfd;
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
if (fstat(fdi, &sb) != 0) {
|
||||
goto badfd;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
badfd:
|
||||
mrb_sys_fail(mrb, "bad file descriptor");
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
mrb_io_initialize(mrb_state *mrb, mrb_value io)
|
||||
{
|
||||
struct mrb_io *fptr;
|
||||
@@ -656,6 +707,7 @@ mrb_io_initialize(mrb_state *mrb, mrb_value io)
|
||||
mode = opt = mrb_nil_value();
|
||||
|
||||
mrb_get_args(mrb, "i|oo", &fd, &mode, &opt);
|
||||
check_file_descriptor(mrb, fd);
|
||||
if (mrb_nil_p(mode)) {
|
||||
mode = mrb_str_new_cstr(mrb, "r");
|
||||
}
|
||||
@@ -747,7 +799,7 @@ fptr_finalize(mrb_state *mrb, struct mrb_io *fptr, int quiet)
|
||||
}
|
||||
}
|
||||
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_io_check_readable(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
struct mrb_io *fptr = io_get_open_fptr(mrb, self);
|
||||
@@ -757,7 +809,7 @@ mrb_io_check_readable(mrb_state *mrb, mrb_value self)
|
||||
return mrb_nil_value();
|
||||
}
|
||||
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_io_isatty(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
struct mrb_io *fptr;
|
||||
@@ -768,7 +820,7 @@ mrb_io_isatty(mrb_state *mrb, mrb_value self)
|
||||
return mrb_true_value();
|
||||
}
|
||||
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_io_s_for_fd(mrb_state *mrb, mrb_value klass)
|
||||
{
|
||||
struct RClass *c = mrb_class_ptr(klass);
|
||||
@@ -781,7 +833,7 @@ mrb_io_s_for_fd(mrb_state *mrb, mrb_value klass)
|
||||
return mrb_io_initialize(mrb, obj);
|
||||
}
|
||||
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_io_s_sysclose(mrb_state *mrb, mrb_value klass)
|
||||
{
|
||||
mrb_int fd;
|
||||
@@ -792,7 +844,7 @@ mrb_io_s_sysclose(mrb_state *mrb, mrb_value klass)
|
||||
return mrb_fixnum_value(0);
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
mrb_cloexec_open(mrb_state *mrb, const char *pathname, mrb_int flags, mrb_int mode)
|
||||
{
|
||||
int fd, retry = FALSE;
|
||||
@@ -827,7 +879,7 @@ reopen:
|
||||
return fd;
|
||||
}
|
||||
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_io_s_sysopen(mrb_state *mrb, mrb_value klass)
|
||||
{
|
||||
mrb_value path = mrb_nil_value();
|
||||
@@ -857,7 +909,7 @@ mrb_sysread_dummy(int fd, void *buf, fsize_t nbytes, off_t offset)
|
||||
return (mrb_io_read_write_size)read(fd, buf, nbytes);
|
||||
}
|
||||
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_io_sysread(mrb_state *mrb, mrb_value io)
|
||||
{
|
||||
mrb_value buf = mrb_nil_value();
|
||||
@@ -911,7 +963,7 @@ mrb_io_sysread_common(mrb_state *mrb,
|
||||
return buf;
|
||||
}
|
||||
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_io_sysseek(mrb_state *mrb, mrb_value io)
|
||||
{
|
||||
struct mrb_io *fptr;
|
||||
@@ -929,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);
|
||||
@@ -971,7 +1023,7 @@ mrb_syswrite_dummy(int fd, const void *buf, fsize_t nbytes, off_t offset)
|
||||
return (mrb_io_read_write_size)write(fd, buf, nbytes);
|
||||
}
|
||||
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_io_syswrite(mrb_state *mrb, mrb_value io)
|
||||
{
|
||||
mrb_value buf;
|
||||
@@ -981,7 +1033,7 @@ mrb_io_syswrite(mrb_state *mrb, mrb_value io)
|
||||
return mrb_io_syswrite_common(mrb, mrb_syswrite_dummy, io, buf, 0);
|
||||
}
|
||||
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_io_close(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
struct mrb_io *fptr;
|
||||
@@ -990,7 +1042,7 @@ mrb_io_close(mrb_state *mrb, mrb_value self)
|
||||
return mrb_nil_value();
|
||||
}
|
||||
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_io_close_write(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
struct mrb_io *fptr;
|
||||
@@ -1001,7 +1053,7 @@ mrb_io_close_write(mrb_state *mrb, mrb_value self)
|
||||
return mrb_nil_value();
|
||||
}
|
||||
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_io_closed(mrb_state *mrb, mrb_value io)
|
||||
{
|
||||
struct mrb_io *fptr;
|
||||
@@ -1013,7 +1065,7 @@ mrb_io_closed(mrb_state *mrb, mrb_value io)
|
||||
return mrb_true_value();
|
||||
}
|
||||
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_io_pid(mrb_state *mrb, mrb_value io)
|
||||
{
|
||||
struct mrb_io *fptr;
|
||||
@@ -1032,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);
|
||||
@@ -1147,6 +1199,7 @@ mrb_io_s_select(mrb_state *mrb, mrb_value klass)
|
||||
for (i = 0; i < RARRAY_LEN(read); i++) {
|
||||
read_io = RARRAY_PTR(read)[i];
|
||||
fptr = io_get_open_fptr(mrb, read_io);
|
||||
if (fptr->fd >= FD_SETSIZE) continue;
|
||||
FD_SET(fptr->fd, rp);
|
||||
if (mrb_io_read_data_pending(mrb, read_io)) {
|
||||
pending++;
|
||||
@@ -1169,6 +1222,7 @@ mrb_io_s_select(mrb_state *mrb, mrb_value klass)
|
||||
FD_ZERO(wp);
|
||||
for (i = 0; i < RARRAY_LEN(write); i++) {
|
||||
fptr = io_get_open_fptr(mrb, RARRAY_PTR(write)[i]);
|
||||
if (fptr->fd >= FD_SETSIZE) continue;
|
||||
FD_SET(fptr->fd, wp);
|
||||
if (max < fptr->fd)
|
||||
max = fptr->fd;
|
||||
@@ -1188,6 +1242,7 @@ mrb_io_s_select(mrb_state *mrb, mrb_value klass)
|
||||
FD_ZERO(ep);
|
||||
for (i = 0; i < RARRAY_LEN(except); i++) {
|
||||
fptr = io_get_open_fptr(mrb, RARRAY_PTR(except)[i]);
|
||||
if (fptr->fd >= FD_SETSIZE) continue;
|
||||
FD_SET(fptr->fd, ep);
|
||||
if (max < fptr->fd)
|
||||
max = fptr->fd;
|
||||
@@ -1276,7 +1331,7 @@ mrb_io_fileno_m(mrb_state *mrb, mrb_value io)
|
||||
return mrb_fixnum_value(fd);
|
||||
}
|
||||
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_io_close_on_exec_p(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
#if defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC)
|
||||
@@ -1300,7 +1355,7 @@ mrb_io_close_on_exec_p(mrb_state *mrb, mrb_value self)
|
||||
#endif
|
||||
}
|
||||
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_io_set_close_on_exec(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
#if defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC)
|
||||
@@ -1336,7 +1391,7 @@ mrb_io_set_close_on_exec(mrb_state *mrb, mrb_value self)
|
||||
#endif
|
||||
}
|
||||
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_io_set_sync(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
struct mrb_io *fptr;
|
||||
@@ -1348,7 +1403,7 @@ mrb_io_set_sync(mrb_state *mrb, mrb_value self)
|
||||
return mrb_bool_value(b);
|
||||
}
|
||||
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_io_sync(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
struct mrb_io *fptr;
|
||||
@@ -1363,22 +1418,7 @@ mrb_io_sync(mrb_state *mrb, mrb_value self)
|
||||
static off_t
|
||||
value2off(mrb_state *mrb, mrb_value offv)
|
||||
{
|
||||
switch (mrb_type(offv)) {
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
case MRB_TT_FLOAT:
|
||||
{
|
||||
mrb_float tmp = mrb_float(offv);
|
||||
if (tmp < INT64_MIN || tmp > INT64_MAX) {
|
||||
/* fall through to use convert by `mrb_int()` (and raise error if out of range) */
|
||||
} else {
|
||||
return (off_t)tmp;
|
||||
}
|
||||
}
|
||||
/* fall through */
|
||||
#endif /* MRB_WITHOUT_FLOAT */
|
||||
default:
|
||||
return (off_t)mrb_int(mrb, offv);
|
||||
}
|
||||
return (off_t)mrb_int(mrb, offv);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1452,7 +1492,8 @@ mrb_io_readchar(mrb_state *mrb, mrb_value self)
|
||||
#endif
|
||||
|
||||
mrb_get_args(mrb, "S", &buf);
|
||||
mrb_assert(RSTRING_PTR(buf) > 0);
|
||||
mrb_assert(RSTRING_LEN(buf) > 0);
|
||||
mrb_assert(RSTRING_PTR(buf) != NULL);
|
||||
mrb_str_modify(mrb, RSTRING(buf));
|
||||
#ifdef MRB_UTF8_STRING
|
||||
c = RSTRING_PTR(buf)[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
|
||||
@@ -110,18 +112,22 @@ assert('File.join') do
|
||||
end
|
||||
|
||||
assert('File.realpath') do
|
||||
if File::ALT_SEPARATOR
|
||||
readme_path = File._getwd + File::ALT_SEPARATOR + "README.md"
|
||||
assert_equal readme_path, File.realpath("README.md")
|
||||
else
|
||||
dir = MRubyIOTestUtil.mkdtemp("mruby-io-test.XXXXXX")
|
||||
begin
|
||||
dir1 = File.realpath($mrbtest_io_rfname)
|
||||
dir2 = File.realpath("./#{dir}//./../#{$mrbtest_io_symlinkname}")
|
||||
assert_equal dir1, dir2
|
||||
ensure
|
||||
MRubyIOTestUtil.rmdir dir
|
||||
dir = MRubyIOTestUtil.mkdtemp("mruby-io-test.XXXXXX")
|
||||
begin
|
||||
sep = File::ALT_SEPARATOR || File::SEPARATOR
|
||||
relative_path = "#{File.basename(dir)}#{sep}realpath_test"
|
||||
path = "#{File._getwd}#{sep}#{relative_path}"
|
||||
File.open(path, "w"){}
|
||||
assert_equal path, File.realpath(relative_path)
|
||||
|
||||
unless MRubyIOTestUtil.win?
|
||||
path1 = File.realpath($mrbtest_io_rfname)
|
||||
path2 = File.realpath($mrbtest_io_symlinkname)
|
||||
assert_equal path1, path2
|
||||
end
|
||||
ensure
|
||||
File.delete path rescue nil
|
||||
MRubyIOTestUtil.rmdir dir
|
||||
end
|
||||
|
||||
assert_raise(ArgumentError) { File.realpath("TO\0DO") }
|
||||
@@ -129,7 +135,9 @@ end
|
||||
|
||||
assert("File.readlink") do
|
||||
begin
|
||||
assert_equal $mrbtest_io_rfname, File.readlink($mrbtest_io_symlinkname)
|
||||
exp = File.basename($mrbtest_io_rfname)
|
||||
act = File.readlink($mrbtest_io_symlinkname)
|
||||
assert_equal exp, act
|
||||
rescue NotImplementedError => e
|
||||
skip e.message
|
||||
end
|
||||
|
||||
@@ -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
|
||||
@@ -24,6 +24,9 @@ def assert_io_open(meth)
|
||||
end
|
||||
end
|
||||
io2.close unless meth == :open
|
||||
|
||||
assert_raise(RuntimeError) { IO.__send__(meth, 1023) } # For Windows
|
||||
assert_raise(RuntimeError) { IO.__send__(meth, 1 << 26) }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -429,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
|
||||
|
||||
@@ -54,6 +54,7 @@ mkdtemp(char *temp)
|
||||
#include <unistd.h>
|
||||
#include <sys/un.h>
|
||||
#include <fcntl.h>
|
||||
#include <libgen.h>
|
||||
#endif
|
||||
|
||||
#include <sys/stat.h>
|
||||
@@ -66,88 +67,53 @@ mkdtemp(char *temp)
|
||||
#include "mruby/variable.h"
|
||||
#include <mruby/ext/io.h>
|
||||
|
||||
int wd_save;
|
||||
int socket_available_p;
|
||||
|
||||
#if !defined(_WIN32) && !defined(_WIN64)
|
||||
static int mrb_io_socket_available()
|
||||
{
|
||||
int fd, retval = 0;
|
||||
struct sockaddr_un sun0;
|
||||
char socketname[] = "tmp.mruby-io-socket-ok.XXXXXXXX";
|
||||
if (!(fd = mkstemp(socketname))) {
|
||||
goto sock_test_out;
|
||||
}
|
||||
unlink(socketname);
|
||||
close(fd);
|
||||
fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (fd == -1) {
|
||||
goto sock_test_out;
|
||||
}
|
||||
sun0.sun_family = AF_UNIX;
|
||||
strncpy(sun0.sun_path, socketname, sizeof(sun0.sun_path));
|
||||
if (bind(fd, (struct sockaddr *)&sun0, sizeof(sun0)) == 0) {
|
||||
retval = 1;
|
||||
}
|
||||
sock_test_out:
|
||||
unlink(socketname);
|
||||
close(fd);
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
|
||||
static mrb_value
|
||||
mrb_io_test_io_setup(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
char rfname[] = "tmp.mruby-io-test-r.XXXXXXXX";
|
||||
char wfname[] = "tmp.mruby-io-test-w.XXXXXXXX";
|
||||
char symlinkname[] = "tmp.mruby-io-test-l.XXXXXXXX";
|
||||
char socketname[] = "tmp.mruby-io-test-s.XXXXXXXX";
|
||||
#define GVNAME(n) "$mrbtest_io_" #n "name"
|
||||
enum {IDX_READ, IDX_WRITE, IDX_LINK, IDX_SOCKET, IDX_COUNT};
|
||||
const char *gvnames[] = {GVNAME(rf), GVNAME(wf), GVNAME(symlink), GVNAME(socket)};
|
||||
char *fnames[IDX_COUNT];
|
||||
int fds[IDX_COUNT];
|
||||
char msg[] = "mruby io test\n";
|
||||
mode_t mask;
|
||||
int fd0, fd1;
|
||||
FILE *fp;
|
||||
|
||||
int i;
|
||||
#if !defined(_WIN32) && !defined(_WIN64)
|
||||
int fd2, fd3;
|
||||
struct sockaddr_un sun0;
|
||||
|
||||
if(!(socket_available_p = mrb_io_socket_available())) {
|
||||
char *tmpdir;
|
||||
wd_save = open(".", O_DIRECTORY);
|
||||
tmpdir = getenv("TMPDIR");
|
||||
if (tmpdir) chdir(tmpdir);
|
||||
else chdir("/tmp");
|
||||
}
|
||||
#endif
|
||||
|
||||
mask = umask(077);
|
||||
fd0 = mkstemp(rfname);
|
||||
fd1 = mkstemp(wfname);
|
||||
if (fd0 == -1 || fd1 == -1) {
|
||||
mrb_raise(mrb, E_RUNTIME_ERROR, "can't create temporary file");
|
||||
return mrb_nil_value();
|
||||
}
|
||||
close(fd0);
|
||||
close(fd1);
|
||||
|
||||
#if !defined(_WIN32) && !defined(_WIN64)
|
||||
fd2 = mkstemp(symlinkname);
|
||||
fd3 = mkstemp(socketname);
|
||||
if (fd2 == -1 || fd3 == -1) {
|
||||
mrb_raise(mrb, E_RUNTIME_ERROR, "can't create temporary file");
|
||||
return mrb_nil_value();
|
||||
}
|
||||
#endif
|
||||
umask(mask);
|
||||
|
||||
mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_rfname"), mrb_str_new_cstr(mrb, rfname));
|
||||
mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_wfname"), mrb_str_new_cstr(mrb, wfname));
|
||||
mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_symlinkname"), mrb_str_new_cstr(mrb, symlinkname));
|
||||
mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_socketname"), mrb_str_new_cstr(mrb, socketname));
|
||||
mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_msg"), mrb_str_new_cstr(mrb, msg));
|
||||
|
||||
fp = fopen(rfname, "wb");
|
||||
mask = umask(077);
|
||||
for (i = 0; i < IDX_COUNT; i++) {
|
||||
mrb_value fname = mrb_str_new_capa(mrb, 0);
|
||||
#if !defined(_WIN32) && !defined(_WIN64)
|
||||
/*
|
||||
* Workaround for not being able to bind a socket to some file systems
|
||||
* (e.g. vboxsf, NFS). [#4981]
|
||||
*/
|
||||
char *tmpdir = getenv("TMPDIR");
|
||||
if (tmpdir && strlen(tmpdir) > 0) {
|
||||
mrb_str_cat_cstr(mrb, fname, tmpdir);
|
||||
if (*(RSTRING_END(fname)-1) != '/') mrb_str_cat_lit(mrb, fname, "/");
|
||||
} else {
|
||||
mrb_str_cat_lit(mrb, fname, "/tmp/");
|
||||
}
|
||||
#endif
|
||||
mrb_str_cat_cstr(mrb, fname, gvnames[i]+1);
|
||||
mrb_str_cat_cstr(mrb, fname, ".XXXXXXXX");
|
||||
fnames[i] = RSTRING_PTR(fname);
|
||||
fds[i] = mkstemp(fnames[i]);
|
||||
if (fds[i] == -1) {
|
||||
mrb_raise(mrb, E_RUNTIME_ERROR, "can't create temporary file");
|
||||
}
|
||||
close(fds[i]);
|
||||
mrb_gv_set(mrb, mrb_intern_cstr(mrb, gvnames[i]), fname);
|
||||
}
|
||||
umask(mask);
|
||||
|
||||
fp = fopen(fnames[IDX_READ], "wb");
|
||||
if (fp == NULL) {
|
||||
mrb_raise(mrb, E_RUNTIME_ERROR, "can't open temporary file");
|
||||
return mrb_nil_value();
|
||||
@@ -155,7 +121,7 @@ mrb_io_test_io_setup(mrb_state *mrb, mrb_value self)
|
||||
fputs(msg, fp);
|
||||
fclose(fp);
|
||||
|
||||
fp = fopen(wfname, "wb");
|
||||
fp = fopen(fnames[IDX_WRITE], "wb");
|
||||
if (fp == NULL) {
|
||||
mrb_raise(mrb, E_RUNTIME_ERROR, "can't open temporary file");
|
||||
return mrb_nil_value();
|
||||
@@ -163,29 +129,29 @@ mrb_io_test_io_setup(mrb_state *mrb, mrb_value self)
|
||||
fclose(fp);
|
||||
|
||||
#if !defined(_WIN32) && !defined(_WIN64)
|
||||
unlink(symlinkname);
|
||||
close(fd2);
|
||||
if (symlink(rfname, symlinkname) == -1) {
|
||||
unlink(fnames[IDX_LINK]);
|
||||
if (symlink(basename(fnames[IDX_READ]), fnames[IDX_LINK]) == -1) {
|
||||
mrb_raise(mrb, E_RUNTIME_ERROR, "can't make a symbolic link");
|
||||
}
|
||||
|
||||
unlink(socketname);
|
||||
close(fd3);
|
||||
fd3 = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (fd3 == -1) {
|
||||
unlink(fnames[IDX_SOCKET]);
|
||||
fds[IDX_SOCKET] = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (fds[IDX_SOCKET] == -1) {
|
||||
mrb_raise(mrb, E_RUNTIME_ERROR, "can't make a socket");
|
||||
}
|
||||
sun0.sun_family = AF_UNIX;
|
||||
strncpy(sun0.sun_path, socketname, sizeof(sun0.sun_path));
|
||||
if (bind(fd3, (struct sockaddr *)&sun0, sizeof(sun0)) == -1) {
|
||||
strncpy(sun0.sun_path, fnames[IDX_SOCKET], sizeof(sun0.sun_path)-1);
|
||||
sun0.sun_path[sizeof(sun0.sun_path)-1] = 0;
|
||||
if (bind(fds[IDX_SOCKET], (struct sockaddr *)&sun0, sizeof(sun0)) == -1) {
|
||||
mrb_raisef(mrb, E_RUNTIME_ERROR, "can't bind AF_UNIX socket to %s: %d",
|
||||
sun0.sun_path,
|
||||
errno);
|
||||
}
|
||||
close(fd3);
|
||||
close(fds[IDX_SOCKET]);
|
||||
#endif
|
||||
|
||||
return mrb_true_value();
|
||||
#undef GVNAME
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
@@ -215,13 +181,6 @@ mrb_io_test_io_cleanup(mrb_state *mrb, mrb_value self)
|
||||
mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_socketname"), mrb_nil_value());
|
||||
mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_msg"), mrb_nil_value());
|
||||
|
||||
#if !defined(_WIN32) && !defined(_WIN64)
|
||||
if(!socket_available_p) {
|
||||
fchdir(wd_save);
|
||||
close(wd_save);
|
||||
}
|
||||
#endif
|
||||
|
||||
return mrb_nil_value();
|
||||
}
|
||||
|
||||
@@ -251,7 +210,7 @@ mrb_io_test_rmdir(mrb_state *mrb, mrb_value klass)
|
||||
return mrb_true_value();
|
||||
}
|
||||
|
||||
mrb_value
|
||||
static mrb_value
|
||||
mrb_io_win_p(mrb_state *mrb, mrb_value klass)
|
||||
{
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
||||
@@ -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
|
||||
@@ -128,9 +128,8 @@ mrb_f_integer(mrb_state *mrb, mrb_value self)
|
||||
static mrb_value
|
||||
mrb_f_float(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value arg;
|
||||
mrb_value arg = mrb_get_arg1(mrb);
|
||||
|
||||
mrb_get_args(mrb, "o", &arg);
|
||||
return mrb_Float(mrb, arg);
|
||||
}
|
||||
#endif
|
||||
@@ -149,10 +148,10 @@ mrb_f_float(mrb_state *mrb, mrb_value self)
|
||||
static mrb_value
|
||||
mrb_f_string(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value arg, tmp;
|
||||
mrb_value arg = mrb_get_arg1(mrb);
|
||||
mrb_value tmp;
|
||||
|
||||
mrb_get_args(mrb, "o", &arg);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -168,10 +167,10 @@ mrb_f_string(mrb_state *mrb, mrb_value self)
|
||||
static mrb_value
|
||||
mrb_f_array(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value arg, tmp;
|
||||
mrb_value arg = mrb_get_arg1(mrb);
|
||||
mrb_value tmp;
|
||||
|
||||
mrb_get_args(mrb, "o", &arg);
|
||||
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);
|
||||
}
|
||||
@@ -196,9 +195,8 @@ mrb_f_array(mrb_state *mrb, mrb_value self)
|
||||
static mrb_value
|
||||
mrb_f_hash(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value arg;
|
||||
mrb_value arg = mrb_get_arg1(mrb);
|
||||
|
||||
mrb_get_args(mrb, "o", &arg);
|
||||
if (mrb_nil_p(arg) || (mrb_array_p(arg) && RARRAY_LEN(arg) == 0)) {
|
||||
return mrb_hash_new(mrb);
|
||||
}
|
||||
@@ -214,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;
|
||||
|
||||
@@ -146,52 +146,72 @@ mrb_local_variables(mrb_state *mrb, mrb_value self)
|
||||
while (proc) {
|
||||
if (MRB_PROC_CFUNC_P(proc)) break;
|
||||
irep = proc->body.irep;
|
||||
if (!irep->lv) break;
|
||||
for (i = 0; i + 1 < irep->nlocals; ++i) {
|
||||
if (irep->lv[i].name) {
|
||||
mrb_sym sym = irep->lv[i].name;
|
||||
const char *name = mrb_sym_name(mrb, sym);
|
||||
switch (name[0]) {
|
||||
case '*': case '&':
|
||||
break;
|
||||
default:
|
||||
mrb_hash_set(mrb, vars, mrb_symbol_value(sym), mrb_true_value());
|
||||
break;
|
||||
if (irep->lv) {
|
||||
for (i = 0; i + 1 < irep->nlocals; ++i) {
|
||||
if (irep->lv[i]) {
|
||||
mrb_sym sym = irep->lv[i];
|
||||
const char *name = mrb_sym_name(mrb, sym);
|
||||
switch (name[0]) {
|
||||
case '*': case '&':
|
||||
break;
|
||||
default:
|
||||
mrb_hash_set(mrb, vars, mrb_symbol_value(sym), mrb_true_value());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!MRB_PROC_ENV_P(proc)) break;
|
||||
if (MRB_PROC_SCOPE_P(proc)) break;
|
||||
proc = proc->upper;
|
||||
//if (MRB_PROC_SCOPE_P(proc)) break;
|
||||
if (!proc->c) break;
|
||||
}
|
||||
|
||||
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
|
||||
@@ -609,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:
|
||||
@@ -645,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;
|
||||
@@ -665,14 +665,13 @@ 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;
|
||||
|
||||
ary = mrb_ary_new(mrb);
|
||||
proc = mrb->c->ci[-1].proc; /* callee proc */
|
||||
mrb_assert(!MRB_PROC_CFUNC_P(proc));
|
||||
while (proc) {
|
||||
while (proc && !MRB_PROC_CFUNC_P(proc)) {
|
||||
if (MRB_PROC_SCOPE_P(proc)) {
|
||||
struct RClass *c2 = MRB_PROC_TARGET_CLASS(proc);
|
||||
|
||||
@@ -686,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)
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user