mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Merge master branch.
This commit is contained in:
@@ -4,9 +4,6 @@
|
||||
# MD001 heading-increment/header-increment - Heading levels should only increment by one level at a time
|
||||
MD001: false
|
||||
|
||||
# MD010 no-hard-tabs - Hard tabs
|
||||
MD010: false
|
||||
|
||||
# MD013 line-length - Line length
|
||||
MD013: false
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ jobs:
|
||||
MRUBY_CONFIG: ci/gcc-clang
|
||||
CC: gcc
|
||||
steps:
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- uses: actions/checkout@v3
|
||||
- name: Ruby version
|
||||
run: ruby -v
|
||||
- name: Compiler version
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
MRUBY_CONFIG: ci/gcc-clang
|
||||
CC: clang
|
||||
steps:
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- uses: actions/checkout@v3
|
||||
- name: Ruby version
|
||||
run: ruby -v
|
||||
- name: Compiler version
|
||||
@@ -40,7 +40,7 @@ jobs:
|
||||
MRUBY_CONFIG: ci/gcc-clang
|
||||
CC: gcc
|
||||
steps:
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- uses: actions/checkout@v3
|
||||
- name: Ruby version
|
||||
run: ruby -v
|
||||
- name: Compiler version
|
||||
@@ -55,7 +55,7 @@ jobs:
|
||||
MRUBY_CONFIG: ci/gcc-clang
|
||||
CC: clang
|
||||
steps:
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- uses: actions/checkout@v3
|
||||
- name: Ruby version
|
||||
run: ruby -v
|
||||
- name: Compiler version
|
||||
@@ -70,7 +70,7 @@ jobs:
|
||||
MRUBY_CONFIG: ci/gcc-clang
|
||||
CC: clang
|
||||
steps:
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- uses: actions/checkout@v3
|
||||
- name: Ruby version
|
||||
run: ruby -v
|
||||
- name: Compiler version
|
||||
@@ -85,7 +85,7 @@ jobs:
|
||||
MRUBY_CONFIG: ci/gcc-clang
|
||||
CC: gcc
|
||||
steps:
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- uses: actions/checkout@v3
|
||||
- name: Ruby version
|
||||
run: ruby -v
|
||||
- name: Compiler version
|
||||
@@ -93,63 +93,17 @@ jobs:
|
||||
- name: Build and test
|
||||
run: rake -m test:build && rake test:run
|
||||
|
||||
Windows-Cygwin:
|
||||
runs-on: windows-latest
|
||||
timeout-minutes: 15
|
||||
env:
|
||||
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
|
||||
MRUBY_CONFIG: ci/gcc-clang
|
||||
CC: gcc
|
||||
installer-path: '%TMP%\cygwin-setup.exe'
|
||||
cygwin-root: C:\cygwin
|
||||
package-dir: C:\cygwin-package
|
||||
cache-version: v1
|
||||
steps:
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- uses: actions/cache@v2.1.7
|
||||
with:
|
||||
path: ${{ env.package-dir }}
|
||||
key: ${{ runner.os }}-cygwin-${{ env.cache-version }}
|
||||
- name: Download Cygwin installer
|
||||
shell: cmd
|
||||
run: >
|
||||
bitsadmin /transfer download /priority foreground
|
||||
https://cygwin.com/setup-x86_64.exe ${{ env.installer-path }}
|
||||
- name: Install Cygwin
|
||||
shell: cmd
|
||||
run: >
|
||||
${{ env.installer-path }}
|
||||
--quiet-mode --no-shortcuts --no-startmenu --no-desktop --no-admin
|
||||
--only-site --site http://mirrors.kernel.org/sourceware/cygwin/
|
||||
--root ${{ env.cygwin-root }}
|
||||
--local-package-dir ${{ env.package-dir }}
|
||||
--packages gcc-core,gcc-g++,ruby
|
||||
- name: Set PATH for Cygwin
|
||||
run: |
|
||||
echo '::set-env name=PATH::${{ env.cygwin-root }}\bin;${{ env.cygwin-root }}\usr\bin'
|
||||
- name: Ruby version
|
||||
shell: cmd
|
||||
run: ruby -v
|
||||
- name: Compiler version
|
||||
run: ${{ env.CC }} --version
|
||||
- name: Build and test
|
||||
shell: cmd
|
||||
run: ruby /usr/bin/rake -m test:build && ruby /usr/bin/rake test:run
|
||||
- name: Set PATH for cache archiving (tar)
|
||||
# set Windows path so that Cygwin tar is not used for cache archiving
|
||||
run: echo '::set-env name=PATH::C:\windows\System32'
|
||||
|
||||
Windows-VC:
|
||||
runs-on: windows-latest
|
||||
runs-on: windows-2022
|
||||
timeout-minutes: 10
|
||||
env:
|
||||
MRUBY_CONFIG: ci/msvc
|
||||
steps:
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- uses: actions/checkout@v3
|
||||
- name: Ruby version
|
||||
run: ruby -v
|
||||
- name: Build and test
|
||||
shell: cmd
|
||||
run: |
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
|
||||
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
|
||||
rake -m test:build && rake test:run
|
||||
|
||||
@@ -2,6 +2,7 @@ name: "Code scanning - action"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches-ignore: "dependabot/**"
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: '0 19 * * 4'
|
||||
@@ -13,7 +14,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2.4.0
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
# We must fetch at least the immediate parents so that if this is
|
||||
# a pull request then we can checkout the head.
|
||||
@@ -21,7 +22,7 @@ jobs:
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
uses: github/codeql-action/init@v2
|
||||
# Override language selection by uncommenting this and choosing your languages
|
||||
# with:
|
||||
# languages: go, javascript, csharp, python, cpp, java
|
||||
@@ -29,7 +30,7 @@ jobs:
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
@@ -43,4 +44,4 @@ jobs:
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
||||
uses: github/codeql-action/analyze@v2
|
||||
|
||||
@@ -8,23 +8,24 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check Out
|
||||
uses: actions/checkout@v2.4.0
|
||||
uses: actions/checkout@v3
|
||||
- name: Install
|
||||
run: wget -O - -q https://git.io/misspell | sh -s -- -b .
|
||||
- name: Misspell
|
||||
- name: Run misspell
|
||||
run: git ls-files --empty-directory | xargs ./misspell -error
|
||||
pre-commit:
|
||||
name: Run pre-commit
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- name: Check merge conflict
|
||||
- name: Check Out
|
||||
uses: actions/checkout@v3
|
||||
- name: Install
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install pre-commit
|
||||
- name: Set PY
|
||||
run: echo "PY=$(python -VV | sha256sum | cut -d' ' -f1)" >> $GITHUB_ENV
|
||||
- uses: actions/cache@v2.1.7
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.cache/pre-commit
|
||||
key: pre-commit|${{ env.PY }}|${{ hashFiles('.pre-commit-config.yaml') }}
|
||||
|
||||
@@ -16,7 +16,7 @@ jobs:
|
||||
fuzz-seconds: 600
|
||||
dry-run: false
|
||||
- name: Upload Crash
|
||||
uses: actions/upload-artifact@v2.3.1
|
||||
uses: actions/upload-artifact@v3
|
||||
if: failure()
|
||||
with:
|
||||
name: artifacts
|
||||
|
||||
@@ -1,19 +1,14 @@
|
||||
name: Super Linter
|
||||
|
||||
on:
|
||||
push:
|
||||
branches-ignore: [master]
|
||||
# Remove the line above to run when pushing to master
|
||||
pull_request:
|
||||
branches: [master]
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Lint Code Base
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- uses: github/super-linter@v4.8.5
|
||||
- uses: actions/checkout@v3
|
||||
- uses: github/super-linter@v4.9.2
|
||||
env:
|
||||
ERROR_ON_MISSING_EXEC_BIT: true
|
||||
VALIDATE_BASH: true
|
||||
|
||||
@@ -3,14 +3,14 @@ default_stages: [commit, push]
|
||||
default_language_version:
|
||||
# force all unspecified Python hooks to run python3
|
||||
python: python3
|
||||
minimum_pre_commit_version: "1.20.0"
|
||||
minimum_pre_commit_version: '2.18.1'
|
||||
repos:
|
||||
- repo: meta
|
||||
hooks:
|
||||
- id: identity
|
||||
- id: check-hooks-apply
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.1.0
|
||||
rev: v4.2.0
|
||||
hooks:
|
||||
- id: check-added-large-files
|
||||
- id: check-case-conflict
|
||||
@@ -39,7 +39,7 @@ repos:
|
||||
description: Check spelling with codespell
|
||||
entry: codespell --ignore-words=codespell.txt
|
||||
- repo: https://github.com/igorshubovych/markdownlint-cli
|
||||
rev: v0.30.0
|
||||
rev: v0.31.1
|
||||
hooks:
|
||||
- id: markdownlint
|
||||
name: Run markdownlint
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
# Authors of mruby (mruby developers)
|
||||
|
||||
## The List of Contributors sorted by number of commits (as of 2022-01-10 69b1667)
|
||||
## The List of Contributors sorted by number of commits (as of 2022-04-28 32fb8b1)
|
||||
|
||||
7956 Yukihiro "Matz" Matsumoto (@matz)*
|
||||
8214 Yukihiro "Matz" Matsumoto (@matz)*
|
||||
586 KOBAYASHI Shuji (@shuujii)
|
||||
376 Daniel Bovensiepen (@bovi)
|
||||
372 dearblue (@dearblue)*
|
||||
346 Takeshi Watanabe (@take-cheeze)*
|
||||
342 dearblue (@dearblue)*
|
||||
334 Masaki Muranaka (@monaka)
|
||||
298 Tomoyuki Sahara (@tsahara)*
|
||||
308 Tomoyuki Sahara (@tsahara)*
|
||||
234 Jun Hiroe (@suzukaze)
|
||||
219 Cremno (@cremno)*
|
||||
220 Cremno (@cremno)*
|
||||
208 Yuki Kurihara (@ksss)+
|
||||
148 Yasuhiro Matsumoto (@mattn)*
|
||||
113 Carson McDonald (@carsonmcdonald)
|
||||
@@ -20,12 +20,12 @@
|
||||
74 Yuichiro MASUI (@masuidrive)
|
||||
71 Tatsuhiko Kubo (@cubicdaiya)*
|
||||
68 Hiroshi Mimaki (@mimaki)*
|
||||
63 Akira Yumiyama (@akiray03)*
|
||||
67 Akira Yumiyama (@akiray03)*
|
||||
62 Paolo Bosetti (@pbosetti)*
|
||||
60 John Bampton (@jbampton)
|
||||
59 Kurebayashi, Takahiro (@crimsonwoods)*
|
||||
56 h2so5 (@h2so5)
|
||||
52 Ralph Desir (@Mav7)*
|
||||
49 John Bampton (@jbampton)
|
||||
45 Rory O'Connell (@RoryO)*
|
||||
43 Yuichiro Kaneko (@yui-knk)+
|
||||
42 fleuria (@flaneur2020)
|
||||
@@ -66,10 +66,10 @@
|
||||
12 Ukrainskiy Sergey (@ukrainskiysergey)
|
||||
12 Xuejie "Rafael" Xiao (@xxuejie)*
|
||||
11 Julien Ammous (@schmurfy)
|
||||
11 Kazuho Oku (@kazuho)
|
||||
11 Seeker (@SeekingMeaning)
|
||||
11 YAMAMOTO Masaya (pandax381)
|
||||
11 takkaw (@takkaw)
|
||||
10 Kazuho Oku (@kazuho)
|
||||
10 Miura Hideki (@miura1729)
|
||||
10 Narihiro Nakamura (@authorNari)
|
||||
10 Ray Chason (@chasonr)*
|
||||
@@ -107,6 +107,7 @@
|
||||
5 Yurie Yamane (@yurie)+
|
||||
5 dreamedge (@dreamedge)
|
||||
5 nkshigeru (@nkshigeru)
|
||||
4 Chris Reuter (@suetanvil)
|
||||
4 Dante Catalfamo (@dantecatalfamo)
|
||||
4 Goro Kikuchi (@gorogit)
|
||||
4 Herwin Weststrate (@herwinw)
|
||||
@@ -128,6 +129,7 @@
|
||||
3 Carlo Prelz (@asfluido)*
|
||||
3 David Turnbull (@AE9RB)
|
||||
3 Franck Verrot (@franckverrot)
|
||||
3 HASUMI Hitoshi (@hasumikin)
|
||||
3 Horimoto Yasuhiro (@komainu8)
|
||||
3 J. Mutua (@katmutua)+
|
||||
3 Jan Berdajs (@mrbrdo)
|
||||
@@ -158,7 +160,6 @@
|
||||
2 Francois Chagnon (@EiNSTeiN-)*
|
||||
2 Gilad Zohari (@gzohari)
|
||||
2 Go Saito (@govm)
|
||||
2 HASUMI Hitoshi (@hasumikin)
|
||||
2 Hirohito Higashi (@HirohitoHigashi)
|
||||
2 Hiroyuki Iwatsuki (@iwadon)
|
||||
2 Huei-Horng Yo (@hiroshiyui)
|
||||
@@ -196,7 +197,6 @@
|
||||
1 Atsushi Morimoto (@mynz)
|
||||
1 Ben A Morgan (@BenMorganIO)
|
||||
1 Benoit Daloze (@eregon)
|
||||
1 Chris Reuter (@suetanvil)
|
||||
1 Daehyub Kim (@lateau)
|
||||
1 Daniel Varga (@vargad)
|
||||
1 Edgar Boda-Majer (@eboda)
|
||||
@@ -225,6 +225,7 @@
|
||||
1 Kazuhiro NISHIYAMA (@znz)
|
||||
1 Kei Sawada (@remore)
|
||||
1 Kim H Madsen (@kimhmadsen)
|
||||
1 Koichi ITO (@koic)
|
||||
1 Konstantin Haase (@rkh)
|
||||
1 Leo Neat (@Leo-Neat)
|
||||
1 Lian Cheng (@liancheng)
|
||||
|
||||
+3
-1
@@ -15,4 +15,6 @@ We *don't* consider following issues as vulnerabilities:
|
||||
|
||||
* Runtime C undefined behavior (including integer overflow)
|
||||
* Crash caused by misused API
|
||||
* Crash caused by tweaked compiled binary
|
||||
* Crash caused by modified compiled binary
|
||||
* ASAN/Valgrind warning for too big memory allocation
|
||||
mruby assumes `malloc(3)` returns `NULL` for too big allocations
|
||||
|
||||
@@ -5,7 +5,7 @@ ints = [64, 32]
|
||||
boxings.product(bits, ints) do |boxing, bit, int|
|
||||
MRuby::Build.new("boxing-#{boxing}-m#{bit}-i#{int}") do |conf|
|
||||
conf.toolchain :gcc
|
||||
conf.gembox 'default'
|
||||
conf.gembox 'full-core'
|
||||
conf.compilers.each do |c|
|
||||
c.defines << "MRB_#{boxing.upcase}_BOXING"
|
||||
c.defines << "MRB_INT#{int}"
|
||||
|
||||
@@ -3,7 +3,7 @@ MRuby::Build.new do |conf|
|
||||
toolchain :gcc
|
||||
|
||||
# include the GEM box
|
||||
conf.gembox 'default'
|
||||
conf.gembox 'full-core'
|
||||
|
||||
conf.cc.defines << 'MRB_USE_FLOAT32'
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ MRuby::Build.new do |conf|
|
||||
toolchain :gcc
|
||||
|
||||
# include the GEM box
|
||||
conf.gembox 'default'
|
||||
conf.gembox 'full-core'
|
||||
|
||||
conf.cc.flags << '-pg'
|
||||
conf.linker.flags << '-pg'
|
||||
|
||||
@@ -3,7 +3,7 @@ MRuby::Build.new do |conf|
|
||||
toolchain :gcc
|
||||
|
||||
# include the GEM box
|
||||
conf.gembox 'default'
|
||||
conf.gembox 'full-core'
|
||||
|
||||
conf.cc.flags << '-m32'
|
||||
conf.linker.flags << '-m32'
|
||||
|
||||
@@ -14,7 +14,7 @@ GC (garbage collector) must ensure that object is "alive", in other
|
||||
words, that it is referenced by somewhere from the program. This can be
|
||||
determined by checking if the object can be directly or indirectly
|
||||
referenced by root. The local variables, global variables and
|
||||
constants etc are root.
|
||||
constants etc. are root.
|
||||
|
||||
If program execution is performed inside mruby VM, there is nothing to
|
||||
worry about because GC can access all roots owned by the VM.
|
||||
@@ -29,7 +29,7 @@ This can be a fatal bug if the GC tries to collect a live object.
|
||||
In CRuby, we scan C stack area, and use C variable as root to check
|
||||
whether object is alive or not. Of course, because we are accessing C
|
||||
stack just as memory region, we never know it is an integer or a
|
||||
pointer. We workaround this by assuming that if it looks like a
|
||||
pointer. We work around this by assuming that if it looks like a
|
||||
pointer, then assume it as a pointer. We call it "conservative".
|
||||
|
||||
By the way, CRuby's "conservative GC" has some problems.
|
||||
@@ -65,14 +65,14 @@ objects (See `MRB_GC_FIXED_ARENA` and `MRB_GC_ARENA_SIZE` in
|
||||
doc/guides/mrbconf.md).
|
||||
|
||||
If you create many objects in C functions, memory usage will increase, since
|
||||
GC never kick in. This memory usage may look like memory leak, but will also
|
||||
GC never kicks in. This memory usage may look like memory leaks, but will also
|
||||
make execution slower as more memory will need to be allocated.
|
||||
|
||||
With the build time configuration, you can limit the maximum size of
|
||||
arena (e.g., 100). Then if you create many objects, arena overflows,
|
||||
thus you will get an "arena overflow error".
|
||||
|
||||
To workaround these problems, we have `mrb_gc_arena_save()` and
|
||||
To work around these problems, we have `mrb_gc_arena_save()` and
|
||||
`mrb_gc_arena_restore()` functions.
|
||||
|
||||
`int mrb_gc_arena_save(mrb)` returns the current position of the stack
|
||||
|
||||
+30
-13
@@ -33,6 +33,9 @@ conf.gem :github => 'masuidrive/mrbgems-example', :branch => 'master'
|
||||
conf.gem :bitbucket => 'mruby/mrbgems-example', :branch => 'master'
|
||||
```
|
||||
|
||||
NOTE: `:bitbucket` option supports only git. Hg is unsupported in this
|
||||
version.
|
||||
|
||||
You can specify the subdirectory of the repository with `:path` option:
|
||||
|
||||
```ruby
|
||||
@@ -55,10 +58,24 @@ conf.gem mgem: 'mruby-redis', checksum_hash: '3446d19fc4a3f9697b5ddbf2a904f301c4
|
||||
If there are missing dependencies, mrbgem dependencies solver will reference
|
||||
mrbgem from the core or mgem-list.
|
||||
|
||||
To pull all gems from remote GIT repository on build, call `rake -p`,
|
||||
or `rake --pull-gems`.
|
||||
Note that if more than one git-based gem has the same base name
|
||||
(i.e. the default checkout directory name), it is (now) an error
|
||||
**UNLESS** they have the same repository URL, branch name and
|
||||
commit-id (i.e. checksum hash). You can bypass this by explicitly
|
||||
importing your preferred version **first** and setting the
|
||||
`canonical:` option to `true`:
|
||||
|
||||
NOTE: `:bitbucket` option supports only git. Hg is unsupported in this version.
|
||||
```ruby
|
||||
conf.gem github: 'me/mruby-yaml', branch: 'my-hacked-branch', canonical: true
|
||||
```
|
||||
|
||||
If you do this, the system will (mostly) silently ignore other
|
||||
attempts to clone a gem with this name.
|
||||
|
||||
Note that this only affects cloning the gem from git. It does not
|
||||
resolve version conflicts. If the version as specified in the gem's
|
||||
rakefile is incompatible with a dependency, your build will still
|
||||
fail.
|
||||
|
||||
## GemBox
|
||||
|
||||
@@ -94,7 +111,7 @@ conf.gembox 'custom'
|
||||
This will cause the `custom` GemBox to be read in during the build process,
|
||||
adding `mruby-time` and `mrbgems-example` to the build.
|
||||
|
||||
If you want, you can put GemBox outside of mruby directory. In that case you must
|
||||
If you want, you can put GemBox outside the mruby directory. In that case you must
|
||||
specify an absolute path like below.
|
||||
|
||||
```ruby
|
||||
@@ -143,7 +160,7 @@ GEM directory. A typical GEM specification could look like this for example:
|
||||
MRuby::Gem::Specification.new('c_and_ruby_extension_example') do |spec|
|
||||
spec.license = 'MIT'
|
||||
spec.author = 'mruby developers'
|
||||
spec.summary = 'Example mrbgem using C and ruby'
|
||||
spec.summary = 'Example mrbgem using C and Ruby'
|
||||
end
|
||||
```
|
||||
|
||||
@@ -397,21 +414,21 @@ binary gems, to separate normal gems and binary gems.
|
||||
```
|
||||
+- mruby-bin-example/
|
||||
|
|
||||
+- README.md (Optional)
|
||||
+- README.md (Optional)
|
||||
|
|
||||
+- bintest/
|
||||
| |
|
||||
| +- example.rb <- Test code for binary gem
|
||||
| +- example.rb <- Test code for binary gem
|
||||
|
|
||||
+- mrbgem.rake <- Gem specification
|
||||
+- mrbgem.rake <- Gem specification
|
||||
|
|
||||
+- mrblib/ <- Source for Ruby extension (Optional)
|
||||
+- mrblib/ <- Source for Ruby extension (Optional)
|
||||
|
|
||||
+- src/ <- Source for C extension (Optional)
|
||||
+- src/ <- Source for C extension (Optional)
|
||||
|
|
||||
+- tools/
|
||||
|
|
||||
+- example/ <- Executable name directory
|
||||
|
|
||||
+- example.c <- Source for Executable (includes main)
|
||||
+- example/ <- Executable name directory
|
||||
|
|
||||
+- example.c <- Source for Executable (includes main)
|
||||
```
|
||||
|
||||
+104
-104
@@ -22,107 +22,107 @@ sign) of operands.
|
||||
|
||||
## table.1 Instruction Table
|
||||
|
||||
| Instruction Name | Operand type | Semantics |
|
||||
|------------------|--------------|----------------------------------------------------------|
|
||||
| `OP_NOP` | `-` | `no operation` |
|
||||
| `OP_MOVE` | `BB` | `R(a) = R(b)` |
|
||||
| `OP_LOADL` | `BB` | `R(a) = Pool(b)` |
|
||||
| `OP_LOADI` | `BB` | `R(a) = mrb_int(b)` |
|
||||
| `OP_LOADINEG` | `BB` | `R(a) = mrb_int(-b)` |
|
||||
| `OP_LOADI__1` | `B` | `R(a) = mrb_int(-1)` |
|
||||
| `OP_LOADI_0` | `B` | `R(a) = mrb_int(0)` |
|
||||
| `OP_LOADI_1` | `B` | `R(a) = mrb_int(1)` |
|
||||
| `OP_LOADI_2` | `B` | `R(a) = mrb_int(2)` |
|
||||
| `OP_LOADI_3` | `B` | `R(a) = mrb_int(3)` |
|
||||
| `OP_LOADI_4` | `B` | `R(a) = mrb_int(4)` |
|
||||
| `OP_LOADI_5` | `B` | `R(a) = mrb_int(5)` |
|
||||
| `OP_LOADI_6` | `B` | `R(a) = mrb_int(6)` |
|
||||
| `OP_LOADI_7` | `B` | `R(a) = mrb_int(7)` |
|
||||
| `OP_LOADI16` | `BS` | `R(a) = mrb_int(b)` |
|
||||
| `OP_LOADI32` | `BSS` | `R(a) = mrb_int((b<<16)+c)` |
|
||||
| `OP_LOADSYM` | `BB` | `R(a) = Syms(b)` |
|
||||
| `OP_LOADNIL` | `B` | `R(a) = nil` |
|
||||
| `OP_LOADSELF` | `B` | `R(a) = self` |
|
||||
| `OP_LOADT` | `B` | `R(a) = true` |
|
||||
| `OP_LOADF` | `B` | `R(a) = false` |
|
||||
| `OP_GETGV` | `BB` | `R(a) = getglobal(Syms(b))` |
|
||||
| `OP_SETGV` | `BB` | `setglobal(Syms(b), R(a))` |
|
||||
| `OP_GETSV` | `BB` | `R(a) = Special[Syms(b)]` |
|
||||
| `OP_SETSV` | `BB` | `Special[Syms(b)] = R(a)` |
|
||||
| `OP_GETIV` | `BB` | `R(a) = ivget(Syms(b))` |
|
||||
| `OP_SETIV` | `BB` | `ivset(Syms(b),R(a))` |
|
||||
| `OP_GETCV` | `BB` | `R(a) = cvget(Syms(b))` |
|
||||
| `OP_SETCV` | `BB` | `cvset(Syms(b),R(a))` |
|
||||
| `OP_GETCONST` | `BB` | `R(a) = constget(Syms(b))` |
|
||||
| `OP_SETCONST` | `BB` | `constset(Syms(b),R(a))` |
|
||||
| `OP_GETMCNST` | `BB` | `R(a) = R(a)::Syms(b)` |
|
||||
| `OP_SETMCNST` | `BB` | `R(a+1)::Syms(b) = R(a)` |
|
||||
| `OP_GETUPVAR` | `BBB` | `R(a) = uvget(b,c)` |
|
||||
| `OP_SETUPVAR` | `BBB` | `uvset(b,c,R(a))` |
|
||||
| `OP_JMP` | `S` | `pc+=a` |
|
||||
| `OP_JMPIF` | `BS` | `if R(a) pc+=b` |
|
||||
| `OP_JMPNOT` | `BS` | `if !R(a) pc+=b` |
|
||||
| `OP_JMPNIL` | `BS` | `if R(a)==nil pc+=b` |
|
||||
| `OP_JMPUW` | `S` | `unwind_and_jump_to(a)` |
|
||||
| `OP_EXCEPT` | `B` | `R(a) = exc` |
|
||||
| `OP_RESCUE` | `BB` | `R(b) = R(a).isa?(R(b))` |
|
||||
| `OP_RAISEIF` | `B` | `raise(R(a)) if R(a)` |
|
||||
| `OP_SEND` | `BBB` | `R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c))` |
|
||||
| `OP_SENDB` | `BBB` | `R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c),&R(a+c+1))` |
|
||||
| `OP_CALL` | `-` | `R(0) = self.call(frame.argc, frame.argv)` |
|
||||
| `OP_SUPER` | `BB` | `R(a) = super(R(a+1),... ,R(a+b+1))` |
|
||||
| `OP_ARGARY` | `BS` | `R(a) = argument array (16=m5:r1:m5:d1:lv4)` |
|
||||
| `OP_ENTER` | `W` | `arg setup according to flags (23=m5:o5:r1:m5:k5:d1:b1)` |
|
||||
| `OP_KEY_P` | `BB` | `R(a) = kdict.key?(Syms(b))` |
|
||||
| `OP_KEYEND` | `-` | `raise unless kdict.empty?` |
|
||||
| `OP_KARG` | `BB` | `R(a) = kdict[Syms(b)]; kdict.delete(Syms(b))` |
|
||||
| `OP_RETURN` | `B` | `return R(a) (normal)` |
|
||||
| `OP_RETURN_BLK` | `B` | `return R(a) (in-block return)` |
|
||||
| `OP_BREAK` | `B` | `break R(a)` |
|
||||
| `OP_BLKPUSH` | `BS` | `R(a) = block (16=m5:r1:m5:d1:lv4)` |
|
||||
| `OP_ADD` | `B` | `R(a) = R(a)+R(a+1)` |
|
||||
| `OP_ADDI` | `BB` | `R(a) = R(a)+mrb_int(b)` |
|
||||
| `OP_SUB` | `B` | `R(a) = R(a)-R(a+1)` |
|
||||
| `OP_SUBI` | `BB` | `R(a) = R(a)-mrb_int(b)` |
|
||||
| `OP_MUL` | `B` | `R(a) = R(a)*R(a+1)` |
|
||||
| `OP_DIV` | `B` | `R(a) = R(a)/R(a+1)` |
|
||||
| `OP_EQ` | `B` | `R(a) = R(a)==R(a+1)` |
|
||||
| `OP_LT` | `B` | `R(a) = R(a)<R(a+1)` |
|
||||
| `OP_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` | `BB` | `ary_push(R(a),R(a+1)..R(a+b))` |
|
||||
| `OP_ARYDUP` | `B` | `R(a) = ary_dup(R(a))` |
|
||||
| `OP_AREF` | `BBB` | `R(a) = R(b)[c]` |
|
||||
| `OP_ASET` | `BBB` | `R(b)[c] = R(a)` |
|
||||
| `OP_APOST` | `BBB` | `*R(a),R(a+1)..R(a+c) = R(a)[b..]` |
|
||||
| `OP_INTERN` | `B` | `R(a) = intern(R(a))` |
|
||||
| `OP_STRING` | `BB` | `R(a) = str_dup(Pool(b))` |
|
||||
| `OP_STRCAT` | `B` | `str_cat(R(a),R(a+1))` |
|
||||
| `OP_HASH` | `BB` | `R(a) = hash_new(R(a),R(a+1)..R(a+b*2-1))` |
|
||||
| `OP_HASHADD` | `BB` | `hash_push(R(a),R(a+1)..R(a+b*2))` |
|
||||
| `OP_HASHCAT` | `B` | `R(a) = hash_cat(R(a),R(a+1))` |
|
||||
| `OP_LAMBDA` | `BB` | `R(a) = lambda(Irep(b),OP_L_LAMBDA)` |
|
||||
| `OP_BLOCK` | `BB` | `R(a) = lambda(Irep(b),OP_L_BLOCK)` |
|
||||
| `OP_METHOD` | `BB` | `R(a) = lambda(Irep(b),OP_L_METHOD)` |
|
||||
| `OP_RANGE_INC` | `B` | `R(a) = range_new(R(a),R(a+1),FALSE)` |
|
||||
| `OP_RANGE_EXC` | `B` | `R(a) = range_new(R(a),R(a+1),TRUE)` |
|
||||
| `OP_OCLASS` | `B` | `R(a) = ::Object` |
|
||||
| `OP_CLASS` | `BB` | `R(a) = newclass(R(a),Syms(b),R(a+1))` |
|
||||
| `OP_MODULE` | `BB` | `R(a) = newmodule(R(a),Syms(b))` |
|
||||
| `OP_EXEC` | `BB` | `R(a) = blockexec(R(a),Irep[b])` |
|
||||
| `OP_DEF` | `BB` | `R(a).newmethod(Syms(b),R(a+1)); R(a) = Syms(b)` |
|
||||
| `OP_ALIAS` | `BB` | `alias_method(target_class,Syms(a),Syms(b))` |
|
||||
| `OP_UNDEF` | `B` | `undef_method(target_class,Syms(a))` |
|
||||
| `OP_SCLASS` | `B` | `R(a) = R(a).singleton_class` |
|
||||
| `OP_TCLASS` | `B` | `R(a) = target_class` |
|
||||
| `OP_DEBUG` | `BBB` | `print a,b,c` |
|
||||
| `OP_ERR` | `B` | `raise(LocalJumpError, Pool(a))` |
|
||||
| `OP_EXT1` | `-` | `make 1st operand 16bit` |
|
||||
| `OP_EXT2` | `-` | `make 2nd operand 16bit` |
|
||||
| `OP_EXT3` | `-` | `make 1st and 2nd operands 16bit` |
|
||||
| `OP_STOP` | `-` | `stop VM` |
|
||||
|------------------|--------------|----------------------------------------------------------|
|
||||
| Instruction Name | Operand type | Semantics |
|
||||
|--------------------|----------------|------------------------------------------------------------|
|
||||
| `OP_NOP` | `-` | `no operation` |
|
||||
| `OP_MOVE` | `BB` | `R(a) = R(b)` |
|
||||
| `OP_LOADL` | `BB` | `R(a) = Pool(b)` |
|
||||
| `OP_LOADI` | `BB` | `R(a) = mrb_int(b)` |
|
||||
| `OP_LOADINEG` | `BB` | `R(a) = mrb_int(-b)` |
|
||||
| `OP_LOADI__1` | `B` | `R(a) = mrb_int(-1)` |
|
||||
| `OP_LOADI_0` | `B` | `R(a) = mrb_int(0)` |
|
||||
| `OP_LOADI_1` | `B` | `R(a) = mrb_int(1)` |
|
||||
| `OP_LOADI_2` | `B` | `R(a) = mrb_int(2)` |
|
||||
| `OP_LOADI_3` | `B` | `R(a) = mrb_int(3)` |
|
||||
| `OP_LOADI_4` | `B` | `R(a) = mrb_int(4)` |
|
||||
| `OP_LOADI_5` | `B` | `R(a) = mrb_int(5)` |
|
||||
| `OP_LOADI_6` | `B` | `R(a) = mrb_int(6)` |
|
||||
| `OP_LOADI_7` | `B` | `R(a) = mrb_int(7)` |
|
||||
| `OP_LOADI16` | `BS` | `R(a) = mrb_int(b)` |
|
||||
| `OP_LOADI32` | `BSS` | `R(a) = mrb_int((b<<16)+c)` |
|
||||
| `OP_LOADSYM` | `BB` | `R(a) = Syms(b)` |
|
||||
| `OP_LOADNIL` | `B` | `R(a) = nil` |
|
||||
| `OP_LOADSELF` | `B` | `R(a) = self` |
|
||||
| `OP_LOADT` | `B` | `R(a) = true` |
|
||||
| `OP_LOADF` | `B` | `R(a) = false` |
|
||||
| `OP_GETGV` | `BB` | `R(a) = getglobal(Syms(b))` |
|
||||
| `OP_SETGV` | `BB` | `setglobal(Syms(b), R(a))` |
|
||||
| `OP_GETSV` | `BB` | `R(a) = Special[Syms(b)]` |
|
||||
| `OP_SETSV` | `BB` | `Special[Syms(b)] = R(a)` |
|
||||
| `OP_GETIV` | `BB` | `R(a) = ivget(Syms(b))` |
|
||||
| `OP_SETIV` | `BB` | `ivset(Syms(b),R(a))` |
|
||||
| `OP_GETCV` | `BB` | `R(a) = cvget(Syms(b))` |
|
||||
| `OP_SETCV` | `BB` | `cvset(Syms(b),R(a))` |
|
||||
| `OP_GETCONST` | `BB` | `R(a) = constget(Syms(b))` |
|
||||
| `OP_SETCONST` | `BB` | `constset(Syms(b),R(a))` |
|
||||
| `OP_GETMCNST` | `BB` | `R(a) = R(a)::Syms(b)` |
|
||||
| `OP_SETMCNST` | `BB` | `R(a+1)::Syms(b) = R(a)` |
|
||||
| `OP_GETUPVAR` | `BBB` | `R(a) = uvget(b,c)` |
|
||||
| `OP_SETUPVAR` | `BBB` | `uvset(b,c,R(a))` |
|
||||
| `OP_JMP` | `S` | `pc+=a` |
|
||||
| `OP_JMPIF` | `BS` | `if R(a) pc+=b` |
|
||||
| `OP_JMPNOT` | `BS` | `if !R(a) pc+=b` |
|
||||
| `OP_JMPNIL` | `BS` | `if R(a)==nil pc+=b` |
|
||||
| `OP_JMPUW` | `S` | `unwind_and_jump_to(a)` |
|
||||
| `OP_EXCEPT` | `B` | `R(a) = exc` |
|
||||
| `OP_RESCUE` | `BB` | `R(b) = R(a).isa?(R(b))` |
|
||||
| `OP_RAISEIF` | `B` | `raise(R(a)) if R(a)` |
|
||||
| `OP_SEND` | `BBB` | `R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c))` |
|
||||
| `OP_SENDB` | `BBB` | `R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c),&R(a+c+1))` |
|
||||
| `OP_CALL` | `-` | `R(0) = self.call(frame.argc, frame.argv)` |
|
||||
| `OP_SUPER` | `BB` | `R(a) = super(R(a+1),... ,R(a+b+1))` |
|
||||
| `OP_ARGARY` | `BS` | `R(a) = argument array (16=m5:r1:m5:d1:lv4)` |
|
||||
| `OP_ENTER` | `W` | `arg setup according to flags (23=m5:o5:r1:m5:k5:d1:b1)` |
|
||||
| `OP_KEY_P` | `BB` | `R(a) = kdict.key?(Syms(b))` |
|
||||
| `OP_KEYEND` | `-` | `raise unless kdict.empty?` |
|
||||
| `OP_KARG` | `BB` | `R(a) = kdict[Syms(b)]; kdict.delete(Syms(b))` |
|
||||
| `OP_RETURN` | `B` | `return R(a) (normal)` |
|
||||
| `OP_RETURN_BLK` | `B` | `return R(a) (in-block return)` |
|
||||
| `OP_BREAK` | `B` | `break R(a)` |
|
||||
| `OP_BLKPUSH` | `BS` | `R(a) = block (16=m5:r1:m5:d1:lv4)` |
|
||||
| `OP_ADD` | `B` | `R(a) = R(a)+R(a+1)` |
|
||||
| `OP_ADDI` | `BB` | `R(a) = R(a)+mrb_int(b)` |
|
||||
| `OP_SUB` | `B` | `R(a) = R(a)-R(a+1)` |
|
||||
| `OP_SUBI` | `BB` | `R(a) = R(a)-mrb_int(b)` |
|
||||
| `OP_MUL` | `B` | `R(a) = R(a)*R(a+1)` |
|
||||
| `OP_DIV` | `B` | `R(a) = R(a)/R(a+1)` |
|
||||
| `OP_EQ` | `B` | `R(a) = R(a)==R(a+1)` |
|
||||
| `OP_LT` | `B` | `R(a) = R(a)<R(a+1)` |
|
||||
| `OP_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` | `BB` | `ary_push(R(a),R(a+1)..R(a+b))` |
|
||||
| `OP_ARYDUP` | `B` | `R(a) = ary_dup(R(a))` |
|
||||
| `OP_AREF` | `BBB` | `R(a) = R(b)[c]` |
|
||||
| `OP_ASET` | `BBB` | `R(b)[c] = R(a)` |
|
||||
| `OP_APOST` | `BBB` | `*R(a),R(a+1)..R(a+c) = R(a)[b..]` |
|
||||
| `OP_INTERN` | `B` | `R(a) = intern(R(a))` |
|
||||
| `OP_STRING` | `BB` | `R(a) = str_dup(Pool(b))` |
|
||||
| `OP_STRCAT` | `B` | `str_cat(R(a),R(a+1))` |
|
||||
| `OP_HASH` | `BB` | `R(a) = hash_new(R(a),R(a+1)..R(a+b*2-1))` |
|
||||
| `OP_HASHADD` | `BB` | `hash_push(R(a),R(a+1)..R(a+b*2))` |
|
||||
| `OP_HASHCAT` | `B` | `R(a) = hash_cat(R(a),R(a+1))` |
|
||||
| `OP_LAMBDA` | `BB` | `R(a) = lambda(Irep(b),OP_L_LAMBDA)` |
|
||||
| `OP_BLOCK` | `BB` | `R(a) = lambda(Irep(b),OP_L_BLOCK)` |
|
||||
| `OP_METHOD` | `BB` | `R(a) = lambda(Irep(b),OP_L_METHOD)` |
|
||||
| `OP_RANGE_INC` | `B` | `R(a) = range_new(R(a),R(a+1),FALSE)` |
|
||||
| `OP_RANGE_EXC` | `B` | `R(a) = range_new(R(a),R(a+1),TRUE)` |
|
||||
| `OP_OCLASS` | `B` | `R(a) = ::Object` |
|
||||
| `OP_CLASS` | `BB` | `R(a) = newclass(R(a),Syms(b),R(a+1))` |
|
||||
| `OP_MODULE` | `BB` | `R(a) = newmodule(R(a),Syms(b))` |
|
||||
| `OP_EXEC` | `BB` | `R(a) = blockexec(R(a),Irep[b])` |
|
||||
| `OP_DEF` | `BB` | `R(a).newmethod(Syms(b),R(a+1)); R(a) = Syms(b)` |
|
||||
| `OP_ALIAS` | `BB` | `alias_method(target_class,Syms(a),Syms(b))` |
|
||||
| `OP_UNDEF` | `B` | `undef_method(target_class,Syms(a))` |
|
||||
| `OP_SCLASS` | `B` | `R(a) = R(a).singleton_class` |
|
||||
| `OP_TCLASS` | `B` | `R(a) = target_class` |
|
||||
| `OP_DEBUG` | `BBB` | `print a,b,c` |
|
||||
| `OP_ERR` | `B` | `raise(LocalJumpError, Pool(a))` |
|
||||
| `OP_EXT1` | `-` | `make 1st operand 16bit` |
|
||||
| `OP_EXT2` | `-` | `make 2nd operand 16bit` |
|
||||
| `OP_EXT3` | `-` | `make 1st and 2nd operands 16bit` |
|
||||
| `OP_STOP` | `-` | `stop VM` |
|
||||
| ------------------ | -------------- | ---------------------------------------------------------- |
|
||||
|
||||
+2
-2
@@ -75,7 +75,7 @@ to be default `mrb_value` representation. Now the default is
|
||||
## `MRB_WORD_BOXING`
|
||||
|
||||
Pack `mrb_value` in an `intptr_t` integer. Consumes less
|
||||
memory compared to `MRB_NO_BOXING` especially on 32 bit
|
||||
memory compared to `MRB_NO_BOXING` especially on 32-bit
|
||||
platforms. `Fixnum` size is 31 bits so some integer values
|
||||
does not fit in `Fixnum` integers.
|
||||
|
||||
@@ -116,7 +116,7 @@ Instructions that access pool[i]/syms[i] where i>255.
|
||||
* `OP_STRING16`
|
||||
* `OP_LOADSYM16`
|
||||
|
||||
Instructions that load a 32 bit integer.
|
||||
Instructions that load a 32-bit integer.
|
||||
|
||||
* `OP_LOADI32`
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
# User visible changes in `mruby3.2` from `mruby3.1`
|
||||
|
||||
# The language
|
||||
|
||||
- Now `a::B = c` should evaluate `a` then `c`.
|
||||
- Anonymous arguments `*`, `**`, `&` can be passed for forwarding.
|
||||
- Multi-precision integer is available now via `mruby-bigint` gem.
|
||||
|
||||
# Tools
|
||||
|
||||
## `mruby`
|
||||
|
||||
- `-b` only specifies the script is the binary. The files loaded by `-r` are not affected by the option.
|
||||
- `mruby` now loads complied binary if the suffix is `.mrb`.
|
||||
|
||||
## `mrbc`
|
||||
|
||||
- Add `--no-optimize` option to disable optimization.
|
||||
|
||||
# mrbgems
|
||||
|
||||
## mruby-errno
|
||||
|
||||
- `mruby-errno` gem is now bundled.
|
||||
|
||||
## mruby-class-ext
|
||||
|
||||
- Add `Class#subclasses` method.
|
||||
- Add `Module#undefined_instance_methods` method.
|
||||
|
||||
# CVEs
|
||||
|
||||
Following CVEs are fixed.
|
||||
|
||||
- [CVE-2022-0481](https://nvd.nist.gov/vuln/detail/CVE-2022-0481)
|
||||
- [CVE-2022-0525](https://nvd.nist.gov/vuln/detail/CVE-2022-0525)
|
||||
- [CVE-2022-0570](https://nvd.nist.gov/vuln/detail/CVE-2022-0570)
|
||||
- [CVE-2022-0614](https://nvd.nist.gov/vuln/detail/CVE-2022-0614)
|
||||
- [CVE-2022-0623](https://nvd.nist.gov/vuln/detail/CVE-2022-0623)
|
||||
- [CVE-2022-0630](https://nvd.nist.gov/vuln/detail/CVE-2022-0630)
|
||||
- [CVE-2022-0717](https://nvd.nist.gov/vuln/detail/CVE-2022-0817)
|
||||
- [CVE-2022-1212](https://nvd.nist.gov/vuln/detail/CVE-2022-1212)
|
||||
- [CVE-2022-1276](https://nvd.nist.gov/vuln/detail/CVE-2022-1276)
|
||||
- [CVE-2022-1286](https://nvd.nist.gov/vuln/detail/CVE-2022-1286)
|
||||
+18
-13
@@ -312,7 +312,7 @@ typedef struct mrb_state {
|
||||
struct RClass *eException_class;
|
||||
struct RClass *eStandardError_class;
|
||||
struct RObject *nomem_err; /* pre-allocated NoMemoryError */
|
||||
struct RObject *stack_err; /* pre-allocated SysStackError */
|
||||
struct RObject *stack_err; /* pre-allocated SystemStackError */
|
||||
#ifdef MRB_GC_FIXED_ARENA
|
||||
struct RObject *arena_err; /* pre-allocated arena overflow error */
|
||||
#endif
|
||||
@@ -948,14 +948,14 @@ typedef const char *mrb_args_format;
|
||||
/**
|
||||
* Get keyword arguments by `mrb_get_args()` with `:` specifier.
|
||||
*
|
||||
* `mrb_kwargs::num` indicates that the number of keyword values.
|
||||
* `mrb_kwargs::num` indicates that the total number of keyword values.
|
||||
*
|
||||
* `mrb_kwargs::values` is an object array, and the keyword argument corresponding to the string array is assigned.
|
||||
* Note that `undef` is assigned if there is no keyword argument corresponding to `mrb_kwargs::optional`.
|
||||
* `mrb_kwargs::required` indicates that the specified number of keywords starting from the beginning of the `mrb_sym` array are required.
|
||||
*
|
||||
* `mrb_kwargs::table` accepts a string array.
|
||||
* `mrb_kwargs::table` accepts a `mrb_sym` array of C.
|
||||
*
|
||||
* `mrb_kwargs::required` indicates that the specified number of keywords starting from the beginning of the string array are required.
|
||||
* `mrb_kwargs::values` is an object array of C, and the keyword argument corresponding to the `mrb_sym` array is assigned.
|
||||
* Note that `undef` is assigned if there is no keyword argument corresponding over `mrb_kwargs::required` to `mrb_kwargs::num`.
|
||||
*
|
||||
* `mrb_kwargs::rest` is the remaining keyword argument that can be accepted as `**rest` in Ruby.
|
||||
* If `NULL` is specified, `ArgumentError` is raised when there is an undefined keyword.
|
||||
@@ -965,10 +965,10 @@ typedef const char *mrb_args_format;
|
||||
* // def method(a: 1, b: 2)
|
||||
*
|
||||
* uint32_t kw_num = 2;
|
||||
* const char *kw_names[kw_num] = { "a", "b" };
|
||||
* uint32_t kw_required = 0;
|
||||
* mrb_sym kw_names[] = { mrb_intern_lit(mrb, "a"), mrb_intern_lit(mrb, "b") };
|
||||
* mrb_value kw_values[kw_num];
|
||||
* const mrb_kwargs kwargs = { kw_num, kw_required, kw_names, kw_values, NULL };
|
||||
* mrb_kwargs kwargs = { kw_num, kw_required, kw_names, kw_values, NULL };
|
||||
*
|
||||
* mrb_get_args(mrb, ":", &kwargs);
|
||||
* if (mrb_undef_p(kw_values[0])) { kw_values[0] = mrb_fixnum_value(1); }
|
||||
@@ -979,10 +979,12 @@ typedef const char *mrb_args_format;
|
||||
*
|
||||
* mrb_value str, kw_rest;
|
||||
* uint32_t kw_num = 3;
|
||||
* const mrb_sym kw_names[kw_num] = { MRB_SYM(x), MRB_SYM(y), MRB_SYM(z) };
|
||||
* uint32_t kw_required = 1;
|
||||
* // Note that `#include <mruby/presym.h>` is required beforehand because `MRB_SYM()` is used.
|
||||
* // If the usage of `MRB_SYM()` is not desired, replace it with `mrb_intern_lit()`.
|
||||
* mrb_sym kw_names[] = { MRB_SYM(x), MRB_SYM(y), MRB_SYM(z) };
|
||||
* mrb_value kw_values[kw_num];
|
||||
* const mrb_kwargs kwargs = { kw_num, kw_required, kw_names, kw_values, &kw_rest };
|
||||
* mrb_kwargs kwargs = { kw_num, kw_required, kw_names, kw_values, &kw_rest };
|
||||
*
|
||||
* mrb_get_args(mrb, "S:", &str, &kwargs);
|
||||
* // or: mrb_get_args(mrb, ":S", &kwargs, &str);
|
||||
@@ -1178,13 +1180,13 @@ MRB_API void mrb_free(mrb_state*, void*);
|
||||
*/
|
||||
#define MRB_OBJ_ALLOC(mrb, tt, klass) ((MRB_VTYPE_TYPEOF(tt)*)mrb_obj_alloc(mrb, tt, klass))
|
||||
|
||||
MRB_API mrb_value mrb_str_new(mrb_state *mrb, const char *p, size_t len);
|
||||
MRB_API mrb_value mrb_str_new(mrb_state *mrb, const char *p, mrb_int len);
|
||||
|
||||
/**
|
||||
* Turns a C string into a Ruby string value.
|
||||
*/
|
||||
MRB_API mrb_value mrb_str_new_cstr(mrb_state*, const char*);
|
||||
MRB_API mrb_value mrb_str_new_static(mrb_state *mrb, const char *p, size_t len);
|
||||
MRB_API mrb_value mrb_str_new_static(mrb_state *mrb, const char *p, mrb_int len);
|
||||
#define mrb_str_new_lit(mrb, lit) mrb_str_new_static(mrb, (lit), mrb_strlen_lit(lit))
|
||||
|
||||
MRB_API mrb_value mrb_obj_freeze(mrb_state*, mrb_value);
|
||||
@@ -1336,7 +1338,7 @@ MRB_API mrb_value mrb_obj_clone(mrb_state *mrb, mrb_value self);
|
||||
#define TOLOWER(c) (ISUPPER(c) ? ((c) | 0x20) : (c))
|
||||
#endif
|
||||
|
||||
MRB_API mrb_value mrb_exc_new(mrb_state *mrb, struct RClass *c, const char *ptr, size_t len);
|
||||
MRB_API mrb_value mrb_exc_new(mrb_state *mrb, struct RClass *c, const char *ptr, mrb_int len);
|
||||
MRB_API mrb_noreturn void mrb_exc_raise(mrb_state *mrb, mrb_value exc);
|
||||
|
||||
MRB_API mrb_noreturn void mrb_raise(mrb_state *mrb, struct RClass *c, const char *msg);
|
||||
@@ -1404,6 +1406,9 @@ MRB_API mrb_value mrb_check_string_type(mrb_state *mrb, mrb_value str);
|
||||
#define mrb_to_str(mrb, str) mrb_ensure_string_type(mrb,str)
|
||||
/* obsolete: use mrb_obj_as_string() instead */
|
||||
#define mrb_str_to_str(mrb, str) mrb_obj_as_string(mrb, str)
|
||||
/* check if val is an integer (including Bigint) */
|
||||
MRB_API mrb_value mrb_ensure_integer_type(mrb_state *mrb, mrb_value val);
|
||||
/* check if val fit in mrb_int */
|
||||
MRB_API mrb_value mrb_ensure_int_type(mrb_state *mrb, mrb_value val);
|
||||
#define mrb_as_int(mrb, val) mrb_integer(mrb_ensure_int_type(mrb, val))
|
||||
/* obsolete: use mrb_ensure_int_type() instead */
|
||||
|
||||
@@ -85,7 +85,6 @@ struct RArray {
|
||||
#define ARY_SET_SHARED_FLAG(a) ((a)->flags |= MRB_ARY_SHARED)
|
||||
#define ARY_UNSET_SHARED_FLAG(a) ((a)->flags &= ~MRB_ARY_SHARED)
|
||||
|
||||
void mrb_ary_decref(mrb_state*, mrb_shared_array*);
|
||||
MRB_API void mrb_ary_modify(mrb_state*, struct RArray*);
|
||||
MRB_API mrb_value mrb_ary_new_capa(mrb_state*, mrb_int);
|
||||
|
||||
@@ -296,8 +295,6 @@ MRB_API mrb_value mrb_ary_join(mrb_state *mrb, mrb_value ary, mrb_value sep);
|
||||
*/
|
||||
MRB_API mrb_value mrb_ary_resize(mrb_state *mrb, mrb_value ary, mrb_int new_len);
|
||||
|
||||
/* helper functions */
|
||||
mrb_value mrb_ary_subseq(mrb_state *mrb, mrb_value ary, mrb_int beg, mrb_int len);
|
||||
|
||||
MRB_END_DECL
|
||||
|
||||
|
||||
@@ -73,8 +73,6 @@ mrb_class(mrb_state *mrb, mrb_value v)
|
||||
#define MRB_SET_INSTANCE_TT(c, tt) ((c)->flags = (((c)->flags & ~MRB_INSTANCE_TT_MASK) | (char)(tt)))
|
||||
#define MRB_INSTANCE_TT(c) (enum mrb_vtype)((c)->flags & MRB_INSTANCE_TT_MASK)
|
||||
|
||||
struct RClass *mrb_vm_define_class(mrb_state*, mrb_value, mrb_value, mrb_sym);
|
||||
struct RClass *mrb_vm_define_module(mrb_state*, mrb_value, mrb_sym);
|
||||
MRB_API void mrb_define_method_raw(mrb_state*, struct RClass*, mrb_sym, mrb_method_t);
|
||||
MRB_API void mrb_alias_method(mrb_state*, struct RClass *c, mrb_sym a, mrb_sym b);
|
||||
MRB_API void mrb_remove_method(mrb_state *mrb, struct RClass *c, mrb_sym sym);
|
||||
@@ -83,15 +81,6 @@ MRB_API mrb_method_t mrb_method_search_vm(mrb_state*, struct RClass**, mrb_sym);
|
||||
MRB_API mrb_method_t mrb_method_search(mrb_state*, struct RClass*, mrb_sym);
|
||||
|
||||
MRB_API struct RClass* mrb_class_real(struct RClass* cl);
|
||||
mrb_value mrb_instance_new(mrb_state *mrb, mrb_value cv);
|
||||
|
||||
void mrb_class_name_class(mrb_state*, struct RClass*, struct RClass*, mrb_sym);
|
||||
mrb_bool mrb_const_name_p(mrb_state*, const char*, mrb_int);
|
||||
mrb_value mrb_class_find_path(mrb_state*, struct RClass*);
|
||||
mrb_value mrb_mod_to_s(mrb_state*, mrb_value);
|
||||
void mrb_gc_mark_mt(mrb_state*, struct RClass*);
|
||||
size_t mrb_gc_mark_mt_size(mrb_state*, struct RClass*);
|
||||
void mrb_gc_free_mt(mrb_state*, struct RClass*);
|
||||
|
||||
#ifndef MRB_NO_METHOD_CACHE
|
||||
void mrb_mc_clear_by_class(mrb_state *mrb, struct RClass* c);
|
||||
|
||||
@@ -31,10 +31,11 @@ typedef struct mrb_irep_debug_info_file {
|
||||
uint32_t line_entry_count;
|
||||
mrb_debug_line_type line_type;
|
||||
union {
|
||||
const char *s;
|
||||
void *ptr;
|
||||
uint16_t *ary;
|
||||
mrb_irep_debug_info_line *flat_map;
|
||||
uint8_t *packed_map;
|
||||
const uint16_t *ary;
|
||||
const mrb_irep_debug_info_line *flat_map;
|
||||
const uint8_t *packed_map;
|
||||
} lines;
|
||||
} mrb_irep_debug_info_file;
|
||||
|
||||
|
||||
@@ -21,15 +21,11 @@ MRB_BEGIN_DECL
|
||||
#define MRB_DUMP_STATIC 2
|
||||
#define DUMP_DEBUG_INFO MRB_DUMP_DEBUG_INFO /* deprecated */
|
||||
|
||||
int mrb_dump_irep(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size);
|
||||
#ifndef MRB_NO_STDIO
|
||||
int mrb_dump_irep_binary(mrb_state*, const mrb_irep*, uint8_t, FILE*);
|
||||
int mrb_dump_irep_cfunc(mrb_state *mrb, const mrb_irep*, uint8_t flags, FILE *f, const char *initname);
|
||||
int mrb_dump_irep_cstruct(mrb_state *mrb, const mrb_irep*, uint8_t flags, FILE *f, const char *initname);
|
||||
mrb_irep *mrb_read_irep_file(mrb_state*, FILE*);
|
||||
MRB_API mrb_value mrb_load_irep_file(mrb_state*,FILE*);
|
||||
MRB_API mrb_value mrb_load_irep_file_cxt(mrb_state*, FILE*, mrbc_context*);
|
||||
#endif
|
||||
/* avoid mrb_read_irep(); use mrb_read_irep_buf() instead (may cause buffer overflow) */
|
||||
MRB_API mrb_irep *mrb_read_irep(mrb_state*, const uint8_t*);
|
||||
MRB_API mrb_irep *mrb_read_irep_buf(mrb_state*, const void*, size_t);
|
||||
|
||||
|
||||
@@ -17,20 +17,16 @@ MRB_BEGIN_DECL
|
||||
struct RException {
|
||||
MRB_OBJECT_HEADER;
|
||||
struct iv_tbl *iv;
|
||||
struct RString *mesg;
|
||||
struct RObject *mesg; // NULL or probably RString
|
||||
struct RObject *backtrace; // NULL, RArray or RData
|
||||
};
|
||||
|
||||
#define mrb_exc_ptr(v) ((struct RException*)mrb_ptr(v))
|
||||
#define MRB_EXC_MESG_STRING_FLAG 0x100
|
||||
|
||||
MRB_API void mrb_sys_fail(mrb_state *mrb, const char *mesg);
|
||||
MRB_API mrb_noreturn void mrb_sys_fail(mrb_state *mrb, const char *mesg);
|
||||
MRB_API mrb_value mrb_exc_new_str(mrb_state *mrb, struct RClass* c, mrb_value str);
|
||||
#define mrb_exc_new_lit(mrb, c, lit) mrb_exc_new_str(mrb, c, mrb_str_new_lit(mrb, lit))
|
||||
#define mrb_exc_new_str_lit(mrb, c, lit) mrb_exc_new_lit(mrb, c, lit)
|
||||
MRB_API mrb_value mrb_make_exception(mrb_state *mrb, mrb_int argc, const mrb_value *argv);
|
||||
mrb_value mrb_exc_backtrace(mrb_state *mrb, mrb_value exc);
|
||||
mrb_value mrb_get_backtrace(mrb_state *mrb);
|
||||
|
||||
MRB_API mrb_noreturn void mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_value args, const char *fmt, ...);
|
||||
|
||||
/* declaration for `fail` method */
|
||||
|
||||
+1
-2
@@ -84,8 +84,7 @@ typedef struct mrb_gc {
|
||||
size_t majorgc_old_threshold;
|
||||
} mrb_gc;
|
||||
|
||||
MRB_API mrb_bool
|
||||
mrb_object_dead_p(struct mrb_state *mrb, struct RBasic *object);
|
||||
MRB_API mrb_bool mrb_object_dead_p(struct mrb_state *mrb, struct RBasic *object);
|
||||
|
||||
#define MRB_GC_RED 7
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ struct RHash {
|
||||
#define mrb_hash_ptr(v) ((struct RHash*)(mrb_ptr(v)))
|
||||
#define mrb_hash_value(p) mrb_obj_value((void*)(p))
|
||||
|
||||
size_t mrb_hash_memsize(mrb_value obj);
|
||||
MRB_API mrb_value mrb_hash_new_capa(mrb_state *mrb, mrb_int capa);
|
||||
|
||||
/*
|
||||
@@ -226,11 +225,6 @@ MRB_API void mrb_hash_merge(mrb_state *mrb, mrb_value hash1, mrb_value hash2);
|
||||
#define MRB_RHASH_DEFAULT_P(hash) (RHASH(hash)->flags & MRB_HASH_DEFAULT)
|
||||
#define MRB_RHASH_PROCDEFAULT_P(hash) (RHASH(hash)->flags & MRB_HASH_PROC_DEFAULT)
|
||||
|
||||
/* GC functions */
|
||||
void mrb_gc_mark_hash(mrb_state*, struct RHash*);
|
||||
size_t mrb_gc_mark_hash_size(mrb_state*, struct RHash*);
|
||||
void mrb_gc_free_hash(mrb_state*, struct RHash*);
|
||||
|
||||
/* return non zero to break the loop */
|
||||
typedef int (mrb_hash_foreach_func)(mrb_state *mrb, mrb_value key, mrb_value val, void *data);
|
||||
MRB_API void mrb_hash_foreach(mrb_state *mrb, struct RHash *hash, mrb_hash_foreach_func *func, void *p);
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
/**
|
||||
** @file mruby/internal.h - Functions only called from within the library
|
||||
**
|
||||
** See Copyright Notice in mruby.h
|
||||
*/
|
||||
|
||||
#ifndef MRUBY_INTERNAL_H
|
||||
#define MRUBY_INTERNAL_H
|
||||
|
||||
#ifdef MRUBY_ARRAY_H
|
||||
void mrb_ary_decref(mrb_state*, mrb_shared_array*);
|
||||
mrb_value mrb_ary_subseq(mrb_state *mrb, mrb_value ary, mrb_int beg, mrb_int len);
|
||||
#endif
|
||||
|
||||
#ifdef MRUBY_CLASS_H
|
||||
struct RClass *mrb_vm_define_class(mrb_state*, mrb_value, mrb_value, mrb_sym);
|
||||
struct RClass *mrb_vm_define_module(mrb_state*, mrb_value, mrb_sym);
|
||||
mrb_value mrb_instance_new(mrb_state *mrb, mrb_value cv);
|
||||
void mrb_class_name_class(mrb_state*, struct RClass*, struct RClass*, mrb_sym);
|
||||
mrb_bool mrb_const_name_p(mrb_state*, const char*, mrb_int);
|
||||
mrb_value mrb_class_find_path(mrb_state*, struct RClass*);
|
||||
mrb_value mrb_mod_to_s(mrb_state *, mrb_value);
|
||||
void mrb_method_added(mrb_state *mrb, struct RClass *c, mrb_sym mid);
|
||||
#endif
|
||||
|
||||
/* debug */
|
||||
size_t mrb_packed_int_len(uint32_t num);
|
||||
size_t mrb_packed_int_encode(uint32_t num, uint8_t *p, uint8_t *pend);
|
||||
uint32_t mrb_packed_int_decode(const uint8_t *p, const uint8_t **newpos);
|
||||
|
||||
/* dump */
|
||||
#ifdef MRUBY_IREP_H
|
||||
int mrb_dump_irep(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size);
|
||||
#ifndef MRB_NO_STDIO
|
||||
int mrb_dump_irep_binary(mrb_state*, const mrb_irep*, uint8_t, FILE*);
|
||||
int mrb_dump_irep_cfunc(mrb_state *mrb, const mrb_irep*, uint8_t flags, FILE *f, const char *initname);
|
||||
int mrb_dump_irep_cstruct(mrb_state *mrb, const mrb_irep*, uint8_t flags, FILE *f, const char *initname);
|
||||
mrb_irep *mrb_read_irep_file(mrb_state*, FILE*);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* error */
|
||||
mrb_value mrb_exc_inspect(mrb_state *mrb, mrb_value exc);
|
||||
mrb_value mrb_exc_backtrace(mrb_state *mrb, mrb_value exc);
|
||||
mrb_value mrb_get_backtrace(mrb_state *mrb);
|
||||
void mrb_exc_mesg_set(mrb_state *mrb, struct RException *exc, mrb_value mesg);
|
||||
mrb_value mrb_exc_mesg_get(mrb_state *mrb, struct RException *exc);
|
||||
|
||||
/* gc */
|
||||
void mrb_gc_mark_mt(mrb_state*, struct RClass*);
|
||||
size_t mrb_gc_mark_mt_size(mrb_state*, struct RClass*);
|
||||
void mrb_gc_free_mt(mrb_state*, struct RClass*);
|
||||
|
||||
/* hash */
|
||||
size_t mrb_hash_memsize(mrb_value obj);
|
||||
void mrb_gc_mark_hash(mrb_state*, struct RHash*);
|
||||
size_t mrb_gc_mark_hash_size(mrb_state*, struct RHash*);
|
||||
void mrb_gc_free_hash(mrb_state*, struct RHash*);
|
||||
|
||||
/* irep */
|
||||
struct mrb_insn_data mrb_decode_insn(const mrb_code *pc);
|
||||
#ifdef MRUBY_IREP_H
|
||||
void mrb_irep_free(mrb_state*, struct mrb_irep*);
|
||||
void mrb_irep_incref(mrb_state*, struct mrb_irep*);
|
||||
void mrb_irep_decref(mrb_state*, struct mrb_irep*);
|
||||
void mrb_irep_cutref(mrb_state*, struct mrb_irep*);
|
||||
void mrb_irep_remove_lv(mrb_state *mrb, mrb_irep *irep);
|
||||
|
||||
static inline const struct mrb_irep_catch_handler *
|
||||
mrb_irep_catch_handler_table(const struct mrb_irep *irep)
|
||||
{
|
||||
if (irep->clen > 0) {
|
||||
return (const struct mrb_irep_catch_handler*)(irep->iseq + irep->ilen);
|
||||
}
|
||||
else {
|
||||
return (const struct mrb_irep_catch_handler*)NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* numeric */
|
||||
mrb_int mrb_div_int(mrb_state *mrb, mrb_int x, mrb_int y);
|
||||
mrb_value mrb_int_add(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
mrb_value mrb_int_sub(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
mrb_value mrb_int_mul(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
void mrb_int_zerodiv(mrb_state *mrb);
|
||||
void mrb_int_overflow(mrb_state *mrb, const char *reason);
|
||||
|
||||
#ifdef MRB_USE_COMPLEX
|
||||
mrb_value mrb_complex_new(mrb_state *mrb, mrb_float x, mrb_float y);
|
||||
mrb_value mrb_complex_add(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
mrb_value mrb_complex_sub(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
mrb_value mrb_complex_mul(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
mrb_value mrb_complex_div(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
#endif
|
||||
#ifdef MRB_USE_RATIONAL
|
||||
mrb_value mrb_rational_new(mrb_state *mrb, mrb_int x, mrb_int y);
|
||||
mrb_value mrb_rational_add(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
mrb_value mrb_rational_sub(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
mrb_value mrb_rational_mul(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
mrb_value mrb_rational_div(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
#endif
|
||||
|
||||
#ifdef MRUBY_PROC_H
|
||||
struct RProc *mrb_proc_new(mrb_state*, const mrb_irep*);
|
||||
struct RProc *mrb_closure_new(mrb_state*, const mrb_irep*);
|
||||
void mrb_proc_copy(mrb_state *mrb, struct RProc *a, struct RProc *b);
|
||||
mrb_int mrb_proc_arity(const struct RProc *p);
|
||||
#endif
|
||||
|
||||
/* range */
|
||||
#ifdef MRUBY_RANGE_H
|
||||
mrb_value mrb_get_values_at(mrb_state *mrb, mrb_value obj, mrb_int olen, mrb_int argc, const mrb_value *argv, mrb_value (*func)(mrb_state*, mrb_value, mrb_int));
|
||||
void mrb_gc_mark_range(mrb_state *mrb, struct RRange *r);
|
||||
#endif
|
||||
|
||||
/* string */
|
||||
void mrb_gc_free_str(mrb_state*, struct RString*);
|
||||
uint32_t mrb_str_hash(mrb_state *mrb, mrb_value str);
|
||||
mrb_value mrb_str_dump(mrb_state *mrb, mrb_value str);
|
||||
mrb_value mrb_str_inspect(mrb_state *mrb, mrb_value str);
|
||||
mrb_bool mrb_str_beg_len(mrb_int str_len, mrb_int *begp, mrb_int *lenp);
|
||||
mrb_value mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len);
|
||||
mrb_value mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value idx, mrb_value len);
|
||||
|
||||
#ifdef MRB_UTF8_STRING
|
||||
mrb_int mrb_utf8len(const char *str, const char *end);
|
||||
mrb_int mrb_utf8_strlen(const char *str, mrb_int byte_len);
|
||||
#endif
|
||||
|
||||
/* variable */
|
||||
mrb_value mrb_vm_special_get(mrb_state*, mrb_sym);
|
||||
void mrb_vm_special_set(mrb_state*, mrb_sym, mrb_value);
|
||||
mrb_value mrb_vm_cv_get(mrb_state*, mrb_sym);
|
||||
void mrb_vm_cv_set(mrb_state*, mrb_sym, mrb_value);
|
||||
mrb_value mrb_vm_const_get(mrb_state*, mrb_sym);
|
||||
void mrb_vm_const_set(mrb_state*, mrb_sym, mrb_value);
|
||||
size_t mrb_obj_iv_tbl_memsize(mrb_value);
|
||||
mrb_value mrb_obj_iv_inspect(mrb_state*, struct RObject*);
|
||||
void mrb_obj_iv_set_force(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v);
|
||||
mrb_value mrb_mod_constants(mrb_state *mrb, mrb_value mod);
|
||||
mrb_value mrb_f_global_variables(mrb_state *mrb, mrb_value self);
|
||||
mrb_value mrb_obj_instance_variables(mrb_state*, mrb_value);
|
||||
mrb_value mrb_mod_class_variables(mrb_state*, mrb_value);
|
||||
mrb_value mrb_mod_cv_get(mrb_state *mrb, struct RClass * c, mrb_sym sym);
|
||||
mrb_bool mrb_mod_cv_defined(mrb_state *mrb, struct RClass * c, mrb_sym sym);
|
||||
mrb_bool mrb_ident_p(const char *s, mrb_int len);
|
||||
|
||||
/* GC functions */
|
||||
void mrb_gc_mark_gv(mrb_state*);
|
||||
void mrb_gc_free_gv(mrb_state*);
|
||||
void mrb_gc_mark_iv(mrb_state*, struct RObject*);
|
||||
size_t mrb_gc_mark_iv_size(mrb_state*, struct RObject*);
|
||||
void mrb_gc_free_iv(mrb_state*, struct RObject*);
|
||||
|
||||
/* VM */
|
||||
mrb_int mrb_ci_bidx(mrb_callinfo *ci);
|
||||
|
||||
#ifdef MRB_USE_BIGINT
|
||||
mrb_value mrb_bint_new_int(mrb_state *mrb, mrb_int x);
|
||||
mrb_value mrb_bint_new_str(mrb_state *mrb, const char *x, mrb_int len, mrb_int base);
|
||||
mrb_value mrb_as_bint(mrb_state *mrb, mrb_value x);
|
||||
mrb_value mrb_bint_add(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
mrb_value mrb_bint_sub(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
mrb_value mrb_bint_mul(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
mrb_value mrb_bint_div(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
mrb_value mrb_bint_divmod(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
mrb_value mrb_bint_add_ii(mrb_state *mrb, mrb_int x, mrb_int y);
|
||||
mrb_value mrb_bint_sub_ii(mrb_state *mrb, mrb_int x, mrb_int y);
|
||||
mrb_value mrb_bint_mul_ii(mrb_state *mrb, mrb_int x, mrb_int y);
|
||||
mrb_value mrb_bint_div_ii(mrb_state *mrb, mrb_int x, mrb_int y);
|
||||
mrb_value mrb_bint_mod(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
mrb_value mrb_bint_rem(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
mrb_value mrb_bint_pow(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
mrb_value mrb_bint_powm(mrb_state *mrb, mrb_value x, mrb_int y, mrb_value z);
|
||||
mrb_value mrb_bint_and(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
mrb_value mrb_bint_or(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
mrb_value mrb_bint_xor(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
mrb_value mrb_bint_rev(mrb_state *mrb, mrb_value x);
|
||||
mrb_value mrb_bint_lshift(mrb_state *mrb, mrb_value x, mrb_int width);
|
||||
mrb_value mrb_bint_rshift(mrb_state *mrb, mrb_value x, mrb_int width);
|
||||
mrb_value mrb_bint_to_s(mrb_state *mrb, mrb_value x, mrb_int base);
|
||||
#ifndef MRB_NO_FLOAT
|
||||
mrb_value mrb_bint_new_float(mrb_state *mrb, mrb_float x);
|
||||
mrb_float mrb_bint_as_float(mrb_state *mrb, mrb_value x);
|
||||
#endif
|
||||
mrb_int mrb_bint_as_int(mrb_state *mrb, mrb_value x);
|
||||
mrb_int mrb_bint_cmp(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
void mrb_gc_free_bint(mrb_state *mrb, struct RBasic *x);
|
||||
#endif
|
||||
|
||||
#endif /* MRUBY_INTERNAL_H */
|
||||
+2
-21
@@ -99,7 +99,7 @@ MRB_API mrb_value mrb_load_irep(mrb_state*, const uint8_t*);
|
||||
|
||||
/*
|
||||
* @param [const void*] irep code
|
||||
* @param [size_t] size of irep buffer. If -1 is given, it is considered unrestricted.
|
||||
* @param [size_t] size of irep buffer.
|
||||
*/
|
||||
MRB_API mrb_value mrb_load_irep_buf(mrb_state*, const void*, size_t);
|
||||
|
||||
@@ -108,16 +108,10 @@ MRB_API mrb_value mrb_load_irep_cxt(mrb_state*, const uint8_t*, mrbc_context*);
|
||||
|
||||
/*
|
||||
* @param [const void*] irep code
|
||||
* @param [size_t] size of irep buffer. If -1 is given, it is considered unrestricted.
|
||||
* @param [size_t] size of irep buffer.
|
||||
*/
|
||||
MRB_API mrb_value mrb_load_irep_buf_cxt(mrb_state*, const void*, size_t, mrbc_context*);
|
||||
|
||||
void mrb_irep_free(mrb_state*, struct mrb_irep*);
|
||||
void mrb_irep_incref(mrb_state*, struct mrb_irep*);
|
||||
void mrb_irep_decref(mrb_state*, struct mrb_irep*);
|
||||
void mrb_irep_cutref(mrb_state*, struct mrb_irep*);
|
||||
void mrb_irep_remove_lv(mrb_state *mrb, mrb_irep *irep);
|
||||
|
||||
struct mrb_insn_data {
|
||||
uint8_t insn;
|
||||
uint16_t a;
|
||||
@@ -126,19 +120,6 @@ struct mrb_insn_data {
|
||||
const mrb_code *addr;
|
||||
};
|
||||
|
||||
struct mrb_insn_data mrb_decode_insn(const mrb_code *pc);
|
||||
|
||||
static inline const struct mrb_irep_catch_handler *
|
||||
mrb_irep_catch_handler_table(const struct mrb_irep *irep)
|
||||
{
|
||||
if (irep->clen > 0) {
|
||||
return (const struct mrb_irep_catch_handler*)(irep->iseq + irep->ilen);
|
||||
}
|
||||
else {
|
||||
return (const struct mrb_irep_catch_handler*)NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#define mrb_irep_catch_handler_pack(n, v) uint32_to_bin(n, v)
|
||||
#define mrb_irep_catch_handler_unpack(v) bin_to_uint32(v)
|
||||
|
||||
|
||||
@@ -30,16 +30,17 @@ MRB_BEGIN_DECL
|
||||
#endif
|
||||
#endif
|
||||
|
||||
MRB_API mrb_value mrb_num_plus(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
MRB_API mrb_value mrb_num_minus(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
/* utility functions */
|
||||
MRB_API mrb_value mrb_num_add(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
MRB_API mrb_value mrb_num_sub(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
MRB_API mrb_value mrb_num_mul(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
/* obsolete old names */
|
||||
#define mrb_num_plus(mrb, x, y) mrb_num_add(mrb, x, y)
|
||||
#define mrb_num_minus(mrb, x, y) mrb_num_sub(mrb, x, y)
|
||||
|
||||
MRB_API mrb_value mrb_integer_to_str(mrb_state *mrb, mrb_value x, mrb_int base);
|
||||
MRB_API char *mrb_int_to_cstr(char *buf, size_t len, mrb_int n, mrb_int base);
|
||||
|
||||
/* internal function(s) */
|
||||
mrb_int mrb_div_int(mrb_state *mrb, mrb_int x, mrb_int y);
|
||||
|
||||
/* obsolete function(s); will be removed */
|
||||
#define mrb_fixnum_to_str(mrb, x, base) mrb_integer_to_str(mrb, x, base)
|
||||
|
||||
@@ -166,10 +167,6 @@ mrb_float mrb_div_float(mrb_float x, mrb_float y);
|
||||
mrb_value mrb_float_to_str(mrb_state *mrb, mrb_value x, const char *fmt);
|
||||
int mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, char sign);
|
||||
|
||||
/* obsolete functions; will be removed */
|
||||
#define mrb_flo_to_fixnum(mrb, val) mrb_float_to_integer(mrb, val)
|
||||
#define mrb_to_flo(mrb, x) mrb_as_float(mrb, x)
|
||||
|
||||
#endif /* MRB_NO_FLOAT */
|
||||
|
||||
MRB_END_DECL
|
||||
|
||||
@@ -88,12 +88,8 @@ struct RProc {
|
||||
|
||||
#define mrb_proc_ptr(v) ((struct RProc*)(mrb_ptr(v)))
|
||||
|
||||
struct RProc *mrb_proc_new(mrb_state*, const mrb_irep*);
|
||||
struct RProc *mrb_closure_new(mrb_state*, const mrb_irep*);
|
||||
MRB_API struct RProc *mrb_proc_new_cfunc(mrb_state*, mrb_func_t);
|
||||
MRB_API struct RProc *mrb_closure_new_cfunc(mrb_state *mrb, mrb_func_t func, int nlocals);
|
||||
void mrb_proc_copy(mrb_state *mrb, struct RProc *a, struct RProc *b);
|
||||
mrb_int mrb_proc_arity(const struct RProc *p);
|
||||
|
||||
/* following functions are defined in mruby-proc-ext so please include it when using */
|
||||
MRB_API struct RProc *mrb_proc_new_cfunc_with_env(mrb_state *mrb, mrb_func_t func, mrb_int argc, const mrb_value *argv);
|
||||
|
||||
@@ -71,8 +71,6 @@ enum mrb_range_beg_len {
|
||||
};
|
||||
|
||||
MRB_API enum mrb_range_beg_len mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc);
|
||||
mrb_value mrb_get_values_at(mrb_state *mrb, mrb_value obj, mrb_int olen, mrb_int argc, const mrb_value *argv, mrb_value (*func)(mrb_state*, mrb_value, mrb_int));
|
||||
void mrb_gc_mark_range(mrb_state *mrb, struct RRange *r);
|
||||
|
||||
MRB_END_DECL
|
||||
|
||||
|
||||
+5
-22
@@ -102,7 +102,6 @@ struct RStringEmbed {
|
||||
#define RSTRING_LEN(s) RSTR_LEN(RSTRING(s))
|
||||
#define RSTRING_CAPA(s) RSTR_CAPA(RSTRING(s))
|
||||
#define RSTRING_END(s) (RSTRING_PTR(s) + RSTRING_LEN(s))
|
||||
MRB_API mrb_int mrb_str_strlen(mrb_state*, struct RString*);
|
||||
#define RSTRING_CSTR(mrb,s) mrb_string_cstr(mrb, s)
|
||||
|
||||
#define MRB_STR_SHARED 1
|
||||
@@ -115,8 +114,6 @@ MRB_API mrb_int mrb_str_strlen(mrb_state*, struct RString*);
|
||||
#define MRB_STR_EMBED_LEN_MASK (((1 << MRB_STR_EMBED_LEN_BIT) - 1) << MRB_STR_EMBED_LEN_SHIFT)
|
||||
#define MRB_STR_TYPE_MASK 15
|
||||
|
||||
void mrb_gc_free_str(mrb_state*, struct RString*);
|
||||
|
||||
MRB_API void mrb_str_modify(mrb_state *mrb, struct RString *s);
|
||||
/* mrb_str_modify() with keeping ASCII flag if set */
|
||||
MRB_API void mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s);
|
||||
@@ -324,7 +321,7 @@ MRB_API mrb_value mrb_str_resize(mrb_state *mrb, mrb_value str, mrb_int len);
|
||||
*/
|
||||
MRB_API mrb_value mrb_str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len);
|
||||
|
||||
MRB_API mrb_value mrb_str_new_capa(mrb_state *mrb, size_t capa);
|
||||
MRB_API mrb_value mrb_str_new_capa(mrb_state *mrb, mrb_int capa);
|
||||
#define mrb_str_buf_new(mrb, capa) mrb_str_new_capa(mrb, (capa))
|
||||
|
||||
/* NULL terminated C string from mrb_value */
|
||||
@@ -332,9 +329,11 @@ MRB_API const char *mrb_string_cstr(mrb_state *mrb, mrb_value str);
|
||||
/* NULL terminated C string from mrb_value; `str` will be updated */
|
||||
MRB_API const char *mrb_string_value_cstr(mrb_state *mrb, mrb_value *str);
|
||||
/* obsolete: use RSTRING_PTR() */
|
||||
MRB_API const char *mrb_string_value_ptr(mrb_state *mrb, mrb_value str);
|
||||
#define mrb_string_value_ptr(mrb, str) RSTRING_PTR(str)
|
||||
/* obsolete: use RSTRING_LEN() */
|
||||
MRB_API mrb_int mrb_string_value_len(mrb_state *mrb, mrb_value str);
|
||||
#define mrb_string_value_len(mrb, str) RSTRING_LEN(str)
|
||||
/* obsolete: substituted by a macro; shall be removed */
|
||||
#define mrb_str_strlen(mrb, s) strlen(RSTR_PTR(s))
|
||||
|
||||
/**
|
||||
* Duplicates a string object.
|
||||
@@ -422,27 +421,11 @@ MRB_API int mrb_str_cmp(mrb_state *mrb, mrb_value str1, mrb_value str2);
|
||||
*/
|
||||
MRB_API char *mrb_str_to_cstr(mrb_state *mrb, mrb_value str);
|
||||
|
||||
uint32_t mrb_str_hash(mrb_state *mrb, mrb_value str);
|
||||
mrb_value mrb_str_dump(mrb_state *mrb, mrb_value str);
|
||||
|
||||
/**
|
||||
* Returns a printable version of str, surrounded by quote marks, with special characters escaped.
|
||||
*/
|
||||
mrb_value mrb_str_inspect(mrb_state *mrb, mrb_value str);
|
||||
|
||||
/* For backward compatibility */
|
||||
#define mrb_str_cat2(mrb, str, ptr) mrb_str_cat_cstr(mrb, str, ptr)
|
||||
#define mrb_str_buf_cat(mrb, str, ptr, len) mrb_str_cat(mrb, str, ptr, len)
|
||||
#define mrb_str_buf_append(mrb, str, str2) mrb_str_cat_str(mrb, str, str2)
|
||||
|
||||
mrb_bool mrb_str_beg_len(mrb_int str_len, mrb_int *begp, mrb_int *lenp);
|
||||
mrb_value mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len);
|
||||
|
||||
#ifdef MRB_UTF8_STRING
|
||||
mrb_int mrb_utf8len(const char *str, const char *end);
|
||||
mrb_int mrb_utf8_strlen(const char *str, mrb_int byte_len);
|
||||
#endif
|
||||
|
||||
MRB_END_DECL
|
||||
|
||||
#endif /* MRUBY_STRING_H */
|
||||
|
||||
@@ -154,7 +154,8 @@ static const unsigned int IEEE754_INFINITY_BITS_SINGLE = 0x7F800000;
|
||||
f(MRB_TT_ISTRUCT, struct RIStruct, "istruct") \
|
||||
f(MRB_TT_BREAK, struct RBreak, "break") \
|
||||
f(MRB_TT_COMPLEX, struct RComplex, "Complex") \
|
||||
f(MRB_TT_RATIONAL, struct RRational, "Rational")
|
||||
f(MRB_TT_RATIONAL, struct RRational, "Rational") \
|
||||
f(MRB_TT_BIGINT, struct RBigint, "Integer")
|
||||
|
||||
enum mrb_vtype {
|
||||
#define MRB_VTYPE_DEFINE(tt, type, name) tt,
|
||||
@@ -300,6 +301,9 @@ struct RCptr {
|
||||
#define mrb_bool(o) (mrb_type(o) != MRB_TT_FALSE)
|
||||
#endif
|
||||
#define mrb_test(o) mrb_bool(o)
|
||||
#ifndef mrb_bigint_p
|
||||
#define mrb_bigint_p(o) (mrb_type(o) == MRB_TT_BIGINT)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Returns a float in Ruby.
|
||||
|
||||
@@ -14,13 +14,6 @@
|
||||
*/
|
||||
MRB_BEGIN_DECL
|
||||
|
||||
mrb_value mrb_vm_special_get(mrb_state*, mrb_sym);
|
||||
void mrb_vm_special_set(mrb_state*, mrb_sym, mrb_value);
|
||||
mrb_value mrb_vm_cv_get(mrb_state*, mrb_sym);
|
||||
void mrb_vm_cv_set(mrb_state*, mrb_sym, mrb_value);
|
||||
mrb_value mrb_vm_const_get(mrb_state*, mrb_sym);
|
||||
void mrb_vm_const_set(mrb_state*, mrb_sym, mrb_value);
|
||||
size_t mrb_obj_iv_tbl_memsize(mrb_value);
|
||||
MRB_API mrb_value mrb_const_get(mrb_state*, mrb_value, mrb_sym);
|
||||
MRB_API void mrb_const_set(mrb_state*, mrb_value, mrb_sym, mrb_value);
|
||||
MRB_API mrb_bool mrb_const_defined(mrb_state*, mrb_value, mrb_sym);
|
||||
@@ -99,22 +92,6 @@ MRB_API mrb_value mrb_cv_get(mrb_state *mrb, mrb_value mod, mrb_sym sym);
|
||||
MRB_API void mrb_mod_cv_set(mrb_state *mrb, struct RClass * c, mrb_sym sym, mrb_value v);
|
||||
MRB_API void mrb_cv_set(mrb_state *mrb, mrb_value mod, mrb_sym sym, mrb_value v);
|
||||
MRB_API mrb_bool mrb_cv_defined(mrb_state *mrb, mrb_value mod, mrb_sym sym);
|
||||
mrb_value mrb_obj_iv_inspect(mrb_state*, struct RObject*);
|
||||
void mrb_obj_iv_set_force(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v);
|
||||
mrb_value mrb_mod_constants(mrb_state *mrb, mrb_value mod);
|
||||
mrb_value mrb_f_global_variables(mrb_state *mrb, mrb_value self);
|
||||
mrb_value mrb_obj_instance_variables(mrb_state*, mrb_value);
|
||||
mrb_value mrb_mod_class_variables(mrb_state*, mrb_value);
|
||||
mrb_value mrb_mod_cv_get(mrb_state *mrb, struct RClass * c, mrb_sym sym);
|
||||
mrb_bool mrb_mod_cv_defined(mrb_state *mrb, struct RClass * c, mrb_sym sym);
|
||||
mrb_bool mrb_ident_p(const char *s, mrb_int len);
|
||||
|
||||
/* GC functions */
|
||||
void mrb_gc_mark_gv(mrb_state*);
|
||||
void mrb_gc_free_gv(mrb_state*);
|
||||
void mrb_gc_mark_iv(mrb_state*, struct RObject*);
|
||||
size_t mrb_gc_mark_iv_size(mrb_state*, struct RObject*);
|
||||
void mrb_gc_free_iv(mrb_state*, struct RObject*);
|
||||
|
||||
/* return non zero to break the loop */
|
||||
typedef int (mrb_iv_foreach_func)(mrb_state*,mrb_sym,mrb_value,void*);
|
||||
|
||||
+11
-1
@@ -123,6 +123,7 @@ module MRuby
|
||||
@enable_test = false
|
||||
@enable_lock = true
|
||||
@enable_presym = true
|
||||
@enable_benchmark = true
|
||||
@mrbcfile_external = false
|
||||
@internal = internal
|
||||
@toolchains = []
|
||||
@@ -232,6 +233,14 @@ module MRuby
|
||||
@cxx_abi_enabled = true
|
||||
end
|
||||
|
||||
def benchmark_enabled?
|
||||
@enable_benchmark
|
||||
end
|
||||
|
||||
def disable_benchmark
|
||||
@enable_benchmark = false
|
||||
end
|
||||
|
||||
def compile_as_cxx(src, cxx_src = nil, obj = nil, includes = [])
|
||||
#
|
||||
# If `cxx_src` is specified, this method behaves the same as before as
|
||||
@@ -491,7 +500,8 @@ EOS
|
||||
v = instance_variable_get(n)
|
||||
v = case v
|
||||
when nil, true, false, Numeric; v
|
||||
when String, Command; v.clone
|
||||
when String; v.clone
|
||||
when Command; v.clone.tap { |u| u.build = build }
|
||||
else Marshal.load(Marshal.dump(v)) # deep clone
|
||||
end
|
||||
build.instance_variable_set(n, v)
|
||||
|
||||
+324
-82
@@ -1,5 +1,8 @@
|
||||
require 'yaml'
|
||||
|
||||
module MRuby
|
||||
module LoadGems
|
||||
|
||||
def gembox(gemboxfile)
|
||||
gembox = File.expand_path("#{gemboxfile}.gembox", "#{MRUBY_ROOT}/mrbgems")
|
||||
fail "Can't find gembox '#{gembox}'" unless File.exist?(gembox)
|
||||
@@ -12,28 +15,30 @@ module MRuby
|
||||
GemBox.path = nil
|
||||
end
|
||||
|
||||
def gem(gemdir, &block)
|
||||
if gemdir.is_a?(Hash)
|
||||
gemdir = load_special_path_gem(gemdir)
|
||||
elsif GemBox.path
|
||||
gemdir = File.expand_path(gemdir, File.dirname(GemBox.path))
|
||||
else
|
||||
caller_dir = File.expand_path(File.dirname(caller(1,1)[0][/^(.*?):\d/,1]))
|
||||
if caller_dir == "#{MRUBY_ROOT}/build_config"
|
||||
caller_dir = MRUBY_ROOT
|
||||
end
|
||||
gemdir = File.expand_path(gemdir, caller_dir)
|
||||
end
|
||||
def gem(gem_src, &block)
|
||||
|
||||
gemrake = File.join(gemdir, "mrbgem.rake")
|
||||
caller_dir = File.expand_path(File.dirname(caller(1,1)[0][/^(.*?):\d/,1]))
|
||||
|
||||
gem_src = {gemdir: gem_src} if gem_src.is_a? String
|
||||
|
||||
@gem_checkouts ||= {}
|
||||
checkout = GemLoader
|
||||
.new(self, caller_dir, @gem_checkouts, **gem_src)
|
||||
.fetch!
|
||||
return nil unless checkout
|
||||
@gem_checkouts[checkout.gemdir] = checkout
|
||||
|
||||
# Load the gem's rakefile
|
||||
gemrake = File.join(checkout.gemdir, "mrbgem.rake")
|
||||
fail "Can't find #{gemrake}" unless File.exist?(gemrake)
|
||||
|
||||
Gem.current = nil
|
||||
load gemrake
|
||||
return nil unless Gem.current
|
||||
current = Gem.current
|
||||
|
||||
current.dir = gemdir
|
||||
# Add it to gems
|
||||
current.dir = checkout.gemdir
|
||||
current.build = self.is_a?(MRuby::Build) ? self : MRuby::Build.current
|
||||
current.build_config_initializer = block
|
||||
gems << current
|
||||
@@ -44,92 +49,329 @@ module MRuby
|
||||
current
|
||||
end
|
||||
|
||||
def load_special_path_gem(params)
|
||||
if params[:github]
|
||||
params[:git] = "https://github.com/#{params[:github]}.git"
|
||||
elsif params[:bitbucket]
|
||||
if params[:method] == "ssh"
|
||||
params[:git] = "git@bitbucket.org:#{params[:bitbucket]}.git"
|
||||
else
|
||||
params[:git] = "https://bitbucket.org/#{params[:bitbucket]}.git"
|
||||
end
|
||||
elsif params[:mgem]
|
||||
mgem_list_dir = "#{gem_clone_dir}/mgem-list"
|
||||
mgem_list_url = 'https://github.com/mruby/mgem-list.git'
|
||||
if File.exist? mgem_list_dir
|
||||
git.run_pull mgem_list_dir, mgem_list_url if $pull_gems
|
||||
else
|
||||
mkdir_p mgem_list_dir
|
||||
git.run_clone mgem_list_dir, mgem_list_url, "--depth 1"
|
||||
end
|
||||
|
||||
require 'yaml'
|
||||
# Class to represent the relationship between a gem dependency and
|
||||
# its remote repository (if any).
|
||||
class GemCheckout
|
||||
attr_reader :gemdir, :repo, :branch, :commit
|
||||
|
||||
conf_path = "#{mgem_list_dir}/#{params[:mgem]}.gem"
|
||||
conf_path = "#{mgem_list_dir}/mruby-#{params[:mgem]}.gem" unless File.exist? conf_path
|
||||
fail "mgem not found: #{params[:mgem]}" unless File.exist? conf_path
|
||||
conf = YAML.load File.read conf_path
|
||||
def initialize(gemdir, repo, branch, commit, canonical)
|
||||
@gemdir = gemdir # Working copy of the gem
|
||||
|
||||
fail "unknown mgem protocol: #{conf['protocol']}" if conf['protocol'] != 'git'
|
||||
params[:git] = conf['repository']
|
||||
params[:branch] = conf['branch'] if conf['branch']
|
||||
@repo = repo # Remote gem repo
|
||||
@branch = branch # Branch to check out
|
||||
@commit = commit # Commit-id to use
|
||||
|
||||
@canonical = canonical # This is the One True checkout
|
||||
end
|
||||
|
||||
if params[:core]
|
||||
gemdir = "#{root}/mrbgems/#{params[:core]}"
|
||||
elsif params[:git]
|
||||
url = params[:git]
|
||||
gemdir = "#{gem_clone_dir}/#{url.match(/([-\w]+)(\.[-\w]+|)$/).to_a[1]}"
|
||||
def canonical?() return @canonical; end
|
||||
def git?() return !!@repo; end
|
||||
def gemname() return File.basename(@gemdir); end
|
||||
|
||||
# by default the 'master' branch is used
|
||||
branch = params[:branch] ? params[:branch] : 'master'
|
||||
def hash()
|
||||
return [@gemdir, @repo, @branch, @commit, @canonical].hash
|
||||
end
|
||||
|
||||
lock = locks[url] if lock_enabled?
|
||||
def ==(other)
|
||||
return @gemdir == other.gemdir && @repo == other.repo &&
|
||||
@branch == other.branch && @commit == other.commit &&
|
||||
@canonical == other.canonical?
|
||||
end
|
||||
alias_method :eql?, :==
|
||||
|
||||
if File.exist?(gemdir)
|
||||
if $pull_gems
|
||||
# Jump to the top of the branch
|
||||
git.run_checkout gemdir, branch
|
||||
git.run_pull gemdir, url
|
||||
elsif params[:checksum_hash]
|
||||
git.run_checkout_detach gemdir, params[:checksum_hash]
|
||||
elsif lock
|
||||
git.run_checkout_detach gemdir, lock['commit']
|
||||
end
|
||||
def to_s
|
||||
desc = @gemdir
|
||||
desc += " -> #{@repo}/#{@branch}" if git?
|
||||
desc += "/#{commit}" if commit
|
||||
return desc
|
||||
end
|
||||
end
|
||||
|
||||
# Class to decode the argument set given to 'MRuby::Build::gem',
|
||||
# and git-clone+git-checkout the sources if needed.
|
||||
class GemLoader
|
||||
def initialize(build,
|
||||
build_config_dir, # Parent dir. of build_config
|
||||
gem_checkouts, # Hash of existing checkouts
|
||||
|
||||
# Git repo:
|
||||
git: nil,
|
||||
branch: "master",
|
||||
checksum_hash: nil,
|
||||
options: [],
|
||||
|
||||
# Git repo on GitHub
|
||||
github: nil,
|
||||
|
||||
# Git repo on BitBucket
|
||||
bitbucket: nil,
|
||||
method: nil,
|
||||
|
||||
# mgem entry
|
||||
mgem: nil,
|
||||
|
||||
# Core package
|
||||
core: nil,
|
||||
|
||||
# Path relative to the mruby checkout; probably wrong!
|
||||
path: nil,
|
||||
|
||||
# Local file(s)
|
||||
gemdir: nil,
|
||||
|
||||
# Related flags:
|
||||
canonical: false # Ignore subsequent checkout of this gem
|
||||
)
|
||||
@build = build
|
||||
@build_config_dir = build_config_dir
|
||||
@gem_checkouts = gem_checkouts
|
||||
@canonical = canonical
|
||||
|
||||
@git = git
|
||||
@branch = branch
|
||||
@checksum_hash = checksum_hash
|
||||
@options = options
|
||||
@canonical = canonical
|
||||
|
||||
@github = github
|
||||
|
||||
@bitbucket = bitbucket
|
||||
@method = method
|
||||
|
||||
@mgem = mgem
|
||||
@core = core
|
||||
@path = path
|
||||
@gemdir = gemdir
|
||||
|
||||
|
||||
actions = [git, github, bitbucket, mgem, core, path, gemdir]
|
||||
fail("Need to set exactly ONE of git, github, bitbucket, mgem, core, " +
|
||||
"path, or gemdir") unless actions.compact.size == 1
|
||||
end
|
||||
|
||||
# Retrieve the repo and return the details in a GemCheckout
|
||||
# object or nil if nothing needed to be done.
|
||||
def fetch!
|
||||
return fromGemdir! if @gemdir
|
||||
return fromCore! if @core
|
||||
return fromPath! if @path
|
||||
return fromGitHub! if @github
|
||||
return fromBitBucket! if @bitbucket
|
||||
|
||||
return fromMGem! if @mgem
|
||||
|
||||
return fromGit!(@git, @branch) if @git
|
||||
|
||||
# Shouldn't be reachable, but...
|
||||
fail "Invalid gem configuration!"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
#
|
||||
# Local Paths
|
||||
#
|
||||
|
||||
def fromGemdir!
|
||||
gem_src = @gemdir
|
||||
|
||||
# If @gemdir is a relative path, we first convert it to an
|
||||
# absolute path; this depends on circumstances.
|
||||
if MRuby::GemBox.path
|
||||
# If GemBox.path is set, it means that this fetch operation is
|
||||
# happening as part of a gembox evaluation and we use the
|
||||
# gembox's path as the starting point.
|
||||
gem_src = File.expand_path(gem_src, File.dirname(MRuby::GemBox.path))
|
||||
else
|
||||
options = [params[:options]] || []
|
||||
options << "--recursive"
|
||||
options << "--branch \"#{branch}\""
|
||||
options << "--depth 1" unless params[:checksum_hash] || lock
|
||||
mkdir_p "#{gem_clone_dir}"
|
||||
git.run_clone gemdir, url, options
|
||||
# Otherwise, we use the path to the build_config.rb file that
|
||||
# requested this gem. This path was extracted earlier and
|
||||
# stored in @build_config_dir via the second argument of
|
||||
# 'initialize'.
|
||||
root_dir = @build_config_dir
|
||||
|
||||
# Jump to the specified commit
|
||||
if params[:checksum_hash]
|
||||
git.run_checkout_detach gemdir, params[:checksum_hash]
|
||||
elsif lock
|
||||
git.run_checkout_detach gemdir, lock['commit']
|
||||
end
|
||||
# And we default to the repo root if the file is one of the
|
||||
# stock configs in build_config/.
|
||||
root_dir = MRUBY_ROOT if root_dir == "#{MRUBY_ROOT}/build_config"
|
||||
|
||||
gem_src = File.expand_path(gem_src, root_dir)
|
||||
end
|
||||
|
||||
if lock_enabled?
|
||||
@gem_dir_to_repo_url[gemdir] = url unless params[:path]
|
||||
locks[url] = {
|
||||
return GemCheckout.new(gem_src, nil, nil, nil, @canonical)
|
||||
end
|
||||
|
||||
def fromCore!
|
||||
return GemCheckout.new("#{@build.root}/mrbgems/#{@core}", nil, nil,
|
||||
nil, @canonical)
|
||||
end
|
||||
|
||||
# This is probably incorrect.
|
||||
#
|
||||
# According to doc/guides/mrbgems.md, this should specify a
|
||||
# subdirectory of a git checkout (i.e. for the case where the gem
|
||||
# itself is not in the repository's root.)
|
||||
#
|
||||
# However, the code treats this as simple path to a local
|
||||
# directory (just like :gemdir) with relative paths resolved
|
||||
# relative to the project root.
|
||||
#
|
||||
# I'm pretty sure that the correct thing is what guide says but
|
||||
# I'm going to keep the initial semantics for now.
|
||||
def fromPath!
|
||||
p = Pathname.new(@path).absolute? ? @path : "#{@build.root}/#{@path}"
|
||||
return GemCheckout.new(p, nil, nil, nil, @canonical)
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Git forges
|
||||
#
|
||||
|
||||
def fromGitHub!
|
||||
url = "https://github.com/#{@github}.git"
|
||||
return fromGit!(url, @branch)
|
||||
end
|
||||
|
||||
def fromBitBucket!
|
||||
if @method == "ssh"
|
||||
url = "git@bitbucket.org:#{@bitbucket}.git"
|
||||
else
|
||||
url = "https://bitbucket.org/#{@bitbucket}.git"
|
||||
end
|
||||
|
||||
return fromGit!(url, @branch)
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# mgem file
|
||||
#
|
||||
|
||||
def fromMGem!
|
||||
mgem = fetchMGem(@mgem)
|
||||
|
||||
url = mgem['repository']
|
||||
branch = mgem['branch'] || @branch
|
||||
|
||||
return fromGit!(url, branch)
|
||||
end
|
||||
|
||||
# Fetch the contents of the named mgem item. Will clone the
|
||||
# mgem-list repo if not present
|
||||
def fetchMGem(mgem)
|
||||
list_dir = "#{@build.gem_clone_dir}/mgem-list"
|
||||
url = 'https://github.com/mruby/mgem-list.git'
|
||||
|
||||
git_clone_dependency(url, list_dir, nil, 'master')
|
||||
|
||||
conf_path = "#{list_dir}/#{mgem}.gem"
|
||||
conf_path = "#{list_dir}/mruby-#{mgem}.gem" unless
|
||||
File.exist? conf_path
|
||||
fail "mgem not found: #{mgem}" unless File.exist? conf_path
|
||||
|
||||
conf = YAML.load File.read conf_path
|
||||
fail "unknown mgem protocol: #{conf['protocol']}" if
|
||||
conf['protocol'] != 'git'
|
||||
|
||||
return conf
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Git checkouts
|
||||
#
|
||||
|
||||
def fromGit!(url, branch)
|
||||
repo_dir = "#{@build.gem_clone_dir}/" +
|
||||
"#{url.match(/([-\w]+)(\.[-\w]+|)$/).to_a[1]}"
|
||||
commit = @checksum_hash
|
||||
|
||||
return nil if skip_this?(url, repo_dir, branch, commit)
|
||||
|
||||
# If there's a lockfile entry for this repo AND the user hasn't
|
||||
# specified a specific commit ID, we use the locked branch and
|
||||
# commit.
|
||||
lock = @build.locks[url] if @build.lock_enabled?
|
||||
if !commit && lock
|
||||
branch = lock['branch']
|
||||
commit = lock['commit']
|
||||
end
|
||||
|
||||
# Clone the dependency (if needed) and checkout the expected
|
||||
# revision.
|
||||
git_clone_dependency(url, repo_dir, commit, branch)
|
||||
git_checkout_dependency(repo_dir, commit, branch)
|
||||
|
||||
# Set the lockfile entry if enabled
|
||||
if @build.lock_enabled?
|
||||
@build.gem_dir_to_repo_url[repo_dir] = url
|
||||
@build.locks[url] = {
|
||||
'url' => url,
|
||||
'branch' => git.current_branch(gemdir),
|
||||
'commit' => git.commit_hash(gemdir),
|
||||
'branch' => @build.git.current_branch(repo_dir),
|
||||
'commit' => @build.git.commit_hash(repo_dir),
|
||||
}
|
||||
end
|
||||
|
||||
gemdir << "/#{params[:path]}" if params[:path]
|
||||
elsif params[:path]
|
||||
require 'pathname'
|
||||
gemdir = Pathname.new(params[:path]).absolute? ? params[:path] : "#{root}/#{params[:path]}"
|
||||
else
|
||||
fail "unknown gem option #{params}"
|
||||
return GemCheckout.new(repo_dir, url, branch, commit, @canonical)
|
||||
end
|
||||
|
||||
gemdir
|
||||
|
||||
# Test if this repo can be skipped. This will happen if it's
|
||||
# already in @gem_checkouts and EITHER it is identical (same
|
||||
# url, branch and commit-ID) as the current checkout OR it's
|
||||
# "canonical" flag is true. If it's in @gem_checkouts and
|
||||
# neither of these conditions is true, that's a fatal error; it
|
||||
# means there are multiple incompatible versions of this gem to
|
||||
# be checked out into this directory.
|
||||
#
|
||||
# Otherwise, returns false.
|
||||
def skip_this?(url, repo_dir, branch, commit)
|
||||
prev = @gem_checkouts[repo_dir]
|
||||
return false unless prev
|
||||
|
||||
# Canonical declarations must precede all others.
|
||||
fail("Attempted to re-declare #{prev.gemname} as canonical!\n" +
|
||||
"('canonical' can only be used on its first declaration.)") if
|
||||
prev && @canonical
|
||||
|
||||
# If prev is canonical, we can ignore this
|
||||
if prev.canonical?
|
||||
puts "Found canonical #{prev.gemname}; skipping this one."
|
||||
return true
|
||||
end
|
||||
|
||||
# If this checkout is identical to the current one, we can skip it.
|
||||
candidate = GemCheckout.new(repo_dir, url, branch, commit, @canonical)
|
||||
if prev == candidate
|
||||
puts "Found duplicate checkout for #{repo_dir}; ignoring."
|
||||
return true
|
||||
end
|
||||
|
||||
# Otherwise, we have a checkout conflict. This is an error.
|
||||
fail "Conflicting gem definitions for '#{repo_dir}':\n" +
|
||||
" #{candidate}\n" +
|
||||
" #{prev}\n"
|
||||
end
|
||||
|
||||
|
||||
# Retrieve a git repo if it's not present. Return
|
||||
# [path_to_checkout, did_clone]
|
||||
def git_clone_dependency(url, repo_dir, commit, branch)
|
||||
return if File.exist?(repo_dir)
|
||||
|
||||
FileUtils.mkdir_p repo_dir
|
||||
|
||||
options = @options.dup
|
||||
options << "--recursive"
|
||||
options << "--branch \"#{branch}\""
|
||||
options << "--depth 1" unless commit
|
||||
|
||||
@build.git.run_clone repo_dir, url, options
|
||||
end
|
||||
|
||||
def git_checkout_dependency(repo_dir, commit, branch)
|
||||
@build.git.run_checkout_detach(repo_dir, commit)
|
||||
end
|
||||
end
|
||||
|
||||
def enable_gems?
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <mruby/array.h>
|
||||
#include <mruby/range.h>
|
||||
#include <mruby/hash.h>
|
||||
#include <mruby/internal.h>
|
||||
#include <mruby/presym.h>
|
||||
|
||||
/*
|
||||
@@ -111,6 +112,8 @@ mrb_ary_values_at(mrb_state *mrb, mrb_value self)
|
||||
return mrb_get_values_at(mrb, self, RARRAY_LEN(self), argc, argv, ary_ref);
|
||||
}
|
||||
|
||||
mrb_value mrb_ary_delete_at(mrb_state *mrb, mrb_value self);
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* ary.slice!(index) -> obj or nil
|
||||
@@ -137,7 +140,6 @@ mrb_ary_slice_bang(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
struct RArray *a = mrb_ary_ptr(self);
|
||||
mrb_int i, j, k, len, alen;
|
||||
mrb_value val;
|
||||
mrb_value *ptr;
|
||||
mrb_value ary;
|
||||
|
||||
@@ -146,21 +148,13 @@ mrb_ary_slice_bang(mrb_state *mrb, mrb_value self)
|
||||
if (mrb_get_argc(mrb) == 1) {
|
||||
mrb_value index = mrb_get_arg1(mrb);
|
||||
|
||||
switch (mrb_type(index)) {
|
||||
case MRB_TT_RANGE:
|
||||
if (mrb_type(index) == MRB_TT_RANGE) {
|
||||
if (mrb_range_beg_len(mrb, index, &i, &len, ARY_LEN(a), TRUE) == MRB_RANGE_OK) {
|
||||
goto delete_pos_len;
|
||||
}
|
||||
else {
|
||||
return mrb_nil_value();
|
||||
}
|
||||
case MRB_TT_INTEGER:
|
||||
val = mrb_funcall_id(mrb, self, MRB_SYM(delete_at), 1, index);
|
||||
return val;
|
||||
default:
|
||||
val = mrb_funcall_id(mrb, self, MRB_SYM(delete_at), 1, index);
|
||||
return val;
|
||||
return mrb_nil_value();
|
||||
}
|
||||
return mrb_ary_delete_at(mrb, self);
|
||||
}
|
||||
|
||||
mrb_get_args(mrb, "ii", &i, &len);
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
# fgmp
|
||||
|
||||
FGMP is a public domain implementation of a subset of the GNU gmp library with the same API.
|
||||
|
||||
WELCOME TO FGMP.
|
||||
|
||||
FGMP is a public domain implementation of a subset of the GNU gmp library
|
||||
with the same API.
|
||||
|
||||
For instance, you can link the following trivial program with either
|
||||
this code, or libgmp.a and get the same results.
|
||||
|
||||
``` C
|
||||
#include <stdio.h>
|
||||
#include "gmp.h"
|
||||
main()
|
||||
{
|
||||
MP_INT a; MP_INT b; MP_INT c;
|
||||
|
||||
mpz_init_set_ui(&a,1); mpz_init_set_ui(&b,2); mpz_init(&c);
|
||||
mpz_add(&c,&a,&b);
|
||||
printf("\n%s\n", mpz_get_str(NULL,10,&c));
|
||||
}
|
||||
```
|
||||
|
||||
FGMP is really in the public domain. You can do whatever you want with
|
||||
it.
|
||||
|
||||
I wrote FGMP so that we would all have access to a (truly free)
|
||||
implementation of this subset of the API of GNU libgmp. I encourage
|
||||
everyone to distribute this as widely as possible.
|
||||
|
||||
If you need more documentation, I suggest you look at the file
|
||||
gmp.texi which is included with the GNU gmp library.
|
||||
|
||||
You can send me bug reports, implementations of missing functions, flames
|
||||
and rants by Email.
|
||||
|
||||
Any submissions of new code to be integrated into fgmp must also be
|
||||
placed in the public domain (For the particularly dense, you can
|
||||
release a new fgmp yourself under different licensing terms. This
|
||||
is a condition for including a submission in a release of FGMP that
|
||||
I personally prepare).
|
||||
|
||||
Mark Henderson <markh@wimsey.bc.ca>
|
||||
|
||||
# This is the fifth BETA release. 1.0b5
|
||||
|
||||
I hearby place this file and all of FGMP in the public domain.
|
||||
|
||||
Thanks to Paul Rouse <par@r-cube.demon.co.uk> for changes to get fgmp
|
||||
to work on a 286 MS-DOS compiler, the functions mpz_sqrt and
|
||||
mpz_sqrtrem, plus other general bug fixes.
|
||||
|
||||
Thanks also to Erick Gallesio <eg@kaolin.unice.fr> for a fix
|
||||
to mpz_init_set_str
|
||||
|
||||
Define B64 if your "long" type is 64 bits. Otherwise we assume 32
|
||||
bit longs. (The 64 bit version hasn't been tested enough)
|
||||
|
||||
```
|
||||
Platforms:
|
||||
Linux 0.99 (gcc)
|
||||
IBM RS6000/AIX 3.2 (IBM xlc compiler and gcc 2.3)
|
||||
Sun OS 4.1, Sun 3/4
|
||||
DEC Alpha OSF/1 (only lightly tested, 64 bit longs do make a difference,
|
||||
thanks to DEC for providing access via axposf.pa.dec.com). Define B64
|
||||
for this platform
|
||||
MS-DOS 286 C compiler (see credits above)
|
||||
```
|
||||
|
||||
# Some differences between gmp and fgmp
|
||||
|
||||
1. fgmp is considerably slower than gmp
|
||||
2. fgmp does not implement the following:
|
||||
all mpq_*
|
||||
internal mpn_* functions
|
||||
mpz_perfect_square_p
|
||||
mpz_inp_raw, mpz_out_raw
|
||||
mp_set_memory_functions, mpz_out_str, mpz_inp_str
|
||||
3. fgmp implements the following in addition to the routines in GNU gmp.
|
||||
`int mpz_jacobi(MP_INT *a, MP_INT *b)`
|
||||
- finds the jacobi symbol (a/b)
|
||||
4. mpz_sizeinbase often overestimates the exact value
|
||||
|
||||
5. To convert your gmp based program to fgmp (subject to the
|
||||
above)
|
||||
|
||||
- recompile your source. Make sure to include the gmp.h file included
|
||||
with fgmp rather than that included with gmp. (The point is to recompile
|
||||
all files which include gmp.h)
|
||||
- link with gmp.o instead of libgmp.a
|
||||
|
||||
Here's a complete sorted list of function implemented in fgmp:
|
||||
|
||||
```
|
||||
_mpz_realloc
|
||||
mpz_abs
|
||||
mpz_add
|
||||
mpz_add_ui
|
||||
mpz_and
|
||||
mpz_clear
|
||||
mpz_cmp
|
||||
mpz_cmp_si
|
||||
mpz_cmp_ui
|
||||
mpz_div
|
||||
mpz_div_2exp
|
||||
mpz_div_ui
|
||||
mpz_divmod
|
||||
mpz_divmod_ui
|
||||
mpz_fac_ui
|
||||
mpz_gcd
|
||||
mpz_gcdext
|
||||
mpz_get_si
|
||||
mpz_get_str
|
||||
mpz_get_ui
|
||||
mpz_init
|
||||
mpz_init_set
|
||||
mpz_init_set_si
|
||||
mpz_init_set_str
|
||||
mpz_init_set_ui
|
||||
mpz_jacobi
|
||||
mpz_mdiv
|
||||
mpz_mdiv_ui
|
||||
mpz_mdivmod
|
||||
mpz_mdivmod_ui
|
||||
mpz_mmod
|
||||
mpz_mmod_ui
|
||||
mpz_mod
|
||||
mpz_mod_2exp
|
||||
mpz_mod_ui
|
||||
mpz_mul
|
||||
mpz_mul_2exp
|
||||
mpz_mul_ui
|
||||
mpz_neg
|
||||
mpz_or
|
||||
mpz_pow_ui
|
||||
mpz_powm
|
||||
mpz_powm_ui
|
||||
mpz_probab_prime_p
|
||||
mpz_random
|
||||
mpz_random2
|
||||
mpz_set
|
||||
mpz_set_si
|
||||
mpz_set_str
|
||||
mpz_set_ui
|
||||
mpz_size
|
||||
mpz_sizeinbase
|
||||
mpz_sqrt
|
||||
mpz_sqrtrem
|
||||
mpz_sub
|
||||
mpz_sub_ui
|
||||
mpz_xor
|
||||
```
|
||||
@@ -0,0 +1,5 @@
|
||||
# Multi-precision Integer extension for mruby
|
||||
|
||||
This extension uses fgmp, which is a public domain implementation of a subset of the GNU gmp library by Mark Henderson <markh@wimsey.bc.ca>
|
||||
But it's heavily modified to fit with mruby. You can get the original source code from <https://github.com/deischi/fgmp.git>
|
||||
You can read the original README for fgmp in <README-fgmp.md>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
** @file mruby/bigint.h - Multi-precision, Integer
|
||||
**
|
||||
** See Copyright Notice in mruby.h
|
||||
*/
|
||||
|
||||
#ifndef MRUBY_BIGINT_H
|
||||
#define MRUBY_BIGINT_H
|
||||
/*
|
||||
* FREE GMP - a public domain implementation of a subset of the
|
||||
* gmp library
|
||||
*
|
||||
* I hearby place the file in the public domain.
|
||||
*
|
||||
* Do whatever you want with this code. Change it. Sell it. Claim you
|
||||
* wrote it.
|
||||
* Bugs, complaints, flames, rants: please send email to
|
||||
* Mark Henderson <markh@wimsey.bc.ca>
|
||||
* I'm already aware that fgmp is considerably slower than gmp
|
||||
*
|
||||
* CREDITS:
|
||||
* Paul Rouse <par@r-cube.demon.co.uk> - generic bug fixes, mpz_sqrt and
|
||||
* mpz_sqrtrem, and modifications to get fgmp to compile on a system
|
||||
* with int and long of different sizes (specifically MS-DOS,286 compiler)
|
||||
* Also see the file "notes" included with the fgmp distribution, for
|
||||
* more credits.
|
||||
*
|
||||
* VERSION 1.0 - beta 5
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#if defined(MRB_32BIT) && defined(MRB_INT32)
|
||||
/*
|
||||
* The values below are for 32 bit machines (i.e. machines with a
|
||||
* 32 bit long type)
|
||||
* You'll need to change them, if you're using something else
|
||||
* If DIGITBITS is odd, see the comment at the top of mpz_sqrtrem
|
||||
*/
|
||||
typedef int32_t mp_limb;
|
||||
typedef uint32_t mp_ulimb;
|
||||
#define LMAX 0x3fffffffL
|
||||
#define LC 0xc0000000L
|
||||
#define CMASK (LMAX+1)
|
||||
#define HLMAX 0x7fffL
|
||||
#define HCMASK (HLMAX + 1)
|
||||
#define HIGH(x) (((x) & 0x3fff8000L) >> 15)
|
||||
#define LOW(x) ((x) & 0x7fffL)
|
||||
|
||||
#else
|
||||
/* 64 bit long type */
|
||||
typedef int64_t mp_limb;
|
||||
typedef uint64_t mp_ulimb;
|
||||
#define LMAX 0x3fffffffffffffffLL
|
||||
#define LC 0xc000000000000000LL
|
||||
#define CMASK (LMAX+1)
|
||||
#define HLMAX 0x7fffffffLL
|
||||
#define HCMASK (HLMAX + 1)
|
||||
#define HIGH(x) (((x) & 0x3fffffff80000000LL) >> 31)
|
||||
#define LOW(x) ((x) & 0x7fffffffLL)
|
||||
#endif
|
||||
|
||||
typedef struct _mpz_t {
|
||||
mp_limb *p;
|
||||
short sn;
|
||||
size_t sz;
|
||||
} mpz_t;
|
||||
|
||||
struct RBigint {
|
||||
MRB_OBJECT_HEADER;
|
||||
mpz_t mp;
|
||||
};
|
||||
#define RBIGINT(v) ((struct RBigint*)mrb_ptr(v))
|
||||
|
||||
#define iabs(x) ((x>0) ? (x) : (-x))
|
||||
#define imax(x,y) ((x>y)?x:y)
|
||||
#define LONGBITS (sizeof(mp_limb)*8)
|
||||
#define DIGITBITS (LONGBITS-2)
|
||||
#define HALFDIGITBITS ((LONGBITS-2)/2)
|
||||
|
||||
#define hd(x,i) (((size_t)(i)>=2*((x)->sz))? 0:(((i)%2) ? HIGH((x)->p[(i)/2]) \
|
||||
: LOW((x)->p[(i)/2])))
|
||||
#define dg(x,i) (((size_t)(i) < (x)->sz) ? ((x)->p)[i] : 0)
|
||||
|
||||
#define RBIGINT(v) ((struct RBigint*)mrb_ptr(v))
|
||||
|
||||
#endif /* MRUBY_BIGINT_H */
|
||||
@@ -0,0 +1,10 @@
|
||||
MRuby::Gem::Specification.new('mruby-bigint') do |spec|
|
||||
spec.license = 'MIT'
|
||||
spec.author = 'mruby developers'
|
||||
spec.summary = 'Integer class extension to multiple-precision'
|
||||
spec.build.defines << "MRB_USE_BIGINT"
|
||||
|
||||
spec.build.libmruby_core_objs << Dir.glob(File.join(__dir__, "core/**/*.c")).map { |fn|
|
||||
objfile(fn.relative_path_from(__dir__).pathmap("#{spec.build_dir}/%X"))
|
||||
}
|
||||
end
|
||||
@@ -0,0 +1,23 @@
|
||||
assert 'Bigint basic' do
|
||||
n = 1<<65
|
||||
assert_equal 36893488147419103232, n
|
||||
assert_equal 36893488147419104229, n+997
|
||||
assert_equal 36893488147419102235, n-997
|
||||
assert_equal 36782807682976845922304, n*997
|
||||
assert_equal 37004501652376231, n.div(997)
|
||||
end
|
||||
|
||||
assert 'Bigint to_s' do
|
||||
n = 1197857166996989179607278372168909873645893814254642585755536286462800958278984531968
|
||||
assert_equal n, "11978_571669_96989179607278372168909873645893814254642585755536286462800958278984531968".to_i
|
||||
assert_equal(-n, "-11978_571669_96989179607278372168909873645893814254642585755536286462800958278984531968".to_i)
|
||||
n = 0x1197857166996989179607278372168909873645893814254642585755536286462800958278984531968
|
||||
assert_equal n, "1197857166996989179607278372168909873645893814254642585755536286462800958278984531968".to_i(16)
|
||||
end
|
||||
|
||||
assert 'Bigint pow' do
|
||||
n = 18446744073709551616
|
||||
assert_equal n, 2 ** 64
|
||||
assert_equal n, 1 << 64
|
||||
assert_equal 2, n >> 63
|
||||
end
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <mruby/class.h>
|
||||
#include <mruby/proc.h>
|
||||
#include <mruby/variable.h>
|
||||
#include <mruby/internal.h>
|
||||
#include "mrdberror.h"
|
||||
#include "apibreak.h"
|
||||
#include "apistring.h"
|
||||
@@ -20,8 +21,6 @@
|
||||
#define MRB_DEBUG_BP_FILE_OK (0x0001)
|
||||
#define MRB_DEBUG_BP_LINENO_OK (0x0002)
|
||||
|
||||
uint32_t mrb_packed_int_decode(uint8_t *p, uint8_t **newpos);
|
||||
|
||||
static uint16_t
|
||||
check_lineno(mrb_irep_debug_info_file *info_file, uint16_t lineno)
|
||||
{
|
||||
@@ -47,8 +46,8 @@ check_lineno(mrb_irep_debug_info_file *info_file, uint16_t lineno)
|
||||
|
||||
case mrb_debug_line_packed_map:
|
||||
{
|
||||
uint8_t *p = info_file->lines.packed_map;
|
||||
uint8_t *pend = p + count;
|
||||
const uint8_t *p = info_file->lines.packed_map;
|
||||
const uint8_t *pend = p + count;
|
||||
uint32_t line = 0;
|
||||
while (p < pend) {
|
||||
mrb_packed_int_decode(p, &p);
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <mruby/opcode.h>
|
||||
#include <mruby/variable.h>
|
||||
#include <mruby/proc.h>
|
||||
#include <mruby/internal.h>
|
||||
|
||||
#include "mrdb.h"
|
||||
#include "apibreak.h"
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <mruby/compile.h>
|
||||
#include <mruby/dump.h>
|
||||
#include <mruby/proc.h>
|
||||
#include <mruby/internal.h>
|
||||
|
||||
#define RITEBIN_EXT ".mrb"
|
||||
#define C_EXT ".c"
|
||||
@@ -25,7 +26,8 @@ struct mrbc_args {
|
||||
mrb_bool verbose : 1;
|
||||
mrb_bool remove_lv : 1;
|
||||
mrb_bool no_ext_ops : 1;
|
||||
uint8_t flags : 4;
|
||||
mrb_bool no_optimize : 1;
|
||||
uint8_t flags : 2;
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -42,6 +44,7 @@ usage(const char *name)
|
||||
"-s define <symbol> as static variable",
|
||||
"--remove-lv remove local variables",
|
||||
"--no-ext-ops prohibit using OP_EXTs",
|
||||
"--no-optimize disable peephole optimization",
|
||||
"--verbose run at verbose mode",
|
||||
"--version print the version",
|
||||
"--copyright print the copyright",
|
||||
@@ -169,6 +172,10 @@ parse_args(mrb_state *mrb, int argc, char **argv, struct mrbc_args *args)
|
||||
args->no_ext_ops = TRUE;
|
||||
break;
|
||||
}
|
||||
else if (strcmp(argv[i] + 2, "no-optimize") == 0) {
|
||||
args->no_optimize = TRUE;
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
default:
|
||||
return i;
|
||||
@@ -224,6 +231,7 @@ load_file(mrb_state *mrb, struct mrbc_args *args)
|
||||
c->dump_result = TRUE;
|
||||
c->no_exec = TRUE;
|
||||
c->no_ext_ops = args->no_ext_ops;
|
||||
c->no_optimize = args->no_optimize;
|
||||
if (input[0] == '-' && input[1] == '\0') {
|
||||
infile = stdin;
|
||||
}
|
||||
@@ -366,31 +374,3 @@ mrb_final_mrbgems(mrb_state *mrb)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MRB_USE_COMPLEX
|
||||
mrb_value mrb_complex_to_i(mrb_state *mrb, mrb_value comp)
|
||||
{
|
||||
/* dummy method */
|
||||
return mrb_nil_value();
|
||||
}
|
||||
mrb_value mrb_complex_to_f(mrb_state *mrb, mrb_value comp)
|
||||
{
|
||||
/* dummy method */
|
||||
return mrb_nil_value();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MRB_USE_RATIONAL
|
||||
mrb_value
|
||||
mrb_rational_to_i(mrb_state *mrb, mrb_value rat)
|
||||
{
|
||||
/* dummy method */
|
||||
return mrb_nil_value();
|
||||
}
|
||||
mrb_value
|
||||
mrb_rational_to_f(mrb_state *mrb, mrb_value rat)
|
||||
{
|
||||
/* dummy method */
|
||||
return mrb_nil_value();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
#include <mruby.h>
|
||||
|
||||
/*
|
||||
functions defined in mrbgems referenced from the core should be listed here
|
||||
to avoid link errors, since mrbc does not link any mrbgem ignoring configuration.
|
||||
*/
|
||||
|
||||
#ifdef MRB_USE_COMPLEX
|
||||
mrb_value mrb_complex_new(mrb_state *mrb, mrb_float x, mrb_float y)
|
||||
{
|
||||
return mrb_nil_value();
|
||||
}
|
||||
mrb_value mrb_complex_add(mrb_state *mrb, mrb_value x, mrb_value y)
|
||||
{
|
||||
return mrb_nil_value();
|
||||
}
|
||||
mrb_value mrb_complex_sub(mrb_state *mrb, mrb_value x, mrb_value y)
|
||||
{
|
||||
return mrb_nil_value();
|
||||
}
|
||||
mrb_value mrb_complex_mul(mrb_state *mrb, mrb_value x, mrb_value y)
|
||||
{
|
||||
return mrb_nil_value();
|
||||
}
|
||||
mrb_value mrb_complex_div(mrb_state *mrb, mrb_value x, mrb_value y)
|
||||
{
|
||||
return mrb_nil_value();
|
||||
}
|
||||
mrb_value mrb_complex_to_i(mrb_state *mrb, mrb_value x)
|
||||
{
|
||||
return mrb_nil_value();
|
||||
}
|
||||
mrb_value mrb_complex_to_f(mrb_state *mrb, mrb_value x)
|
||||
{
|
||||
return mrb_nil_value();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MRB_USE_RATIONAL
|
||||
mrb_value mrb_rational_new(mrb_state *mrb, mrb_int x, mrb_int y)
|
||||
{
|
||||
return mrb_nil_value();
|
||||
}
|
||||
mrb_value mrb_rational_add(mrb_state *mrb, mrb_value x, mrb_value y)
|
||||
{
|
||||
return mrb_nil_value();
|
||||
}
|
||||
mrb_value mrb_rational_sub(mrb_state *mrb, mrb_value x, mrb_value y)
|
||||
{
|
||||
return mrb_nil_value();
|
||||
}
|
||||
mrb_value mrb_rational_mul(mrb_state *mrb, mrb_value x, mrb_value y)
|
||||
{
|
||||
return mrb_nil_value();
|
||||
}
|
||||
mrb_value mrb_rational_div(mrb_state *mrb, mrb_value x, mrb_value y)
|
||||
{
|
||||
return mrb_nil_value();
|
||||
}
|
||||
mrb_value mrb_rational_to_i(mrb_state *mrb, mrb_value x)
|
||||
{
|
||||
return mrb_nil_value();
|
||||
}
|
||||
mrb_value mrb_rational_to_f(mrb_state *mrb, mrb_value x)
|
||||
{
|
||||
return mrb_nil_value();
|
||||
}
|
||||
#endif
|
||||
@@ -63,6 +63,16 @@ usage(const char *name)
|
||||
printf(" %s\n", *p++);
|
||||
}
|
||||
|
||||
static mrb_bool
|
||||
mrb_extension_p(const char *path)
|
||||
{
|
||||
const char *e = strrchr(path, '.');
|
||||
if (e && e[1] == 'm' && e[2] == 'r' && e[3] == 'b' && e[4] == '\0') {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
options_init(struct options *opts, int argc, char **argv)
|
||||
{
|
||||
@@ -323,7 +333,7 @@ main(int argc, char **argv)
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
mrbc_filename(mrb, c, args.libv[i]);
|
||||
if (args.mrbfile) {
|
||||
if (mrb_extension_p(args.libv[i])) {
|
||||
v = mrb_load_irep_file_cxt(mrb, lfp, c);
|
||||
}
|
||||
else {
|
||||
@@ -340,7 +350,7 @@ main(int argc, char **argv)
|
||||
mrbc_filename(mrb, c, cmdline);
|
||||
|
||||
/* Load program */
|
||||
if (args.mrbfile) {
|
||||
if (args.mrbfile || mrb_extension_p(cmdline)) {
|
||||
v = mrb_load_irep_file_cxt(mrb, args.rfp, c);
|
||||
}
|
||||
else if (args.rfp) {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <string.h>
|
||||
#include <mruby/irep.h>
|
||||
#include <mruby/dump.h>
|
||||
#include <mruby/internal.h>
|
||||
|
||||
struct strip_args {
|
||||
int argc_start;
|
||||
|
||||
@@ -45,7 +45,7 @@ binding_eval_error_check(mrb_state *mrb, struct mrb_parser_state *p, const char
|
||||
struct expand_lvspace {
|
||||
mrb_irep *irep;
|
||||
struct REnv *env;
|
||||
size_t numvar;
|
||||
int numvar;
|
||||
mrb_sym syms[LV_BUFFERS];
|
||||
};
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#include <mruby.h>
|
||||
#include <mruby/presym.h>
|
||||
|
||||
static mrb_value
|
||||
binding_in_c(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
return mrb_funcall_argv(mrb, mrb_obj_value(mrb->object_class), mrb_intern_lit(mrb, "binding"), 0, NULL);
|
||||
return mrb_funcall_argv(mrb, mrb_obj_value(mrb->object_class), MRB_SYM(binding), 0, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "mruby.h"
|
||||
#include "mruby/class.h"
|
||||
#include "mruby/string.h"
|
||||
#include "mruby/array.h"
|
||||
#include "mruby/proc.h"
|
||||
|
||||
static mrb_value
|
||||
@@ -56,6 +57,57 @@ mrb_mod_module_exec(mrb_state *mrb, mrb_value self)
|
||||
return mrb_yield_cont(mrb, blk, self, argc, argv);
|
||||
}
|
||||
|
||||
struct subclass_args {
|
||||
struct RClass *c;
|
||||
mrb_value ary;
|
||||
};
|
||||
|
||||
static int
|
||||
add_subclasses(mrb_state *mrb, struct RBasic *obj, void *data)
|
||||
{
|
||||
struct subclass_args *args = (struct subclass_args*)data;
|
||||
if (obj->tt == MRB_TT_CLASS) {
|
||||
struct RClass *c = (struct RClass*)obj;
|
||||
if (mrb_class_real(c->super) == args->c) {
|
||||
mrb_ary_push(mrb, args->ary, mrb_obj_value(obj));
|
||||
}
|
||||
}
|
||||
return MRB_EACH_OBJ_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* subclasses -> array
|
||||
*
|
||||
* Returns an array of classes where the receiver is the
|
||||
* direct superclass of the class, excluding singleton classes.
|
||||
* The order of the returned array is not defined.
|
||||
*
|
||||
* class A; end
|
||||
* class B < A; end
|
||||
* class C < B; end
|
||||
* class D < A; end
|
||||
*
|
||||
* A.subclasses #=> [D, B]
|
||||
* B.subclasses #=> [C]
|
||||
* C.subclasses #=> []
|
||||
*/
|
||||
static mrb_value
|
||||
mrb_class_subclasses(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
struct RClass *c;
|
||||
mrb_value ary;
|
||||
|
||||
c = mrb_class_ptr(self);
|
||||
ary = mrb_ary_new(mrb);
|
||||
|
||||
if (c->flags & MRB_FL_CLASS_IS_INHERITED) {
|
||||
struct subclass_args arg = {c, ary};
|
||||
mrb_objspace_each_objects(mrb, add_subclasses, &arg);
|
||||
}
|
||||
return ary;
|
||||
}
|
||||
|
||||
void
|
||||
mrb_mruby_class_ext_gem_init(mrb_state *mrb)
|
||||
{
|
||||
@@ -65,6 +117,9 @@ mrb_mruby_class_ext_gem_init(mrb_state *mrb)
|
||||
mrb_define_method(mrb, mod, "singleton_class?", mrb_mod_singleton_class_p, MRB_ARGS_NONE());
|
||||
mrb_define_method(mrb, mod, "module_exec", mrb_mod_module_exec, MRB_ARGS_ANY()|MRB_ARGS_BLOCK());
|
||||
mrb_define_method(mrb, mod, "class_exec", mrb_mod_module_exec, MRB_ARGS_ANY()|MRB_ARGS_BLOCK());
|
||||
|
||||
struct RClass *cls = mrb->module_class;
|
||||
mrb_define_method(mrb, cls, "subclasses", mrb_class_subclasses, MRB_ARGS_NONE());
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
assert 'Class#subclasses' do
|
||||
a = Class.new
|
||||
b = Class.new(a)
|
||||
c = Class.new(b)
|
||||
d = Class.new(a)
|
||||
|
||||
a_sub = a.subclasses
|
||||
assert_equal(2, a_sub.size)
|
||||
assert_true(a_sub.include?(b))
|
||||
assert_true(a_sub.include?(d))
|
||||
assert_equal([c], b.subclasses)
|
||||
assert_equal([], c.subclasses)
|
||||
end
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <mruby/throw.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <mruby/internal.h>
|
||||
|
||||
#ifndef MRB_CODEGEN_LEVEL_MAX
|
||||
#define MRB_CODEGEN_LEVEL_MAX 256
|
||||
@@ -57,7 +58,7 @@ typedef struct scope {
|
||||
uint32_t pc;
|
||||
uint32_t lastpc;
|
||||
uint32_t lastlabel;
|
||||
size_t ainfo:15;
|
||||
uint16_t ainfo:15;
|
||||
mrb_bool mscope:1;
|
||||
|
||||
struct loopinfo *loop;
|
||||
@@ -101,8 +102,8 @@ static void loop_pop(codegen_scope *s, int val);
|
||||
static int catch_handler_new(codegen_scope *s);
|
||||
static void catch_handler_set(codegen_scope *s, int ent, enum mrb_catch_type type, uint32_t begin, uint32_t end, uint32_t target);
|
||||
|
||||
static void gen_assignment(codegen_scope *s, node *tree, int sp, int val);
|
||||
static void gen_vmassignment(codegen_scope *s, node *tree, int rhs, int val);
|
||||
static void gen_assignment(codegen_scope *s, node *tree, node *rhs, int sp, int val);
|
||||
static void gen_massignment(codegen_scope *s, node *tree, int sp, int val);
|
||||
|
||||
static void codegen(codegen_scope *s, node *tree, int val);
|
||||
static void raise_error(codegen_scope *s, const char *msg);
|
||||
@@ -286,10 +287,10 @@ genop_2(codegen_scope *s, mrb_code i, uint16_t a, uint16_t b)
|
||||
}
|
||||
|
||||
static void
|
||||
genop_3(codegen_scope *s, mrb_code i, uint16_t a, uint16_t b, uint8_t c)
|
||||
genop_3(codegen_scope *s, mrb_code i, uint16_t a, uint16_t b, uint16_t c)
|
||||
{
|
||||
genop_2(s, i, a, b);
|
||||
gen_B(s, c);
|
||||
gen_B(s, (uint8_t)c);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -594,9 +595,22 @@ gen_move(codegen_scope *s, uint16_t dst, uint16_t src, int nopeep)
|
||||
|
||||
switch (data.insn) {
|
||||
case OP_MOVE:
|
||||
if (dst == src) return; /* remove useless MOVE */
|
||||
if (data.b == dst && data.a == src) /* skip swapping MOVE */
|
||||
if (dst == src) return; /* remove useless MOVE */
|
||||
if (data.a == src) {
|
||||
if (data.b == dst) /* skip swapping MOVE */
|
||||
return;
|
||||
if (data.a < s->nlocals) goto normal;
|
||||
rewind_pc(s);
|
||||
s->lastpc = addr_pc(s, mrb_prev_pc(s, data.addr));
|
||||
gen_move(s, dst, data.b, FALSE);
|
||||
return;
|
||||
}
|
||||
if (dst == data.a) { /* skip overwritten move */
|
||||
rewind_pc(s);
|
||||
s->lastpc = addr_pc(s, mrb_prev_pc(s, data.addr));
|
||||
gen_move(s, dst, src, FALSE);
|
||||
return;
|
||||
}
|
||||
goto normal;
|
||||
case OP_LOADNIL: case OP_LOADSELF: case OP_LOADT: case OP_LOADF:
|
||||
case OP_LOADI__1:
|
||||
@@ -606,7 +620,7 @@ gen_move(codegen_scope *s, uint16_t dst, uint16_t src, int nopeep)
|
||||
rewind_pc(s);
|
||||
genop_1(s, data.insn, dst);
|
||||
return;
|
||||
case OP_HASH: case OP_ARRAY:
|
||||
case OP_HASH:
|
||||
if (data.b != 0) goto normal;
|
||||
/* fall through */
|
||||
case OP_LOADI: case OP_LOADINEG:
|
||||
@@ -631,6 +645,19 @@ gen_move(codegen_scope *s, uint16_t dst, uint16_t src, int nopeep)
|
||||
genop_2SS(s, data.insn, dst, i);
|
||||
}
|
||||
return;
|
||||
case OP_ARRAY:
|
||||
if (data.a != src || data.a < s->nlocals || data.a < dst) goto normal;
|
||||
rewind_pc(s);
|
||||
if (data.b == 0 || dst == data.a)
|
||||
genop_2(s, OP_ARRAY, dst, 0);
|
||||
else
|
||||
genop_3(s, OP_ARRAY2, dst, data.a, data.b);
|
||||
return;
|
||||
case OP_ARRAY2:
|
||||
if (data.a != src || data.a < s->nlocals || data.a < dst) goto normal;
|
||||
rewind_pc(s);
|
||||
genop_3(s, OP_ARRAY2, dst, data.b, data.c);
|
||||
return;
|
||||
case OP_AREF:
|
||||
case OP_GETUPVAR:
|
||||
if (data.a != src || data.a < s->nlocals) goto normal;
|
||||
@@ -831,13 +858,14 @@ gen_muldiv(codegen_scope *s, uint8_t op, uint16_t dst)
|
||||
goto normal;
|
||||
}
|
||||
struct mrb_insn_data data0 = mrb_decode_insn(mrb_prev_pc(s, data.addr));
|
||||
if (!get_int_operand(s, &data0, &n0) || n == 0) {
|
||||
if (!get_int_operand(s, &data0, &n0)) {
|
||||
goto normal;
|
||||
}
|
||||
if (op == OP_MUL) {
|
||||
if (mrb_int_mul_overflow(n0, n, &n)) goto normal;
|
||||
}
|
||||
else { /* OP_DIV */
|
||||
if (n == 0) goto normal;
|
||||
if (n0 == MRB_INT_MIN && n == -1) goto normal;
|
||||
n = mrb_div_int(s->mrb, n0, n);
|
||||
}
|
||||
@@ -961,6 +989,17 @@ pop_n_(codegen_scope *s, int n)
|
||||
#define pop_n(n) pop_n_(s,n)
|
||||
#define cursp() (s->sp)
|
||||
|
||||
static mrb_pool_value*
|
||||
lit_pool_extend(codegen_scope *s)
|
||||
{
|
||||
if (s->irep->plen == s->pcapa) {
|
||||
s->pcapa *= 2;
|
||||
s->pool = (mrb_pool_value*)codegen_realloc(s, s->pool, sizeof(mrb_pool_value)*s->pcapa);
|
||||
}
|
||||
|
||||
return &s->pool[s->irep->plen++];
|
||||
}
|
||||
|
||||
static int
|
||||
new_litbn(codegen_scope *s, const char *p, int base, mrb_bool neg)
|
||||
{
|
||||
@@ -981,13 +1020,8 @@ new_litbn(codegen_scope *s, const char *p, int base, mrb_bool neg)
|
||||
return i;
|
||||
}
|
||||
|
||||
if (s->irep->plen == s->pcapa) {
|
||||
s->pcapa *= 2;
|
||||
s->pool = (mrb_pool_value*)codegen_realloc(s, s->pool, sizeof(mrb_pool_value)*s->pcapa);
|
||||
}
|
||||
pv = lit_pool_extend(s);
|
||||
|
||||
pv = &s->pool[s->irep->plen];
|
||||
i = s->irep->plen++;
|
||||
{
|
||||
char *buf;
|
||||
pv->tt = IREP_TT_BIGINT;
|
||||
@@ -1003,104 +1037,100 @@ new_litbn(codegen_scope *s, const char *p, int base, mrb_bool neg)
|
||||
}
|
||||
|
||||
static int
|
||||
new_lit(codegen_scope *s, mrb_value val)
|
||||
new_lit_str(codegen_scope *s, const char *str, mrb_int len)
|
||||
{
|
||||
int i;
|
||||
mrb_pool_value *pv;
|
||||
|
||||
switch (mrb_type(val)) {
|
||||
case MRB_TT_STRING:
|
||||
for (i=0; i<s->irep->plen; i++) {
|
||||
mrb_int len;
|
||||
pv = &s->pool[i];
|
||||
if (pv->tt & IREP_TT_NFLAG) continue;
|
||||
len = pv->tt>>2;
|
||||
if (RSTRING_LEN(val) != len) continue;
|
||||
if (memcmp(pv->u.str, RSTRING_PTR(val), len) == 0)
|
||||
return i;
|
||||
}
|
||||
break;
|
||||
#ifndef MRB_NO_FLOAT
|
||||
case MRB_TT_FLOAT:
|
||||
for (i=0; i<s->irep->plen; i++) {
|
||||
mrb_float f1, f2;
|
||||
pv = &s->pool[i];
|
||||
if (pv->tt != IREP_TT_FLOAT) continue;
|
||||
pv = &s->pool[i];
|
||||
f1 = pv->u.f;
|
||||
f2 = mrb_float(val);
|
||||
if (f1 == f2 && !signbit(f1) == !signbit(f2)) return i;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case MRB_TT_INTEGER:
|
||||
for (i=0; i<s->irep->plen; i++) {
|
||||
mrb_int v = mrb_integer(val);
|
||||
pv = &s->pool[i];
|
||||
if (pv->tt == IREP_TT_INT32) {
|
||||
if (v == pv->u.i32) return i;
|
||||
}
|
||||
#ifdef MRB_64BIT
|
||||
else if (pv->tt == IREP_TT_INT64) {
|
||||
if (v == pv->u.i64) return i;
|
||||
}
|
||||
continue;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* should not happen */
|
||||
return 0;
|
||||
for (i=0; i<s->irep->plen; i++) {
|
||||
pv = &s->pool[i];
|
||||
if (pv->tt & IREP_TT_NFLAG) continue;
|
||||
mrb_int plen = pv->tt>>2;
|
||||
if (len != plen) continue;
|
||||
if (memcmp(pv->u.str, str, plen) == 0)
|
||||
return i;
|
||||
}
|
||||
|
||||
if (s->irep->plen == s->pcapa) {
|
||||
s->pcapa *= 2;
|
||||
s->pool = (mrb_pool_value*)codegen_realloc(s, s->pool, sizeof(mrb_pool_value)*s->pcapa);
|
||||
pv = lit_pool_extend(s);
|
||||
|
||||
if (mrb_ro_data_p(str)) {
|
||||
pv->tt = (uint32_t)(len<<2) | IREP_TT_SSTR;
|
||||
pv->u.str = str;
|
||||
}
|
||||
else {
|
||||
char *p;
|
||||
pv->tt = (uint32_t)(len<<2) | IREP_TT_STR;
|
||||
p = (char*)codegen_realloc(s, NULL, len+1);
|
||||
memcpy(p, str, len);
|
||||
p[len] = '\0';
|
||||
pv->u.str = p;
|
||||
}
|
||||
|
||||
pv = &s->pool[s->irep->plen];
|
||||
i = s->irep->plen++;
|
||||
|
||||
switch (mrb_type(val)) {
|
||||
case MRB_TT_STRING:
|
||||
if (RSTR_NOFREE_P(RSTRING(val))) {
|
||||
pv->tt = (uint32_t)(RSTRING_LEN(val)<<2) | IREP_TT_SSTR;
|
||||
pv->u.str = RSTRING_PTR(val);
|
||||
}
|
||||
else {
|
||||
char *p;
|
||||
mrb_int len = RSTRING_LEN(val);
|
||||
pv->tt = (uint32_t)(len<<2) | IREP_TT_STR;
|
||||
p = (char*)codegen_realloc(s, NULL, len+1);
|
||||
memcpy(p, RSTRING_PTR(val), len);
|
||||
p[len] = '\0';
|
||||
pv->u.str = p;
|
||||
}
|
||||
break;
|
||||
|
||||
#ifndef MRB_NO_FLOAT
|
||||
case MRB_TT_FLOAT:
|
||||
pv->tt = IREP_TT_FLOAT;
|
||||
pv->u.f = mrb_float(val);
|
||||
break;
|
||||
#endif
|
||||
case MRB_TT_INTEGER:
|
||||
#ifdef MRB_INT64
|
||||
pv->tt = IREP_TT_INT64;
|
||||
pv->u.i64 = mrb_integer(val);
|
||||
#else
|
||||
pv->tt = IREP_TT_INT32;
|
||||
pv->u.i32 = mrb_integer(val);
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
/* should not happen */
|
||||
break;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
static int
|
||||
new_lit_cstr(codegen_scope *s, const char *str)
|
||||
{
|
||||
return new_lit_str(s, str, (mrb_int)strlen(str));
|
||||
}
|
||||
|
||||
static int
|
||||
new_lit_int(codegen_scope *s, mrb_int num)
|
||||
{
|
||||
int i;
|
||||
mrb_pool_value *pv;
|
||||
|
||||
for (i=0; i<s->irep->plen; i++) {
|
||||
pv = &s->pool[i];
|
||||
if (pv->tt == IREP_TT_INT32) {
|
||||
if (num == pv->u.i32) return i;
|
||||
}
|
||||
#ifdef MRB_64BIT
|
||||
else if (pv->tt == IREP_TT_INT64) {
|
||||
if (num == pv->u.i64) return i;
|
||||
}
|
||||
continue;
|
||||
#endif
|
||||
}
|
||||
|
||||
pv = lit_pool_extend(s);
|
||||
|
||||
#ifdef MRB_INT64
|
||||
pv->tt = IREP_TT_INT64;
|
||||
pv->u.i64 = num;
|
||||
#else
|
||||
pv->tt = IREP_TT_INT32;
|
||||
pv->u.i32 = num;
|
||||
#endif
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
#ifndef MRB_NO_FLOAT
|
||||
static int
|
||||
new_lit_float(codegen_scope *s, mrb_float num)
|
||||
{
|
||||
int i;
|
||||
mrb_pool_value *pv;
|
||||
|
||||
for (i=0; i<s->irep->plen; i++) {
|
||||
mrb_float f;
|
||||
pv = &s->pool[i];
|
||||
if (pv->tt != IREP_TT_FLOAT) continue;
|
||||
f = pv->u.f;
|
||||
if (f == num && !signbit(f) == !signbit(num)) return i;
|
||||
}
|
||||
|
||||
pv = lit_pool_extend(s);
|
||||
|
||||
pv->tt = IREP_TT_FLOAT;
|
||||
pv->u.f = num;
|
||||
|
||||
return i;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
new_sym(codegen_scope *s, mrb_sym sym)
|
||||
{
|
||||
@@ -1153,7 +1183,7 @@ gen_int(codegen_scope *s, uint16_t dst, mrb_int i)
|
||||
else if (i <= INT32_MAX) genop_2SS(s, OP_LOADI32, dst, (uint32_t)i);
|
||||
else {
|
||||
int_lit:
|
||||
genop_2(s, OP_LOADL, dst, new_lit(s, mrb_int_value(s->mrb, i)));
|
||||
genop_2(s, OP_LOADL, dst, new_lit_int(s, i));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1275,10 +1305,10 @@ for_body(codegen_scope *s, node *tree)
|
||||
n2 = tree->car;
|
||||
genop_W(s, OP_ENTER, 0x40000);
|
||||
if (n2->car && !n2->car->cdr && !n2->cdr) {
|
||||
gen_assignment(s, n2->car->car, 1, NOVAL);
|
||||
gen_assignment(s, n2->car->car, NULL, 1, NOVAL);
|
||||
}
|
||||
else {
|
||||
gen_vmassignment(s, n2, 1, VAL);
|
||||
gen_massignment(s, n2, 1, VAL);
|
||||
}
|
||||
/* construct loop */
|
||||
lp = loop_push(s, LOOP_FOR);
|
||||
@@ -1444,7 +1474,7 @@ lambda_body(codegen_scope *s, node *tree, int blk)
|
||||
pos = 1;
|
||||
while (n) {
|
||||
if (nint(n->car->car) == NODE_MASGN) {
|
||||
gen_vmassignment(s, n->car->cdr->car, pos, NOVAL);
|
||||
gen_massignment(s, n->car->cdr->car, pos, NOVAL);
|
||||
}
|
||||
pos++;
|
||||
n = n->cdr;
|
||||
@@ -1456,7 +1486,7 @@ lambda_body(codegen_scope *s, node *tree, int blk)
|
||||
pos = ma+oa+ra+1;
|
||||
while (n) {
|
||||
if (nint(n->car->car) == NODE_MASGN) {
|
||||
gen_vmassignment(s, n->car->cdr->car, pos, NOVAL);
|
||||
gen_massignment(s, n->car->cdr->car, pos, NOVAL);
|
||||
}
|
||||
pos++;
|
||||
n = n->cdr;
|
||||
@@ -1530,7 +1560,7 @@ attrsym(codegen_scope *s, mrb_sym a)
|
||||
#define GEN_VAL_STACK_MAX 99
|
||||
|
||||
static int
|
||||
gen_values(codegen_scope *s, node *t, int val, int extra, int limit)
|
||||
gen_values(codegen_scope *s, node *t, int val, int limit)
|
||||
{
|
||||
int n = 0;
|
||||
int first = 1;
|
||||
@@ -1551,7 +1581,7 @@ gen_values(codegen_scope *s, node *t, int val, int extra, int limit)
|
||||
while (t) {
|
||||
int is_splat = nint(t->car->car) == NODE_SPLAT;
|
||||
|
||||
if (is_splat || n+extra >= limit-1 || cursp() >= slimit) { /* flush stack */
|
||||
if (is_splat || cursp() >= slimit) { /* flush stack */
|
||||
pop_n(n);
|
||||
if (first) {
|
||||
if (n == 0) {
|
||||
@@ -1590,6 +1620,11 @@ gen_values(codegen_scope *s, node *t, int val, int extra, int limit)
|
||||
}
|
||||
return -1; /* variable length */
|
||||
}
|
||||
else if (n > limit) {
|
||||
pop_n(n);
|
||||
genop_2(s, OP_ARRAY, cursp(), n);
|
||||
return -1;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -1600,10 +1635,16 @@ gen_hash(codegen_scope *s, node *tree, int val, int limit)
|
||||
if (cursp() >= GEN_LIT_ARY_MAX) slimit = INT16_MAX;
|
||||
int len = 0;
|
||||
mrb_bool update = FALSE;
|
||||
mrb_bool first = TRUE;
|
||||
|
||||
while (tree) {
|
||||
if (nint(tree->car->car->car) == NODE_KW_REST_ARGS) {
|
||||
if (val && len > 0) {
|
||||
if (val && first) {
|
||||
genop_2(s, OP_HASH, cursp(), 0);
|
||||
push();
|
||||
update = TRUE;
|
||||
}
|
||||
else if (val && len > 0) {
|
||||
pop_n(len*2);
|
||||
if (!update) {
|
||||
genop_2(s, OP_HASH, cursp(), len);
|
||||
@@ -1642,6 +1683,13 @@ gen_hash(codegen_scope *s, node *tree, int val, int limit)
|
||||
update = TRUE;
|
||||
len = 0;
|
||||
}
|
||||
first = FALSE;
|
||||
}
|
||||
if (val && len > limit) {
|
||||
pop_n(len*2);
|
||||
genop_2(s, OP_HASH, cursp(), len);
|
||||
push();
|
||||
return -1;
|
||||
}
|
||||
if (update) {
|
||||
if (val && len > 0) {
|
||||
@@ -1655,10 +1703,10 @@ gen_hash(codegen_scope *s, node *tree, int val, int limit)
|
||||
}
|
||||
|
||||
static void
|
||||
gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe)
|
||||
gen_call(codegen_scope *s, node *tree, int val, int safe)
|
||||
{
|
||||
mrb_sym sym = name ? name : nsym(tree->cdr->car);
|
||||
int skip = 0, n = 0, nk = 0, noop = 0, noself = 0, blk = 0, sp_save = cursp();
|
||||
mrb_sym sym = nsym(tree->cdr->car);
|
||||
int skip = 0, n = 0, nk = 0, noop = no_optimize(s), noself = 0, blk = 0, sp_save = cursp();
|
||||
|
||||
if (!tree->car) {
|
||||
noself = noop = 1;
|
||||
@@ -1675,7 +1723,7 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe)
|
||||
tree = tree->cdr->cdr->car;
|
||||
if (tree) {
|
||||
if (tree->car) { /* positional arguments */
|
||||
n = gen_values(s, tree->car, VAL, sp?1:0, 14);
|
||||
n = gen_values(s, tree->car, VAL, 14);
|
||||
if (n < 0) { /* variable length */
|
||||
noop = 1; /* not operator */
|
||||
n = 15;
|
||||
@@ -1688,32 +1736,6 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe)
|
||||
if (nk < 0) nk = 15;
|
||||
}
|
||||
}
|
||||
if (sp) { /* last argument pushed (attr=, []=) */
|
||||
/* pack keyword arguments */
|
||||
if (nk > 0 && nk < 15) {
|
||||
pop_n(nk*2);
|
||||
genop_2(s, OP_HASH, cursp(), nk);
|
||||
push();
|
||||
}
|
||||
if (n == CALL_MAXARGS) {
|
||||
if (nk > 0) {
|
||||
pop(); pop();
|
||||
genop_2(s, OP_ARYPUSH, cursp(), 1);
|
||||
push();
|
||||
}
|
||||
gen_move(s, cursp(), sp, 0);
|
||||
pop();
|
||||
genop_2(s, OP_ARYPUSH, cursp(), 1);
|
||||
push();
|
||||
}
|
||||
else {
|
||||
gen_move(s, cursp(), sp, 0);
|
||||
push();
|
||||
if (nk > 0) n++;
|
||||
n++;
|
||||
}
|
||||
nk = 0;
|
||||
}
|
||||
if (tree && tree->cdr && tree->cdr->cdr) {
|
||||
codegen(s, tree->cdr->cdr, VAL);
|
||||
pop();
|
||||
@@ -1773,11 +1795,42 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe)
|
||||
}
|
||||
|
||||
static void
|
||||
gen_assignment(codegen_scope *s, node *tree, int sp, int val)
|
||||
gen_assignment(codegen_scope *s, node *tree, node *rhs, int sp, int val)
|
||||
{
|
||||
int idx;
|
||||
int type = nint(tree->car);
|
||||
|
||||
switch (type) {
|
||||
case NODE_GVAR:
|
||||
case NODE_ARG:
|
||||
case NODE_LVAR:
|
||||
case NODE_IVAR:
|
||||
case NODE_CVAR:
|
||||
case NODE_CONST:
|
||||
case NODE_NIL:
|
||||
case NODE_MASGN:
|
||||
if (rhs) {
|
||||
codegen(s, rhs, VAL);
|
||||
pop();
|
||||
sp = cursp();
|
||||
}
|
||||
break;
|
||||
|
||||
case NODE_COLON2:
|
||||
case NODE_CALL:
|
||||
case NODE_SCALL:
|
||||
/* keep evaluation order */
|
||||
break;
|
||||
|
||||
case NODE_NVAR:
|
||||
codegen_error(s, "Can't assign to numbered parameter");
|
||||
break;
|
||||
|
||||
default:
|
||||
codegen_error(s, "unknown lhs");
|
||||
break;
|
||||
}
|
||||
|
||||
tree = tree->cdr;
|
||||
switch (type) {
|
||||
case NODE_GVAR:
|
||||
@@ -1796,10 +1849,6 @@ gen_assignment(codegen_scope *s, node *tree, int sp, int val)
|
||||
gen_setupvar(s, sp, nsym(tree));
|
||||
}
|
||||
break;
|
||||
case NODE_NVAR:
|
||||
idx = nint(tree);
|
||||
codegen_error(s, "Can't assign to numbered parameter");
|
||||
break;
|
||||
case NODE_IVAR:
|
||||
gen_setxv(s, OP_SETIV, sp, nsym(tree), val);
|
||||
break;
|
||||
@@ -1810,9 +1859,16 @@ gen_assignment(codegen_scope *s, node *tree, int sp, int val)
|
||||
gen_setxv(s, OP_SETCONST, sp, nsym(tree), val);
|
||||
break;
|
||||
case NODE_COLON2:
|
||||
gen_move(s, cursp(), sp, 0);
|
||||
if (sp) {
|
||||
gen_move(s, cursp(), sp, 0);
|
||||
}
|
||||
sp = cursp();
|
||||
push();
|
||||
codegen(s, tree->car, VAL);
|
||||
if (rhs) {
|
||||
codegen(s, rhs, VAL); pop();
|
||||
gen_move(s, sp, cursp(), 0);
|
||||
}
|
||||
pop_n(2);
|
||||
idx = new_sym(s, nsym(tree->cdr));
|
||||
genop_2(s, OP_SETMCNST, sp, idx);
|
||||
@@ -1820,17 +1876,91 @@ gen_assignment(codegen_scope *s, node *tree, int sp, int val)
|
||||
|
||||
case NODE_CALL:
|
||||
case NODE_SCALL:
|
||||
push();
|
||||
gen_call(s, tree, attrsym(s, nsym(tree->cdr->car)), sp, NOVAL,
|
||||
type == NODE_SCALL);
|
||||
pop();
|
||||
if (val && cursp() != sp) {
|
||||
gen_move(s, cursp(), sp, 0);
|
||||
{
|
||||
int noself = 0, safe = (type == NODE_SCALL), skip = 0, top, call, n = 0;
|
||||
mrb_sym mid = nsym(tree->cdr->car);
|
||||
|
||||
top = cursp();
|
||||
if (val || sp == cursp()) {
|
||||
push(); /* room for retval */
|
||||
}
|
||||
call = cursp();
|
||||
if (!tree->car) {
|
||||
noself = 1;
|
||||
push();
|
||||
}
|
||||
else {
|
||||
codegen(s, tree->car, VAL); /* receiver */
|
||||
}
|
||||
if (safe) {
|
||||
int recv = cursp()-1;
|
||||
gen_move(s, cursp(), recv, 1);
|
||||
skip = genjmp2_0(s, OP_JMPNIL, cursp(), val);
|
||||
}
|
||||
tree = tree->cdr->cdr->car;
|
||||
if (tree) {
|
||||
if (tree->car) { /* positional arguments */
|
||||
n = gen_values(s, tree->car, VAL, (tree->cdr->car)?13:14);
|
||||
if (n < 0) { /* variable length */
|
||||
n = 15;
|
||||
push();
|
||||
}
|
||||
}
|
||||
if (tree->cdr->car) { /* keyword arguments */
|
||||
if (n == 13 || n == 14) {
|
||||
pop_n(n);
|
||||
genop_2(s, OP_ARRAY, cursp(), n);
|
||||
push();
|
||||
n = 15;
|
||||
}
|
||||
gen_hash(s, tree->cdr->car->cdr, VAL, 0);
|
||||
if (n < 14) {
|
||||
n++;
|
||||
}
|
||||
else {
|
||||
pop_n(2);
|
||||
genop_2(s, OP_ARYPUSH, cursp(), 1);
|
||||
}
|
||||
push();
|
||||
}
|
||||
}
|
||||
if (rhs) {
|
||||
codegen(s, rhs, VAL);
|
||||
pop();
|
||||
}
|
||||
else {
|
||||
gen_move(s, cursp(), sp, 0);
|
||||
}
|
||||
if (val) {
|
||||
gen_move(s, top, cursp(), 1);
|
||||
}
|
||||
if (n < 15) {
|
||||
n++;
|
||||
if (n == 15) {
|
||||
pop_n(14);
|
||||
genop_2(s, OP_ARRAY, cursp(), 15);
|
||||
}
|
||||
}
|
||||
else {
|
||||
pop();
|
||||
genop_2(s, OP_ARYPUSH, cursp(), 1);
|
||||
}
|
||||
s->sp = call;
|
||||
if (mid == MRB_OPSYM_2(s->mrb, aref) && n == 2) {
|
||||
genop_1(s, OP_SETIDX, cursp());
|
||||
}
|
||||
else {
|
||||
genop_3(s, noself ? OP_SSEND : OP_SEND, cursp(), new_sym(s, attrsym(s, mid)), n);
|
||||
}
|
||||
if (safe) {
|
||||
dispatch(s, skip);
|
||||
}
|
||||
s->sp = top;
|
||||
}
|
||||
break;
|
||||
|
||||
case NODE_MASGN:
|
||||
gen_vmassignment(s, tree->car, sp, val);
|
||||
gen_massignment(s, tree->car, sp, val);
|
||||
break;
|
||||
|
||||
/* splat without assignment */
|
||||
@@ -1845,7 +1975,7 @@ gen_assignment(codegen_scope *s, node *tree, int sp, int val)
|
||||
}
|
||||
|
||||
static void
|
||||
gen_vmassignment(codegen_scope *s, node *tree, int rhs, int val)
|
||||
gen_massignment(codegen_scope *s, node *tree, int rhs, int val)
|
||||
{
|
||||
int n = 0, post = 0;
|
||||
node *t, *p;
|
||||
@@ -1858,7 +1988,7 @@ gen_vmassignment(codegen_scope *s, node *tree, int rhs, int val)
|
||||
|
||||
genop_3(s, OP_AREF, sp, rhs, n);
|
||||
push();
|
||||
gen_assignment(s, t->car, sp, NOVAL);
|
||||
gen_assignment(s, t->car, NULL, sp, NOVAL);
|
||||
pop();
|
||||
n++;
|
||||
t = t->cdr;
|
||||
@@ -1879,12 +2009,12 @@ gen_vmassignment(codegen_scope *s, node *tree, int rhs, int val)
|
||||
genop_3(s, OP_APOST, cursp(), n, post);
|
||||
n = 1;
|
||||
if (t->car && t->car != (node*)-1) { /* rest */
|
||||
gen_assignment(s, t->car, cursp(), NOVAL);
|
||||
gen_assignment(s, t->car, NULL, cursp(), NOVAL);
|
||||
}
|
||||
if (t->cdr && t->cdr->car) {
|
||||
t = t->cdr->car;
|
||||
while (t) {
|
||||
gen_assignment(s, t->car, cursp()+n, NOVAL);
|
||||
gen_assignment(s, t->car, NULL, cursp()+n, NOVAL);
|
||||
t = t->cdr;
|
||||
n++;
|
||||
}
|
||||
@@ -1989,7 +2119,7 @@ gen_literal_array(codegen_scope *s, node *tree, mrb_bool sym, int val)
|
||||
static void
|
||||
raise_error(codegen_scope *s, const char *msg)
|
||||
{
|
||||
int idx = new_lit(s, mrb_str_new_cstr(s->mrb, msg));
|
||||
int idx = new_lit_cstr(s, msg);
|
||||
|
||||
genop_1(s, OP_ERR, idx);
|
||||
}
|
||||
@@ -2204,7 +2334,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
|
||||
pop();
|
||||
if (n3->cdr->car) {
|
||||
gen_assignment(s, n3->cdr->car, exc, NOVAL);
|
||||
gen_assignment(s, n3->cdr->car, NULL, exc, NOVAL);
|
||||
}
|
||||
if (n3->cdr->cdr->car) {
|
||||
codegen(s, n3->cdr->cdr->car, val);
|
||||
@@ -2509,10 +2639,10 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
|
||||
case NODE_FCALL:
|
||||
case NODE_CALL:
|
||||
gen_call(s, tree, 0, 0, val, 0);
|
||||
gen_call(s, tree, val, 0);
|
||||
break;
|
||||
case NODE_SCALL:
|
||||
gen_call(s, tree, 0, 0, val, 1);
|
||||
gen_call(s, tree, val, 1);
|
||||
break;
|
||||
|
||||
case NODE_DOT2:
|
||||
@@ -2560,7 +2690,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
{
|
||||
int n;
|
||||
|
||||
n = gen_values(s, tree, val, 0, 0);
|
||||
n = gen_values(s, tree, val, 0);
|
||||
if (val) {
|
||||
if (n >= 0) {
|
||||
pop_n(n);
|
||||
@@ -2588,9 +2718,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
break;
|
||||
|
||||
case NODE_ASGN:
|
||||
codegen(s, tree->cdr, VAL);
|
||||
pop();
|
||||
gen_assignment(s, tree->car, cursp(), val);
|
||||
gen_assignment(s, tree->car, tree->cdr, 0, val);
|
||||
break;
|
||||
|
||||
case NODE_MASGN:
|
||||
@@ -2613,12 +2741,12 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
n = 0;
|
||||
while (t) {
|
||||
if (n < len) {
|
||||
gen_assignment(s, t->car, rhs+n, NOVAL);
|
||||
gen_assignment(s, t->car, NULL, rhs+n, NOVAL);
|
||||
n++;
|
||||
}
|
||||
else {
|
||||
genop_1(s, OP_LOADNIL, rhs+n);
|
||||
gen_assignment(s, t->car, rhs+n, NOVAL);
|
||||
gen_assignment(s, t->car, NULL, rhs+n, NOVAL);
|
||||
}
|
||||
t = t->cdr;
|
||||
}
|
||||
@@ -2641,14 +2769,25 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
else {
|
||||
rn = len - post - n;
|
||||
}
|
||||
genop_3(s, OP_ARRAY2, cursp(), rhs+n, rn);
|
||||
gen_assignment(s, t->car, cursp(), NOVAL);
|
||||
if (cursp() == rhs+n) {
|
||||
genop_2(s, OP_ARRAY, cursp(), rn);
|
||||
}
|
||||
else {
|
||||
genop_3(s, OP_ARRAY2, cursp(), rhs+n, rn);
|
||||
}
|
||||
gen_assignment(s, t->car, NULL, cursp(), NOVAL);
|
||||
n += rn;
|
||||
}
|
||||
if (t->cdr && t->cdr->car) {
|
||||
t = t->cdr->car;
|
||||
while (n<len) {
|
||||
gen_assignment(s, t->car, rhs+n, NOVAL);
|
||||
while (t) {
|
||||
if (n<len) {
|
||||
gen_assignment(s, t->car, NULL, rhs+n, NOVAL);
|
||||
}
|
||||
else {
|
||||
genop_1(s, OP_LOADNIL, cursp());
|
||||
gen_assignment(s, t->car, NULL, cursp(), NOVAL);
|
||||
}
|
||||
t = t->cdr;
|
||||
n++;
|
||||
}
|
||||
@@ -2663,7 +2802,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
else {
|
||||
/* variable rhs */
|
||||
codegen(s, t, VAL);
|
||||
gen_vmassignment(s, tree->car, rhs, val);
|
||||
gen_massignment(s, tree->car, rhs, val);
|
||||
if (!val) {
|
||||
pop();
|
||||
}
|
||||
@@ -2713,7 +2852,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
idx = new_sym(s, nsym(n->cdr->car));
|
||||
base = cursp()-1;
|
||||
if (n->cdr->cdr->car) {
|
||||
nargs = gen_values(s, n->cdr->cdr->car->car, VAL, 1, 14);
|
||||
nargs = gen_values(s, n->cdr->cdr->car->car, VAL, 13);
|
||||
if (nargs >= 0) {
|
||||
callargs = nargs;
|
||||
}
|
||||
@@ -2769,7 +2908,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
genop_3(s, OP_SEND, cursp(), idx, callargs);
|
||||
}
|
||||
else {
|
||||
gen_assignment(s, tree->car, cursp(), val);
|
||||
gen_assignment(s, tree->car, NULL, cursp(), val);
|
||||
}
|
||||
dispatch(s, pos);
|
||||
goto exit;
|
||||
@@ -2807,7 +2946,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
genop_3(s, OP_SEND, cursp(), idx, 1);
|
||||
}
|
||||
if (callargs < 0) {
|
||||
gen_assignment(s, tree->car, cursp(), val);
|
||||
gen_assignment(s, tree->car, NULL, cursp(), val);
|
||||
}
|
||||
else {
|
||||
if (val && vsp >= 0) {
|
||||
@@ -2843,7 +2982,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
if (tree) {
|
||||
node *args = tree->car;
|
||||
if (args) {
|
||||
st = n = gen_values(s, args, VAL, 0, 14);
|
||||
st = n = gen_values(s, args, VAL, 14);
|
||||
if (n < 0) {
|
||||
st = 1; n = 15;
|
||||
push();
|
||||
@@ -2884,7 +3023,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
{
|
||||
codegen_scope *s2 = s;
|
||||
int lv = 0;
|
||||
size_t ainfo = 0;
|
||||
uint16_t ainfo = 0;
|
||||
int n = CALL_MAXARGS;
|
||||
int sp = cursp();
|
||||
|
||||
@@ -2961,7 +3100,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
if (ainfo < 0) codegen_error(s, "invalid yield (SyntaxError)");
|
||||
push();
|
||||
if (tree) {
|
||||
n = gen_values(s, tree, VAL, 0, 14);
|
||||
n = gen_values(s, tree, VAL, 14);
|
||||
if (n < 0) {
|
||||
n = sendv = 1;
|
||||
push();
|
||||
@@ -3156,7 +3295,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
if (val) {
|
||||
char *p = (char*)tree;
|
||||
mrb_float f = mrb_float_read(p, NULL);
|
||||
int off = new_lit(s, mrb_float_value(s->mrb, f));
|
||||
int off = new_lit_float(s, f);
|
||||
|
||||
genop_2(s, OP_LOADL, cursp(), off);
|
||||
push();
|
||||
@@ -3173,7 +3312,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
if (val) {
|
||||
char *p = (char*)tree->cdr;
|
||||
mrb_float f = mrb_float_read(p, NULL);
|
||||
int off = new_lit(s, mrb_float_value(s->mrb, -f));
|
||||
int off = new_lit_float(s, -f);
|
||||
|
||||
genop_2(s, OP_LOADL, cursp(), off);
|
||||
push();
|
||||
@@ -3222,11 +3361,9 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
case NODE_STR:
|
||||
if (val) {
|
||||
char *p = (char*)tree->car;
|
||||
size_t len = (intptr_t)tree->cdr;
|
||||
int ai = mrb_gc_arena_save(s->mrb);
|
||||
int off = new_lit(s, mrb_str_new(s->mrb, p, len));
|
||||
mrb_int len = nint(tree->cdr);
|
||||
int off = new_lit_str(s, p, len);
|
||||
|
||||
mrb_gc_arena_restore(s->mrb, ai);
|
||||
genop_2(s, OP_STRING, cursp(), off);
|
||||
push();
|
||||
}
|
||||
@@ -3277,7 +3414,6 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
case NODE_DXSTR:
|
||||
{
|
||||
node *n;
|
||||
int ai = mrb_gc_arena_save(s->mrb);
|
||||
int sym = new_sym(s, MRB_SYM_2(s->mrb, Kernel));
|
||||
|
||||
genop_1(s, OP_LOADSELF, cursp());
|
||||
@@ -3300,16 +3436,14 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
sym = new_sym(s, MRB_OPSYM_2(s->mrb, tick)); /* ` */
|
||||
genop_3(s, OP_SEND, cursp(), sym, 1);
|
||||
if (val) push();
|
||||
mrb_gc_arena_restore(s->mrb, ai);
|
||||
}
|
||||
break;
|
||||
|
||||
case NODE_XSTR:
|
||||
{
|
||||
char *p = (char*)tree->car;
|
||||
size_t len = (intptr_t)tree->cdr;
|
||||
int ai = mrb_gc_arena_save(s->mrb);
|
||||
int off = new_lit(s, mrb_str_new(s->mrb, p, len));
|
||||
mrb_int len = nint(tree->cdr);
|
||||
int off = new_lit_str(s, p, len);
|
||||
int sym;
|
||||
|
||||
genop_1(s, OP_LOADSELF, cursp());
|
||||
@@ -3320,7 +3454,6 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
sym = new_sym(s, MRB_OPSYM_2(s->mrb, tick)); /* ` */
|
||||
genop_3(s, OP_SEND, cursp(), sym, 1);
|
||||
if (val) push();
|
||||
mrb_gc_arena_restore(s->mrb, ai);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -3329,9 +3462,8 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
char *p1 = (char*)tree->car;
|
||||
char *p2 = (char*)tree->cdr->car;
|
||||
char *p3 = (char*)tree->cdr->cdr;
|
||||
int ai = mrb_gc_arena_save(s->mrb);
|
||||
int sym = new_sym(s, mrb_intern_lit(s->mrb, REGEXP_CLASS));
|
||||
int off = new_lit(s, mrb_str_new_cstr(s->mrb, p1));
|
||||
int off = new_lit_cstr(s, p1);
|
||||
int argc = 1;
|
||||
|
||||
genop_1(s, OP_OCLASS, cursp());
|
||||
@@ -3341,7 +3473,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
push();
|
||||
if (p2 || p3) {
|
||||
if (p2) { /* opt */
|
||||
off = new_lit(s, mrb_str_new_cstr(s->mrb, p2));
|
||||
off = new_lit_cstr(s, p2);
|
||||
genop_2(s, OP_STRING, cursp(), off);
|
||||
}
|
||||
else {
|
||||
@@ -3350,7 +3482,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
push();
|
||||
argc++;
|
||||
if (p3) { /* enc */
|
||||
off = new_lit(s, mrb_str_new(s->mrb, p3, 1));
|
||||
off = new_lit_str(s, p3, 1);
|
||||
genop_2(s, OP_STRING, cursp(), off);
|
||||
push();
|
||||
argc++;
|
||||
@@ -3360,7 +3492,6 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
pop_n(argc+2);
|
||||
sym = new_sym(s, MRB_SYM_2(s->mrb, compile));
|
||||
genop_3(s, OP_SEND, cursp(), sym, argc);
|
||||
mrb_gc_arena_restore(s->mrb, ai);
|
||||
push();
|
||||
}
|
||||
break;
|
||||
@@ -3368,7 +3499,6 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
case NODE_DREGX:
|
||||
if (val) {
|
||||
node *n = tree->car;
|
||||
int ai = mrb_gc_arena_save(s->mrb);
|
||||
int sym = new_sym(s, mrb_intern_lit(s->mrb, REGEXP_CLASS));
|
||||
int argc = 1;
|
||||
int off;
|
||||
@@ -3389,7 +3519,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
n = tree->cdr->cdr;
|
||||
if (n->car) { /* tail */
|
||||
p = (char*)n->car;
|
||||
off = new_lit(s, mrb_str_new_cstr(s->mrb, p));
|
||||
off = new_lit_cstr(s, p);
|
||||
codegen(s, tree->car, VAL);
|
||||
genop_2(s, OP_STRING, cursp(), off);
|
||||
pop();
|
||||
@@ -3398,14 +3528,14 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
}
|
||||
if (n->cdr->car) { /* opt */
|
||||
char *p2 = (char*)n->cdr->car;
|
||||
off = new_lit(s, mrb_str_new_cstr(s->mrb, p2));
|
||||
off = new_lit_cstr(s, p2);
|
||||
genop_2(s, OP_STRING, cursp(), off);
|
||||
push();
|
||||
argc++;
|
||||
}
|
||||
if (n->cdr->cdr) { /* enc */
|
||||
char *p2 = (char*)n->cdr->cdr;
|
||||
off = new_lit(s, mrb_str_new_cstr(s->mrb, p2));
|
||||
off = new_lit_cstr(s, p2);
|
||||
genop_2(s, OP_STRING, cursp(), off);
|
||||
push();
|
||||
argc++;
|
||||
@@ -3414,7 +3544,6 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
pop_n(argc+2);
|
||||
sym = new_sym(s, MRB_SYM_2(s->mrb, compile));
|
||||
genop_3(s, OP_SEND, cursp(), sym, argc);
|
||||
mrb_gc_arena_restore(s->mrb, ai);
|
||||
push();
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <mruby/throw.h>
|
||||
#include <mruby/string.h>
|
||||
#include <mruby/dump.h>
|
||||
#include <mruby/internal.h>
|
||||
#include <mruby/presym.h>
|
||||
#include "node.h"
|
||||
|
||||
@@ -994,13 +995,13 @@ static node*
|
||||
new_imaginary(parser_state *p, node *imaginary)
|
||||
{
|
||||
return new_call(p, new_const(p, MRB_SYM_2(p->mrb, Kernel)), MRB_SYM_2(p->mrb, Complex),
|
||||
new_callargs(p, list2(list3((node*)NODE_INT, (node*)strdup("0"), nint(10)), imaginary), 0, 0), 1);
|
||||
new_callargs(p, list2(list3((node*)NODE_INT, (node*)strdup("0"), nint(10)), imaginary), 0, 0), '.');
|
||||
}
|
||||
|
||||
static node*
|
||||
new_rational(parser_state *p, node *rational)
|
||||
{
|
||||
return new_call(p, new_const(p, MRB_SYM_2(p->mrb, Kernel)), MRB_SYM_2(p->mrb, Rational), new_callargs(p, list1(rational), 0, 0), 1);
|
||||
return new_call(p, new_const(p, MRB_SYM_2(p->mrb, Kernel)), MRB_SYM_2(p->mrb, Rational), new_callargs(p, list1(rational), 0, 0), '.');
|
||||
}
|
||||
|
||||
/* (:int . i) */
|
||||
@@ -1216,14 +1217,14 @@ static node*
|
||||
call_uni_op(parser_state *p, node *recv, const char *m)
|
||||
{
|
||||
void_expr_error(p, recv);
|
||||
return new_call(p, recv, intern_cstr(m), 0, 1);
|
||||
return new_call(p, recv, intern_cstr(m), 0, '.');
|
||||
}
|
||||
|
||||
/* (:call a op b) */
|
||||
static node*
|
||||
call_bin_op(parser_state *p, node *recv, const char *m, node *arg1)
|
||||
{
|
||||
return new_call(p, recv, intern_cstr(m), new_callargs(p, list1(arg1), 0, 0), 1);
|
||||
return new_call(p, recv, intern_cstr(m), new_callargs(p, list1(arg1), 0, 0), '.');
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -6933,7 +6934,7 @@ mrb_load_detect_file_cxt(mrb_state *mrb, FILE *fp, mrbc_context *c)
|
||||
return mrb_load_exec(mrb, mrb_parse_file_continue(mrb, fp, leading.b, bufsize, c), c);
|
||||
}
|
||||
else {
|
||||
size_t binsize;
|
||||
mrb_int binsize;
|
||||
uint8_t *bin;
|
||||
mrb_value bin_obj = mrb_nil_value(); /* temporary string object */
|
||||
mrb_value result;
|
||||
@@ -6941,11 +6942,12 @@ mrb_load_detect_file_cxt(mrb_state *mrb, FILE *fp, mrbc_context *c)
|
||||
binsize = bin_to_uint32(leading.h.binary_size);
|
||||
bin_obj = mrb_str_new(mrb, NULL, binsize);
|
||||
bin = (uint8_t *)RSTRING_PTR(bin_obj);
|
||||
memcpy(bin, leading.b, bufsize);
|
||||
if (binsize > bufsize &&
|
||||
fread(bin + bufsize, binsize - bufsize, 1, fp) == 0) {
|
||||
binsize = bufsize;
|
||||
/* The error is reported by mrb_load_irep_buf_cxt() */
|
||||
if ((size_t)binsize > bufsize) {
|
||||
memcpy(bin, leading.b, bufsize);
|
||||
if (fread(bin + bufsize, binsize - bufsize, 1, fp) == 0) {
|
||||
binsize = bufsize;
|
||||
/* The error is reported by mrb_load_irep_buf_cxt() */
|
||||
}
|
||||
}
|
||||
|
||||
result = mrb_load_irep_buf_cxt(mrb, bin, binsize, c);
|
||||
@@ -7417,12 +7419,10 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
|
||||
}
|
||||
}
|
||||
n2 = n2->cdr;
|
||||
if (n2) {
|
||||
if (n2->car) {
|
||||
dump_prefix(n2, offset+2);
|
||||
printf("post:\n");
|
||||
dump_recur(mrb, n2->car, offset+3);
|
||||
}
|
||||
if (n2 && n2->car) {
|
||||
dump_prefix(n2, offset+2);
|
||||
printf("post:\n");
|
||||
dump_recur(mrb, n2->car, offset+3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1027
-1026
File diff suppressed because it is too large
Load Diff
@@ -168,10 +168,9 @@ complex_eq(mrb_state *mrb, mrb_value x)
|
||||
return mrb_bool_value(mrb_complex_eq(mrb, x, y));
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
complex_add(mrb_state *mrb, mrb_value x)
|
||||
mrb_value
|
||||
mrb_complex_add(mrb_state *mrb, mrb_value x, mrb_value y)
|
||||
{
|
||||
mrb_value y = mrb_get_arg1(mrb);
|
||||
struct mrb_complex *p1 = complex_ptr(mrb, x);
|
||||
|
||||
switch (mrb_type(y)) {
|
||||
@@ -190,9 +189,15 @@ complex_add(mrb_state *mrb, mrb_value x)
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
complex_sub(mrb_state *mrb, mrb_value x)
|
||||
complex_add(mrb_state *mrb, mrb_value x)
|
||||
{
|
||||
mrb_value y = mrb_get_arg1(mrb);
|
||||
return mrb_complex_add(mrb, x, y);
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_complex_sub(mrb_state *mrb, mrb_value x, mrb_value y)
|
||||
{
|
||||
struct mrb_complex *p1 = complex_ptr(mrb, x);
|
||||
|
||||
switch (mrb_type(y)) {
|
||||
@@ -211,9 +216,15 @@ complex_sub(mrb_state *mrb, mrb_value x)
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
complex_mul(mrb_state *mrb, mrb_value x)
|
||||
complex_sub(mrb_state *mrb, mrb_value x)
|
||||
{
|
||||
mrb_value y = mrb_get_arg1(mrb);
|
||||
return mrb_complex_sub(mrb, x, y);
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_complex_mul(mrb_state *mrb, mrb_value x, mrb_value y)
|
||||
{
|
||||
struct mrb_complex *p1 = complex_ptr(mrb, x);
|
||||
|
||||
switch (mrb_type(y)) {
|
||||
@@ -232,6 +243,13 @@ complex_mul(mrb_state *mrb, mrb_value x)
|
||||
}
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
complex_mul(mrb_state *mrb, mrb_value x)
|
||||
{
|
||||
mrb_value y = mrb_get_arg1(mrb);
|
||||
return mrb_complex_mul(mrb, x, y);
|
||||
}
|
||||
|
||||
/* Arithmetic on (significand, exponent) pairs avoids premature overflow in
|
||||
complex division */
|
||||
struct float_pair {
|
||||
@@ -272,11 +290,10 @@ div_pair(struct float_pair *q, struct float_pair const *a,
|
||||
q->x = a->x - b->x;
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
complex_div(mrb_state *mrb, mrb_value self)
|
||||
mrb_value
|
||||
mrb_complex_div(mrb_state *mrb, mrb_value self, mrb_value rhs)
|
||||
{
|
||||
struct mrb_complex *a, *b;
|
||||
mrb_value rhs = mrb_get_arg1(mrb);
|
||||
|
||||
a = complex_ptr(mrb, self);
|
||||
if (mrb_type(rhs) != MRB_TT_COMPLEX) {
|
||||
@@ -324,78 +341,11 @@ complex_div(mrb_state *mrb, mrb_value self)
|
||||
return complex_new(mrb, F(ldexp)(zr.s, zr.x), F(ldexp)(zi.s, zi.x));
|
||||
}
|
||||
|
||||
mrb_int mrb_div_int(mrb_state *mrb, mrb_int x, mrb_int y);
|
||||
mrb_value mrb_rational_new(mrb_state *mrb, mrb_int n, mrb_int d);
|
||||
mrb_value mrb_rational_div(mrb_state *mrb, mrb_value x);
|
||||
|
||||
/* 15.2.8.3.4 */
|
||||
/*
|
||||
* redefine Integer#/
|
||||
*/
|
||||
static mrb_value
|
||||
cpx_int_div(mrb_state *mrb, mrb_value x)
|
||||
complex_div(mrb_state *mrb, mrb_value x)
|
||||
{
|
||||
mrb_value y = mrb_get_arg1(mrb);
|
||||
mrb_int a = mrb_integer(x);
|
||||
|
||||
if (mrb_integer_p(y)) {
|
||||
mrb_int div = mrb_div_int(mrb, a, mrb_integer(y));
|
||||
return mrb_int_value(mrb, div);
|
||||
}
|
||||
switch (mrb_type(y)) {
|
||||
#ifdef MRB_USE_RATIONAL
|
||||
case MRB_TT_RATIONAL:
|
||||
return mrb_rational_div(mrb, mrb_rational_new(mrb, a, 1));
|
||||
#endif
|
||||
case MRB_TT_COMPLEX:
|
||||
x = complex_new(mrb, (mrb_float)a, 0);
|
||||
return complex_div(mrb, x);
|
||||
default:
|
||||
return mrb_float_value(mrb, mrb_div_float((mrb_float)a, mrb_as_float(mrb, y)));
|
||||
}
|
||||
}
|
||||
|
||||
/* 15.2.9.3.19(x) */
|
||||
/*
|
||||
* redefine Integer#quo
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
cpx_int_quo(mrb_state *mrb, mrb_value x)
|
||||
{
|
||||
mrb_value y = mrb_get_arg1(mrb);
|
||||
mrb_int a = mrb_integer(x);
|
||||
|
||||
switch (mrb_type(y)) {
|
||||
#ifdef MRB_USE_RATIONAL
|
||||
case MRB_TT_RATIONAL:
|
||||
x = mrb_rational_new(mrb, a, 1);
|
||||
return mrb_funcall_id(mrb, x, MRB_OPSYM(div), 1, y);
|
||||
#endif
|
||||
case MRB_TT_COMPLEX:
|
||||
x = complex_new(mrb, (mrb_float)a, 0);
|
||||
return complex_div(mrb, x);
|
||||
default:
|
||||
return mrb_float_value(mrb, mrb_div_float((mrb_float)a, mrb_as_float(mrb, y)));
|
||||
}
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
cpx_flo_div(mrb_state *mrb, mrb_value x)
|
||||
{
|
||||
mrb_float a = mrb_float(x);
|
||||
mrb_value y = mrb_get_arg1(mrb);
|
||||
|
||||
switch(mrb_type(y)) {
|
||||
case MRB_TT_COMPLEX:
|
||||
return complex_div(mrb, complex_new(mrb, a, 0));
|
||||
case MRB_TT_FLOAT:
|
||||
a = mrb_div_float(a, mrb_float(y));
|
||||
return mrb_float_value(mrb, a);
|
||||
default:
|
||||
a = mrb_div_float(a, mrb_as_float(mrb, y));
|
||||
return mrb_float_value(mrb, a);
|
||||
}
|
||||
return mrb_complex_div(mrb, x, y);
|
||||
}
|
||||
|
||||
void mrb_mruby_complex_gem_init(mrb_state *mrb)
|
||||
@@ -424,10 +374,6 @@ void mrb_mruby_complex_gem_init(mrb_state *mrb)
|
||||
mrb_define_method(mrb, comp, "/", complex_div, MRB_ARGS_REQ(1));
|
||||
mrb_define_method(mrb, comp, "quo", complex_div, MRB_ARGS_REQ(1));
|
||||
mrb_define_method(mrb, comp, "==", complex_eq, MRB_ARGS_REQ(1));
|
||||
mrb_define_method(mrb, mrb->integer_class, "/", cpx_int_div, MRB_ARGS_REQ(1)); /* override */
|
||||
mrb_define_method(mrb, mrb->integer_class, "quo", cpx_int_quo, MRB_ARGS_REQ(1)); /* override */
|
||||
mrb_define_method(mrb, mrb->float_class, "/", cpx_flo_div, MRB_ARGS_REQ(1)); /* override */
|
||||
mrb_define_method(mrb, mrb->float_class, "quo", cpx_flo_div, MRB_ARGS_REQ(1)); /* override */
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
/tmp
|
||||
@@ -0,0 +1,2 @@
|
||||
script:
|
||||
- "ruby run_test.rb all test"
|
||||
@@ -0,0 +1,25 @@
|
||||
# mruby-errno
|
||||
|
||||
Errno module for mruby
|
||||
|
||||
## License
|
||||
|
||||
Copyright (c) 2013 Internet Initiative Japan Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
@@ -0,0 +1,6 @@
|
||||
MRuby::Gem::Specification.new('mruby-errno') do |spec|
|
||||
spec.license = 'MIT'
|
||||
spec.authors = 'Internet Initiative Japan Inc.'
|
||||
|
||||
spec.cc.include_paths << "#{build.root}/src"
|
||||
end
|
||||
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env ruby
|
||||
#
|
||||
# mrbgems test runner
|
||||
#
|
||||
|
||||
gemname = File.basename(File.dirname(File.expand_path __FILE__))
|
||||
|
||||
if __FILE__ == $0
|
||||
repository, dir = 'https://github.com/mruby/mruby.git', 'tmp/mruby'
|
||||
build_args = ARGV
|
||||
build_args = ['all', 'test'] if build_args.nil? or build_args.empty?
|
||||
|
||||
Dir.mkdir 'tmp' unless File.exist?('tmp')
|
||||
unless File.exist?(dir)
|
||||
system "git clone #{repository} #{dir}"
|
||||
end
|
||||
|
||||
exit system(%Q[cd #{dir}; MRUBY_CONFIG=#{File.expand_path __FILE__} ruby minirake #{build_args.join(' ')}])
|
||||
end
|
||||
|
||||
MRuby::Build.new do |conf|
|
||||
toolchain :gcc
|
||||
conf.gembox 'default'
|
||||
|
||||
conf.gem File.expand_path(File.dirname(__FILE__))
|
||||
end
|
||||
@@ -0,0 +1,191 @@
|
||||
#include "mruby.h"
|
||||
#include "mruby/array.h"
|
||||
#include "mruby/class.h"
|
||||
#include "mruby/error.h"
|
||||
#include "mruby/hash.h"
|
||||
#include "mruby/numeric.h"
|
||||
#include "mruby/string.h"
|
||||
#include "mruby/variable.h"
|
||||
#include "mruby/internal.h"
|
||||
#include <mruby/presym.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
static const struct {
|
||||
#ifdef MRB_NO_PRESYM
|
||||
#define itsdefined(name, sym) { #name, name },
|
||||
const char *name;
|
||||
#else
|
||||
#define itsdefined(name, sym) { sym, name },
|
||||
mrb_sym sym;
|
||||
#endif
|
||||
int eno;
|
||||
} e2c[] = {
|
||||
#define itsnotdefined(name, sym)
|
||||
#include "known_errors_def.cstub"
|
||||
#undef itsdefined
|
||||
#undef itsnotdefined
|
||||
};
|
||||
|
||||
#ifdef MRB_NO_PRESYM
|
||||
#define ENTRY_SYM(e) mrb_intern_static(mrb, (e).name, strlen((e).name))
|
||||
#else
|
||||
#define ENTRY_SYM(e) (e).sym
|
||||
#endif
|
||||
|
||||
#define E2C_LEN (sizeof(e2c) / sizeof(e2c[0]))
|
||||
|
||||
static void
|
||||
mrb_sce_init(mrb_state *mrb, mrb_value self, mrb_value m, int n)
|
||||
{
|
||||
mrb_value str;
|
||||
struct RClass *m_errno;
|
||||
int no_errno = (n < 0);
|
||||
char buf[20];
|
||||
|
||||
m_errno = mrb_module_get_id(mrb, MRB_SYM(Errno));
|
||||
if (!no_errno) {
|
||||
size_t i;
|
||||
|
||||
for (i=0; i < E2C_LEN; i++) {
|
||||
if (e2c[i].eno == n) {
|
||||
mrb_basic_ptr(self)->c = mrb_class_get_under_id(mrb, m_errno, ENTRY_SYM(e2c[i]));
|
||||
str = mrb_str_new_cstr(mrb, strerror(n));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == E2C_LEN) {
|
||||
mrb_iv_set(mrb, self, MRB_SYM(errno), mrb_fixnum_value(n));
|
||||
str = mrb_str_new_cstr(mrb, "Unknown error: ");
|
||||
char *bp = mrb_int_to_cstr(buf, sizeof(buf), n, 10);
|
||||
mrb_str_cat2(mrb, str, bp);
|
||||
}
|
||||
}
|
||||
else {
|
||||
str = mrb_str_new_cstr(mrb, "unknown error");
|
||||
}
|
||||
if (!mrb_nil_p(m)) {
|
||||
mrb_str_cat2(mrb, str, " - ");
|
||||
mrb_str_append(mrb, str, m);
|
||||
}
|
||||
mrb_exc_mesg_set(mrb, mrb_exc_ptr(self), str);
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
mrb_sce_init_m(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value m;
|
||||
mrb_int n;
|
||||
|
||||
if (mrb_get_args(mrb, "o|i", &m, &n) == 1) {
|
||||
if (mrb_fixnum_p(m)) {
|
||||
n = mrb_fixnum(m);
|
||||
m = mrb_nil_value();
|
||||
}
|
||||
else {
|
||||
n = -1;
|
||||
}
|
||||
}
|
||||
mrb_sce_init(mrb, self, m, (int)n);
|
||||
return self;
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
mrb_sce_errno(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
struct RClass *c;
|
||||
mrb_sym sym;
|
||||
|
||||
c = mrb_class(mrb, self);
|
||||
sym = MRB_SYM(Errno);
|
||||
if (mrb_const_defined_at(mrb, mrb_obj_value(c), sym)) {
|
||||
return mrb_const_get(mrb, mrb_obj_value(c), sym);
|
||||
} else {
|
||||
sym = MRB_SYM(errno);
|
||||
return mrb_attr_get(mrb, self, sym);
|
||||
}
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
mrb_sce_sys_fail(mrb_state *mrb, mrb_value cls)
|
||||
{
|
||||
struct RClass *sce;
|
||||
mrb_value msg;
|
||||
mrb_int no = -1;
|
||||
mrb_int argc;
|
||||
|
||||
mrb->c->ci->mid = 0;
|
||||
sce = mrb_class_get_id(mrb, MRB_SYM(SystemCallError));
|
||||
argc = mrb_get_args(mrb, "i|S", &no, &msg);
|
||||
|
||||
struct RBasic* e = mrb_obj_alloc(mrb, MRB_TT_EXCEPTION, sce);
|
||||
mrb_value exc = mrb_obj_value(e);
|
||||
if (argc == 1) {
|
||||
msg = mrb_nil_value();
|
||||
}
|
||||
exc = mrb_obj_value(e);
|
||||
mrb_sce_init(mrb, exc, msg, (int)no);
|
||||
mrb_exc_raise(mrb, exc);
|
||||
return mrb_nil_value(); /* NOTREACHED */
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
mrb_exxx_init(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value m, no, str;
|
||||
|
||||
no = mrb_const_get(mrb, mrb_obj_value(mrb_class(mrb, self)), MRB_SYM(Errno));
|
||||
str = mrb_str_new_cstr(mrb, strerror((int)mrb_fixnum(no)));
|
||||
|
||||
m = mrb_nil_value();
|
||||
mrb_get_args(mrb, "|S", &m);
|
||||
if (!mrb_nil_p(m)) {
|
||||
mrb_str_cat2(mrb, str, " - ");
|
||||
mrb_str_append(mrb, str, m);
|
||||
}
|
||||
mrb_exc_mesg_set(mrb, mrb_exc_ptr(self), str);
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
mrb_mruby_errno_gem_init(mrb_state *mrb)
|
||||
{
|
||||
struct RClass *e, *eno, *sce, *ste;
|
||||
mrb_value noerror;
|
||||
|
||||
ste = mrb_class_get_id(mrb, MRB_SYM(StandardError));
|
||||
|
||||
sce = mrb_define_class(mrb, "SystemCallError", ste);
|
||||
mrb_define_class_method(mrb, sce, "_sys_fail", mrb_sce_sys_fail, MRB_ARGS_REQ(1));
|
||||
mrb_define_method(mrb, sce, "errno", mrb_sce_errno, MRB_ARGS_NONE());
|
||||
mrb_define_method(mrb, sce, "initialize", mrb_sce_init_m, MRB_ARGS_ARG(1, 1));
|
||||
|
||||
eno = mrb_define_module_id(mrb, MRB_SYM(Errno));
|
||||
|
||||
e = mrb_define_class_under_id(mrb, eno, MRB_SYM(NOERROR), sce);
|
||||
mrb_define_const_id(mrb, e, MRB_SYM(Errno), mrb_fixnum_value(0));
|
||||
mrb_define_method(mrb, e, "initialize", mrb_exxx_init, MRB_ARGS_OPT(1));
|
||||
//mrb_define_method(mrb, e, "===", mrb_exxx_cmp, MRB_ARGS_REQ(1));
|
||||
noerror = mrb_obj_value(e);
|
||||
|
||||
#define itsdefined(name, sym) \
|
||||
do { \
|
||||
int ai = mrb_gc_arena_save(mrb); \
|
||||
e = mrb_define_class_under_id(mrb, eno, sym, sce); \
|
||||
mrb_define_const_id(mrb, e, MRB_SYM(Errno), mrb_fixnum_value(name)); \
|
||||
mrb_define_method(mrb, e, "initialize", mrb_exxx_init, MRB_ARGS_OPT(1)); \
|
||||
mrb_gc_arena_restore(mrb, ai); \
|
||||
} while (0);
|
||||
|
||||
#define itsnotdefined(name, sym) \
|
||||
do { \
|
||||
mrb_define_const_id(mrb, eno, sym, noerror); \
|
||||
} while (0);
|
||||
|
||||
#include "known_errors_def.cstub"
|
||||
}
|
||||
|
||||
void
|
||||
mrb_mruby_errno_gem_final(mrb_state *mrb)
|
||||
{
|
||||
}
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
Dir.chdir(File.dirname($0))
|
||||
|
||||
d = File.open("known_errors_def.cstub", "w")
|
||||
|
||||
IO.readlines("known_errors.def").each { |name|
|
||||
next if name =~ /^#/
|
||||
name.strip!
|
||||
|
||||
d.write <<CODE
|
||||
#ifdef #{name}
|
||||
itsdefined(#{name}, MRB_SYM(#{name}))
|
||||
#else
|
||||
itsnotdefined(#{name}, MRB_SYM(#{name}))
|
||||
#endif
|
||||
CODE
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
EPERM
|
||||
ENOENT
|
||||
ESRCH
|
||||
EINTR
|
||||
EIO
|
||||
ENXIO
|
||||
E2BIG
|
||||
ENOEXEC
|
||||
EBADF
|
||||
ECHILD
|
||||
EAGAIN
|
||||
ENOMEM
|
||||
EACCES
|
||||
EFAULT
|
||||
ENOTBLK
|
||||
EBUSY
|
||||
EEXIST
|
||||
EXDEV
|
||||
ENODEV
|
||||
ENOTDIR
|
||||
EISDIR
|
||||
EINVAL
|
||||
ENFILE
|
||||
EMFILE
|
||||
ENOTTY
|
||||
ETXTBSY
|
||||
EFBIG
|
||||
ENOSPC
|
||||
ESPIPE
|
||||
EROFS
|
||||
EMLINK
|
||||
EPIPE
|
||||
EDOM
|
||||
ERANGE
|
||||
EDEADLK
|
||||
ENAMETOOLONG
|
||||
ENOLCK
|
||||
ENOSYS
|
||||
ENOTEMPTY
|
||||
ELOOP
|
||||
EWOULDBLOCK
|
||||
ENOMSG
|
||||
EIDRM
|
||||
ECHRNG
|
||||
EL2NSYNC
|
||||
EL3HLT
|
||||
EL3RST
|
||||
ELNRNG
|
||||
EUNATCH
|
||||
ENOCSI
|
||||
EL2HLT
|
||||
EBADE
|
||||
EBADR
|
||||
EXFULL
|
||||
ENOANO
|
||||
EBADRQC
|
||||
EBADSLT
|
||||
EDEADLOCK
|
||||
EBFONT
|
||||
ENOSTR
|
||||
ENODATA
|
||||
ETIME
|
||||
ENOSR
|
||||
ENONET
|
||||
ENOPKG
|
||||
EREMOTE
|
||||
ENOLINK
|
||||
EADV
|
||||
ESRMNT
|
||||
ECOMM
|
||||
EPROTO
|
||||
ENOTCAPABLE
|
||||
ECAPMODE
|
||||
EMULTIHOP
|
||||
EDOTDOT
|
||||
EBADMSG
|
||||
EPWROFF
|
||||
EDEVERR
|
||||
EOVERFLOW
|
||||
EBADEXEC
|
||||
EBADARCH
|
||||
EBADMACHO
|
||||
ESHLIBVERS
|
||||
ENOTUNIQ
|
||||
EBADFD
|
||||
EREMCHG
|
||||
ELIBACC
|
||||
ELIBBAD
|
||||
ELIBSCN
|
||||
ELIBMAX
|
||||
ELIBEXEC
|
||||
EILSEQ
|
||||
ERESTART
|
||||
ESTRPIPE
|
||||
EUSERS
|
||||
ENOTSOCK
|
||||
EDESTADDRREQ
|
||||
EMSGSIZE
|
||||
EPROTOTYPE
|
||||
ENOPROTOOPT
|
||||
EPROTONOSUPPORT
|
||||
ESOCKTNOSUPPORT
|
||||
EOPNOTSUPP
|
||||
EPFNOSUPPORT
|
||||
EAFNOSUPPORT
|
||||
EADDRINUSE
|
||||
EADDRNOTAVAIL
|
||||
ENETDOWN
|
||||
ENETUNREACH
|
||||
ENETRESET
|
||||
ECONNABORTED
|
||||
ECONNRESET
|
||||
ENOBUFS
|
||||
EISCONN
|
||||
ENOTCONN
|
||||
ESHUTDOWN
|
||||
ETOOMANYREFS
|
||||
ETIMEDOUT
|
||||
ECONNREFUSED
|
||||
EHOSTDOWN
|
||||
EHOSTUNREACH
|
||||
EALREADY
|
||||
EINPROGRESS
|
||||
ESTALE
|
||||
EUCLEAN
|
||||
ENOTNAM
|
||||
ENAVAIL
|
||||
EISNAM
|
||||
EREMOTEIO
|
||||
EDQUOT
|
||||
ECANCELED
|
||||
EKEYEXPIRED
|
||||
EKEYREJECTED
|
||||
EKEYREVOKED
|
||||
EMEDIUMTYPE
|
||||
ENOKEY
|
||||
ENOMEDIUM
|
||||
ENOTRECOVERABLE
|
||||
EOWNERDEAD
|
||||
EINTEGRITY
|
||||
ERFKILL
|
||||
EAUTH
|
||||
EBADRPC
|
||||
EDOOFUS
|
||||
EFTYPE
|
||||
ENEEDAUTH
|
||||
ENOATTR
|
||||
ENOTSUP
|
||||
EPROCLIM
|
||||
EPROCUNAVAIL
|
||||
EPROGMISMATCH
|
||||
EPROGUNAVAIL
|
||||
ERPCMISMATCH
|
||||
EIPSEC
|
||||
ENOPOLICY
|
||||
EQFULL
|
||||
@@ -0,0 +1,780 @@
|
||||
#ifdef EPERM
|
||||
itsdefined(EPERM, MRB_SYM(EPERM))
|
||||
#else
|
||||
itsnotdefined(EPERM, MRB_SYM(EPERM))
|
||||
#endif
|
||||
#ifdef ENOENT
|
||||
itsdefined(ENOENT, MRB_SYM(ENOENT))
|
||||
#else
|
||||
itsnotdefined(ENOENT, MRB_SYM(ENOENT))
|
||||
#endif
|
||||
#ifdef ESRCH
|
||||
itsdefined(ESRCH, MRB_SYM(ESRCH))
|
||||
#else
|
||||
itsnotdefined(ESRCH, MRB_SYM(ESRCH))
|
||||
#endif
|
||||
#ifdef EINTR
|
||||
itsdefined(EINTR, MRB_SYM(EINTR))
|
||||
#else
|
||||
itsnotdefined(EINTR, MRB_SYM(EINTR))
|
||||
#endif
|
||||
#ifdef EIO
|
||||
itsdefined(EIO, MRB_SYM(EIO))
|
||||
#else
|
||||
itsnotdefined(EIO, MRB_SYM(EIO))
|
||||
#endif
|
||||
#ifdef ENXIO
|
||||
itsdefined(ENXIO, MRB_SYM(ENXIO))
|
||||
#else
|
||||
itsnotdefined(ENXIO, MRB_SYM(ENXIO))
|
||||
#endif
|
||||
#ifdef E2BIG
|
||||
itsdefined(E2BIG, MRB_SYM(E2BIG))
|
||||
#else
|
||||
itsnotdefined(E2BIG, MRB_SYM(E2BIG))
|
||||
#endif
|
||||
#ifdef ENOEXEC
|
||||
itsdefined(ENOEXEC, MRB_SYM(ENOEXEC))
|
||||
#else
|
||||
itsnotdefined(ENOEXEC, MRB_SYM(ENOEXEC))
|
||||
#endif
|
||||
#ifdef EBADF
|
||||
itsdefined(EBADF, MRB_SYM(EBADF))
|
||||
#else
|
||||
itsnotdefined(EBADF, MRB_SYM(EBADF))
|
||||
#endif
|
||||
#ifdef ECHILD
|
||||
itsdefined(ECHILD, MRB_SYM(ECHILD))
|
||||
#else
|
||||
itsnotdefined(ECHILD, MRB_SYM(ECHILD))
|
||||
#endif
|
||||
#ifdef EAGAIN
|
||||
itsdefined(EAGAIN, MRB_SYM(EAGAIN))
|
||||
#else
|
||||
itsnotdefined(EAGAIN, MRB_SYM(EAGAIN))
|
||||
#endif
|
||||
#ifdef ENOMEM
|
||||
itsdefined(ENOMEM, MRB_SYM(ENOMEM))
|
||||
#else
|
||||
itsnotdefined(ENOMEM, MRB_SYM(ENOMEM))
|
||||
#endif
|
||||
#ifdef EACCES
|
||||
itsdefined(EACCES, MRB_SYM(EACCES))
|
||||
#else
|
||||
itsnotdefined(EACCES, MRB_SYM(EACCES))
|
||||
#endif
|
||||
#ifdef EFAULT
|
||||
itsdefined(EFAULT, MRB_SYM(EFAULT))
|
||||
#else
|
||||
itsnotdefined(EFAULT, MRB_SYM(EFAULT))
|
||||
#endif
|
||||
#ifdef ENOTBLK
|
||||
itsdefined(ENOTBLK, MRB_SYM(ENOTBLK))
|
||||
#else
|
||||
itsnotdefined(ENOTBLK, MRB_SYM(ENOTBLK))
|
||||
#endif
|
||||
#ifdef EBUSY
|
||||
itsdefined(EBUSY, MRB_SYM(EBUSY))
|
||||
#else
|
||||
itsnotdefined(EBUSY, MRB_SYM(EBUSY))
|
||||
#endif
|
||||
#ifdef EEXIST
|
||||
itsdefined(EEXIST, MRB_SYM(EEXIST))
|
||||
#else
|
||||
itsnotdefined(EEXIST, MRB_SYM(EEXIST))
|
||||
#endif
|
||||
#ifdef EXDEV
|
||||
itsdefined(EXDEV, MRB_SYM(EXDEV))
|
||||
#else
|
||||
itsnotdefined(EXDEV, MRB_SYM(EXDEV))
|
||||
#endif
|
||||
#ifdef ENODEV
|
||||
itsdefined(ENODEV, MRB_SYM(ENODEV))
|
||||
#else
|
||||
itsnotdefined(ENODEV, MRB_SYM(ENODEV))
|
||||
#endif
|
||||
#ifdef ENOTDIR
|
||||
itsdefined(ENOTDIR, MRB_SYM(ENOTDIR))
|
||||
#else
|
||||
itsnotdefined(ENOTDIR, MRB_SYM(ENOTDIR))
|
||||
#endif
|
||||
#ifdef EISDIR
|
||||
itsdefined(EISDIR, MRB_SYM(EISDIR))
|
||||
#else
|
||||
itsnotdefined(EISDIR, MRB_SYM(EISDIR))
|
||||
#endif
|
||||
#ifdef EINVAL
|
||||
itsdefined(EINVAL, MRB_SYM(EINVAL))
|
||||
#else
|
||||
itsnotdefined(EINVAL, MRB_SYM(EINVAL))
|
||||
#endif
|
||||
#ifdef ENFILE
|
||||
itsdefined(ENFILE, MRB_SYM(ENFILE))
|
||||
#else
|
||||
itsnotdefined(ENFILE, MRB_SYM(ENFILE))
|
||||
#endif
|
||||
#ifdef EMFILE
|
||||
itsdefined(EMFILE, MRB_SYM(EMFILE))
|
||||
#else
|
||||
itsnotdefined(EMFILE, MRB_SYM(EMFILE))
|
||||
#endif
|
||||
#ifdef ENOTTY
|
||||
itsdefined(ENOTTY, MRB_SYM(ENOTTY))
|
||||
#else
|
||||
itsnotdefined(ENOTTY, MRB_SYM(ENOTTY))
|
||||
#endif
|
||||
#ifdef ETXTBSY
|
||||
itsdefined(ETXTBSY, MRB_SYM(ETXTBSY))
|
||||
#else
|
||||
itsnotdefined(ETXTBSY, MRB_SYM(ETXTBSY))
|
||||
#endif
|
||||
#ifdef EFBIG
|
||||
itsdefined(EFBIG, MRB_SYM(EFBIG))
|
||||
#else
|
||||
itsnotdefined(EFBIG, MRB_SYM(EFBIG))
|
||||
#endif
|
||||
#ifdef ENOSPC
|
||||
itsdefined(ENOSPC, MRB_SYM(ENOSPC))
|
||||
#else
|
||||
itsnotdefined(ENOSPC, MRB_SYM(ENOSPC))
|
||||
#endif
|
||||
#ifdef ESPIPE
|
||||
itsdefined(ESPIPE, MRB_SYM(ESPIPE))
|
||||
#else
|
||||
itsnotdefined(ESPIPE, MRB_SYM(ESPIPE))
|
||||
#endif
|
||||
#ifdef EROFS
|
||||
itsdefined(EROFS, MRB_SYM(EROFS))
|
||||
#else
|
||||
itsnotdefined(EROFS, MRB_SYM(EROFS))
|
||||
#endif
|
||||
#ifdef EMLINK
|
||||
itsdefined(EMLINK, MRB_SYM(EMLINK))
|
||||
#else
|
||||
itsnotdefined(EMLINK, MRB_SYM(EMLINK))
|
||||
#endif
|
||||
#ifdef EPIPE
|
||||
itsdefined(EPIPE, MRB_SYM(EPIPE))
|
||||
#else
|
||||
itsnotdefined(EPIPE, MRB_SYM(EPIPE))
|
||||
#endif
|
||||
#ifdef EDOM
|
||||
itsdefined(EDOM, MRB_SYM(EDOM))
|
||||
#else
|
||||
itsnotdefined(EDOM, MRB_SYM(EDOM))
|
||||
#endif
|
||||
#ifdef ERANGE
|
||||
itsdefined(ERANGE, MRB_SYM(ERANGE))
|
||||
#else
|
||||
itsnotdefined(ERANGE, MRB_SYM(ERANGE))
|
||||
#endif
|
||||
#ifdef EDEADLK
|
||||
itsdefined(EDEADLK, MRB_SYM(EDEADLK))
|
||||
#else
|
||||
itsnotdefined(EDEADLK, MRB_SYM(EDEADLK))
|
||||
#endif
|
||||
#ifdef ENAMETOOLONG
|
||||
itsdefined(ENAMETOOLONG, MRB_SYM(ENAMETOOLONG))
|
||||
#else
|
||||
itsnotdefined(ENAMETOOLONG, MRB_SYM(ENAMETOOLONG))
|
||||
#endif
|
||||
#ifdef ENOLCK
|
||||
itsdefined(ENOLCK, MRB_SYM(ENOLCK))
|
||||
#else
|
||||
itsnotdefined(ENOLCK, MRB_SYM(ENOLCK))
|
||||
#endif
|
||||
#ifdef ENOSYS
|
||||
itsdefined(ENOSYS, MRB_SYM(ENOSYS))
|
||||
#else
|
||||
itsnotdefined(ENOSYS, MRB_SYM(ENOSYS))
|
||||
#endif
|
||||
#ifdef ENOTEMPTY
|
||||
itsdefined(ENOTEMPTY, MRB_SYM(ENOTEMPTY))
|
||||
#else
|
||||
itsnotdefined(ENOTEMPTY, MRB_SYM(ENOTEMPTY))
|
||||
#endif
|
||||
#ifdef ELOOP
|
||||
itsdefined(ELOOP, MRB_SYM(ELOOP))
|
||||
#else
|
||||
itsnotdefined(ELOOP, MRB_SYM(ELOOP))
|
||||
#endif
|
||||
#ifdef EWOULDBLOCK
|
||||
itsdefined(EWOULDBLOCK, MRB_SYM(EWOULDBLOCK))
|
||||
#else
|
||||
itsnotdefined(EWOULDBLOCK, MRB_SYM(EWOULDBLOCK))
|
||||
#endif
|
||||
#ifdef ENOMSG
|
||||
itsdefined(ENOMSG, MRB_SYM(ENOMSG))
|
||||
#else
|
||||
itsnotdefined(ENOMSG, MRB_SYM(ENOMSG))
|
||||
#endif
|
||||
#ifdef EIDRM
|
||||
itsdefined(EIDRM, MRB_SYM(EIDRM))
|
||||
#else
|
||||
itsnotdefined(EIDRM, MRB_SYM(EIDRM))
|
||||
#endif
|
||||
#ifdef ECHRNG
|
||||
itsdefined(ECHRNG, MRB_SYM(ECHRNG))
|
||||
#else
|
||||
itsnotdefined(ECHRNG, MRB_SYM(ECHRNG))
|
||||
#endif
|
||||
#ifdef EL2NSYNC
|
||||
itsdefined(EL2NSYNC, MRB_SYM(EL2NSYNC))
|
||||
#else
|
||||
itsnotdefined(EL2NSYNC, MRB_SYM(EL2NSYNC))
|
||||
#endif
|
||||
#ifdef EL3HLT
|
||||
itsdefined(EL3HLT, MRB_SYM(EL3HLT))
|
||||
#else
|
||||
itsnotdefined(EL3HLT, MRB_SYM(EL3HLT))
|
||||
#endif
|
||||
#ifdef EL3RST
|
||||
itsdefined(EL3RST, MRB_SYM(EL3RST))
|
||||
#else
|
||||
itsnotdefined(EL3RST, MRB_SYM(EL3RST))
|
||||
#endif
|
||||
#ifdef ELNRNG
|
||||
itsdefined(ELNRNG, MRB_SYM(ELNRNG))
|
||||
#else
|
||||
itsnotdefined(ELNRNG, MRB_SYM(ELNRNG))
|
||||
#endif
|
||||
#ifdef EUNATCH
|
||||
itsdefined(EUNATCH, MRB_SYM(EUNATCH))
|
||||
#else
|
||||
itsnotdefined(EUNATCH, MRB_SYM(EUNATCH))
|
||||
#endif
|
||||
#ifdef ENOCSI
|
||||
itsdefined(ENOCSI, MRB_SYM(ENOCSI))
|
||||
#else
|
||||
itsnotdefined(ENOCSI, MRB_SYM(ENOCSI))
|
||||
#endif
|
||||
#ifdef EL2HLT
|
||||
itsdefined(EL2HLT, MRB_SYM(EL2HLT))
|
||||
#else
|
||||
itsnotdefined(EL2HLT, MRB_SYM(EL2HLT))
|
||||
#endif
|
||||
#ifdef EBADE
|
||||
itsdefined(EBADE, MRB_SYM(EBADE))
|
||||
#else
|
||||
itsnotdefined(EBADE, MRB_SYM(EBADE))
|
||||
#endif
|
||||
#ifdef EBADR
|
||||
itsdefined(EBADR, MRB_SYM(EBADR))
|
||||
#else
|
||||
itsnotdefined(EBADR, MRB_SYM(EBADR))
|
||||
#endif
|
||||
#ifdef EXFULL
|
||||
itsdefined(EXFULL, MRB_SYM(EXFULL))
|
||||
#else
|
||||
itsnotdefined(EXFULL, MRB_SYM(EXFULL))
|
||||
#endif
|
||||
#ifdef ENOANO
|
||||
itsdefined(ENOANO, MRB_SYM(ENOANO))
|
||||
#else
|
||||
itsnotdefined(ENOANO, MRB_SYM(ENOANO))
|
||||
#endif
|
||||
#ifdef EBADRQC
|
||||
itsdefined(EBADRQC, MRB_SYM(EBADRQC))
|
||||
#else
|
||||
itsnotdefined(EBADRQC, MRB_SYM(EBADRQC))
|
||||
#endif
|
||||
#ifdef EBADSLT
|
||||
itsdefined(EBADSLT, MRB_SYM(EBADSLT))
|
||||
#else
|
||||
itsnotdefined(EBADSLT, MRB_SYM(EBADSLT))
|
||||
#endif
|
||||
#ifdef EDEADLOCK
|
||||
itsdefined(EDEADLOCK, MRB_SYM(EDEADLOCK))
|
||||
#else
|
||||
itsnotdefined(EDEADLOCK, MRB_SYM(EDEADLOCK))
|
||||
#endif
|
||||
#ifdef EBFONT
|
||||
itsdefined(EBFONT, MRB_SYM(EBFONT))
|
||||
#else
|
||||
itsnotdefined(EBFONT, MRB_SYM(EBFONT))
|
||||
#endif
|
||||
#ifdef ENOSTR
|
||||
itsdefined(ENOSTR, MRB_SYM(ENOSTR))
|
||||
#else
|
||||
itsnotdefined(ENOSTR, MRB_SYM(ENOSTR))
|
||||
#endif
|
||||
#ifdef ENODATA
|
||||
itsdefined(ENODATA, MRB_SYM(ENODATA))
|
||||
#else
|
||||
itsnotdefined(ENODATA, MRB_SYM(ENODATA))
|
||||
#endif
|
||||
#ifdef ETIME
|
||||
itsdefined(ETIME, MRB_SYM(ETIME))
|
||||
#else
|
||||
itsnotdefined(ETIME, MRB_SYM(ETIME))
|
||||
#endif
|
||||
#ifdef ENOSR
|
||||
itsdefined(ENOSR, MRB_SYM(ENOSR))
|
||||
#else
|
||||
itsnotdefined(ENOSR, MRB_SYM(ENOSR))
|
||||
#endif
|
||||
#ifdef ENONET
|
||||
itsdefined(ENONET, MRB_SYM(ENONET))
|
||||
#else
|
||||
itsnotdefined(ENONET, MRB_SYM(ENONET))
|
||||
#endif
|
||||
#ifdef ENOPKG
|
||||
itsdefined(ENOPKG, MRB_SYM(ENOPKG))
|
||||
#else
|
||||
itsnotdefined(ENOPKG, MRB_SYM(ENOPKG))
|
||||
#endif
|
||||
#ifdef EREMOTE
|
||||
itsdefined(EREMOTE, MRB_SYM(EREMOTE))
|
||||
#else
|
||||
itsnotdefined(EREMOTE, MRB_SYM(EREMOTE))
|
||||
#endif
|
||||
#ifdef ENOLINK
|
||||
itsdefined(ENOLINK, MRB_SYM(ENOLINK))
|
||||
#else
|
||||
itsnotdefined(ENOLINK, MRB_SYM(ENOLINK))
|
||||
#endif
|
||||
#ifdef EADV
|
||||
itsdefined(EADV, MRB_SYM(EADV))
|
||||
#else
|
||||
itsnotdefined(EADV, MRB_SYM(EADV))
|
||||
#endif
|
||||
#ifdef ESRMNT
|
||||
itsdefined(ESRMNT, MRB_SYM(ESRMNT))
|
||||
#else
|
||||
itsnotdefined(ESRMNT, MRB_SYM(ESRMNT))
|
||||
#endif
|
||||
#ifdef ECOMM
|
||||
itsdefined(ECOMM, MRB_SYM(ECOMM))
|
||||
#else
|
||||
itsnotdefined(ECOMM, MRB_SYM(ECOMM))
|
||||
#endif
|
||||
#ifdef EPROTO
|
||||
itsdefined(EPROTO, MRB_SYM(EPROTO))
|
||||
#else
|
||||
itsnotdefined(EPROTO, MRB_SYM(EPROTO))
|
||||
#endif
|
||||
#ifdef ENOTCAPABLE
|
||||
itsdefined(ENOTCAPABLE, MRB_SYM(ENOTCAPABLE))
|
||||
#else
|
||||
itsnotdefined(ENOTCAPABLE, MRB_SYM(ENOTCAPABLE))
|
||||
#endif
|
||||
#ifdef ECAPMODE
|
||||
itsdefined(ECAPMODE, MRB_SYM(ECAPMODE))
|
||||
#else
|
||||
itsnotdefined(ECAPMODE, MRB_SYM(ECAPMODE))
|
||||
#endif
|
||||
#ifdef EMULTIHOP
|
||||
itsdefined(EMULTIHOP, MRB_SYM(EMULTIHOP))
|
||||
#else
|
||||
itsnotdefined(EMULTIHOP, MRB_SYM(EMULTIHOP))
|
||||
#endif
|
||||
#ifdef EDOTDOT
|
||||
itsdefined(EDOTDOT, MRB_SYM(EDOTDOT))
|
||||
#else
|
||||
itsnotdefined(EDOTDOT, MRB_SYM(EDOTDOT))
|
||||
#endif
|
||||
#ifdef EBADMSG
|
||||
itsdefined(EBADMSG, MRB_SYM(EBADMSG))
|
||||
#else
|
||||
itsnotdefined(EBADMSG, MRB_SYM(EBADMSG))
|
||||
#endif
|
||||
#ifdef EPWROFF
|
||||
itsdefined(EPWROFF, MRB_SYM(EPWROFF))
|
||||
#else
|
||||
itsnotdefined(EPWROFF, MRB_SYM(EPWROFF))
|
||||
#endif
|
||||
#ifdef EDEVERR
|
||||
itsdefined(EDEVERR, MRB_SYM(EDEVERR))
|
||||
#else
|
||||
itsnotdefined(EDEVERR, MRB_SYM(EDEVERR))
|
||||
#endif
|
||||
#ifdef EOVERFLOW
|
||||
itsdefined(EOVERFLOW, MRB_SYM(EOVERFLOW))
|
||||
#else
|
||||
itsnotdefined(EOVERFLOW, MRB_SYM(EOVERFLOW))
|
||||
#endif
|
||||
#ifdef EBADEXEC
|
||||
itsdefined(EBADEXEC, MRB_SYM(EBADEXEC))
|
||||
#else
|
||||
itsnotdefined(EBADEXEC, MRB_SYM(EBADEXEC))
|
||||
#endif
|
||||
#ifdef EBADARCH
|
||||
itsdefined(EBADARCH, MRB_SYM(EBADARCH))
|
||||
#else
|
||||
itsnotdefined(EBADARCH, MRB_SYM(EBADARCH))
|
||||
#endif
|
||||
#ifdef EBADMACHO
|
||||
itsdefined(EBADMACHO, MRB_SYM(EBADMACHO))
|
||||
#else
|
||||
itsnotdefined(EBADMACHO, MRB_SYM(EBADMACHO))
|
||||
#endif
|
||||
#ifdef ESHLIBVERS
|
||||
itsdefined(ESHLIBVERS, MRB_SYM(ESHLIBVERS))
|
||||
#else
|
||||
itsnotdefined(ESHLIBVERS, MRB_SYM(ESHLIBVERS))
|
||||
#endif
|
||||
#ifdef ENOTUNIQ
|
||||
itsdefined(ENOTUNIQ, MRB_SYM(ENOTUNIQ))
|
||||
#else
|
||||
itsnotdefined(ENOTUNIQ, MRB_SYM(ENOTUNIQ))
|
||||
#endif
|
||||
#ifdef EBADFD
|
||||
itsdefined(EBADFD, MRB_SYM(EBADFD))
|
||||
#else
|
||||
itsnotdefined(EBADFD, MRB_SYM(EBADFD))
|
||||
#endif
|
||||
#ifdef EREMCHG
|
||||
itsdefined(EREMCHG, MRB_SYM(EREMCHG))
|
||||
#else
|
||||
itsnotdefined(EREMCHG, MRB_SYM(EREMCHG))
|
||||
#endif
|
||||
#ifdef ELIBACC
|
||||
itsdefined(ELIBACC, MRB_SYM(ELIBACC))
|
||||
#else
|
||||
itsnotdefined(ELIBACC, MRB_SYM(ELIBACC))
|
||||
#endif
|
||||
#ifdef ELIBBAD
|
||||
itsdefined(ELIBBAD, MRB_SYM(ELIBBAD))
|
||||
#else
|
||||
itsnotdefined(ELIBBAD, MRB_SYM(ELIBBAD))
|
||||
#endif
|
||||
#ifdef ELIBSCN
|
||||
itsdefined(ELIBSCN, MRB_SYM(ELIBSCN))
|
||||
#else
|
||||
itsnotdefined(ELIBSCN, MRB_SYM(ELIBSCN))
|
||||
#endif
|
||||
#ifdef ELIBMAX
|
||||
itsdefined(ELIBMAX, MRB_SYM(ELIBMAX))
|
||||
#else
|
||||
itsnotdefined(ELIBMAX, MRB_SYM(ELIBMAX))
|
||||
#endif
|
||||
#ifdef ELIBEXEC
|
||||
itsdefined(ELIBEXEC, MRB_SYM(ELIBEXEC))
|
||||
#else
|
||||
itsnotdefined(ELIBEXEC, MRB_SYM(ELIBEXEC))
|
||||
#endif
|
||||
#ifdef EILSEQ
|
||||
itsdefined(EILSEQ, MRB_SYM(EILSEQ))
|
||||
#else
|
||||
itsnotdefined(EILSEQ, MRB_SYM(EILSEQ))
|
||||
#endif
|
||||
#ifdef ERESTART
|
||||
itsdefined(ERESTART, MRB_SYM(ERESTART))
|
||||
#else
|
||||
itsnotdefined(ERESTART, MRB_SYM(ERESTART))
|
||||
#endif
|
||||
#ifdef ESTRPIPE
|
||||
itsdefined(ESTRPIPE, MRB_SYM(ESTRPIPE))
|
||||
#else
|
||||
itsnotdefined(ESTRPIPE, MRB_SYM(ESTRPIPE))
|
||||
#endif
|
||||
#ifdef EUSERS
|
||||
itsdefined(EUSERS, MRB_SYM(EUSERS))
|
||||
#else
|
||||
itsnotdefined(EUSERS, MRB_SYM(EUSERS))
|
||||
#endif
|
||||
#ifdef ENOTSOCK
|
||||
itsdefined(ENOTSOCK, MRB_SYM(ENOTSOCK))
|
||||
#else
|
||||
itsnotdefined(ENOTSOCK, MRB_SYM(ENOTSOCK))
|
||||
#endif
|
||||
#ifdef EDESTADDRREQ
|
||||
itsdefined(EDESTADDRREQ, MRB_SYM(EDESTADDRREQ))
|
||||
#else
|
||||
itsnotdefined(EDESTADDRREQ, MRB_SYM(EDESTADDRREQ))
|
||||
#endif
|
||||
#ifdef EMSGSIZE
|
||||
itsdefined(EMSGSIZE, MRB_SYM(EMSGSIZE))
|
||||
#else
|
||||
itsnotdefined(EMSGSIZE, MRB_SYM(EMSGSIZE))
|
||||
#endif
|
||||
#ifdef EPROTOTYPE
|
||||
itsdefined(EPROTOTYPE, MRB_SYM(EPROTOTYPE))
|
||||
#else
|
||||
itsnotdefined(EPROTOTYPE, MRB_SYM(EPROTOTYPE))
|
||||
#endif
|
||||
#ifdef ENOPROTOOPT
|
||||
itsdefined(ENOPROTOOPT, MRB_SYM(ENOPROTOOPT))
|
||||
#else
|
||||
itsnotdefined(ENOPROTOOPT, MRB_SYM(ENOPROTOOPT))
|
||||
#endif
|
||||
#ifdef EPROTONOSUPPORT
|
||||
itsdefined(EPROTONOSUPPORT, MRB_SYM(EPROTONOSUPPORT))
|
||||
#else
|
||||
itsnotdefined(EPROTONOSUPPORT, MRB_SYM(EPROTONOSUPPORT))
|
||||
#endif
|
||||
#ifdef ESOCKTNOSUPPORT
|
||||
itsdefined(ESOCKTNOSUPPORT, MRB_SYM(ESOCKTNOSUPPORT))
|
||||
#else
|
||||
itsnotdefined(ESOCKTNOSUPPORT, MRB_SYM(ESOCKTNOSUPPORT))
|
||||
#endif
|
||||
#ifdef EOPNOTSUPP
|
||||
itsdefined(EOPNOTSUPP, MRB_SYM(EOPNOTSUPP))
|
||||
#else
|
||||
itsnotdefined(EOPNOTSUPP, MRB_SYM(EOPNOTSUPP))
|
||||
#endif
|
||||
#ifdef EPFNOSUPPORT
|
||||
itsdefined(EPFNOSUPPORT, MRB_SYM(EPFNOSUPPORT))
|
||||
#else
|
||||
itsnotdefined(EPFNOSUPPORT, MRB_SYM(EPFNOSUPPORT))
|
||||
#endif
|
||||
#ifdef EAFNOSUPPORT
|
||||
itsdefined(EAFNOSUPPORT, MRB_SYM(EAFNOSUPPORT))
|
||||
#else
|
||||
itsnotdefined(EAFNOSUPPORT, MRB_SYM(EAFNOSUPPORT))
|
||||
#endif
|
||||
#ifdef EADDRINUSE
|
||||
itsdefined(EADDRINUSE, MRB_SYM(EADDRINUSE))
|
||||
#else
|
||||
itsnotdefined(EADDRINUSE, MRB_SYM(EADDRINUSE))
|
||||
#endif
|
||||
#ifdef EADDRNOTAVAIL
|
||||
itsdefined(EADDRNOTAVAIL, MRB_SYM(EADDRNOTAVAIL))
|
||||
#else
|
||||
itsnotdefined(EADDRNOTAVAIL, MRB_SYM(EADDRNOTAVAIL))
|
||||
#endif
|
||||
#ifdef ENETDOWN
|
||||
itsdefined(ENETDOWN, MRB_SYM(ENETDOWN))
|
||||
#else
|
||||
itsnotdefined(ENETDOWN, MRB_SYM(ENETDOWN))
|
||||
#endif
|
||||
#ifdef ENETUNREACH
|
||||
itsdefined(ENETUNREACH, MRB_SYM(ENETUNREACH))
|
||||
#else
|
||||
itsnotdefined(ENETUNREACH, MRB_SYM(ENETUNREACH))
|
||||
#endif
|
||||
#ifdef ENETRESET
|
||||
itsdefined(ENETRESET, MRB_SYM(ENETRESET))
|
||||
#else
|
||||
itsnotdefined(ENETRESET, MRB_SYM(ENETRESET))
|
||||
#endif
|
||||
#ifdef ECONNABORTED
|
||||
itsdefined(ECONNABORTED, MRB_SYM(ECONNABORTED))
|
||||
#else
|
||||
itsnotdefined(ECONNABORTED, MRB_SYM(ECONNABORTED))
|
||||
#endif
|
||||
#ifdef ECONNRESET
|
||||
itsdefined(ECONNRESET, MRB_SYM(ECONNRESET))
|
||||
#else
|
||||
itsnotdefined(ECONNRESET, MRB_SYM(ECONNRESET))
|
||||
#endif
|
||||
#ifdef ENOBUFS
|
||||
itsdefined(ENOBUFS, MRB_SYM(ENOBUFS))
|
||||
#else
|
||||
itsnotdefined(ENOBUFS, MRB_SYM(ENOBUFS))
|
||||
#endif
|
||||
#ifdef EISCONN
|
||||
itsdefined(EISCONN, MRB_SYM(EISCONN))
|
||||
#else
|
||||
itsnotdefined(EISCONN, MRB_SYM(EISCONN))
|
||||
#endif
|
||||
#ifdef ENOTCONN
|
||||
itsdefined(ENOTCONN, MRB_SYM(ENOTCONN))
|
||||
#else
|
||||
itsnotdefined(ENOTCONN, MRB_SYM(ENOTCONN))
|
||||
#endif
|
||||
#ifdef ESHUTDOWN
|
||||
itsdefined(ESHUTDOWN, MRB_SYM(ESHUTDOWN))
|
||||
#else
|
||||
itsnotdefined(ESHUTDOWN, MRB_SYM(ESHUTDOWN))
|
||||
#endif
|
||||
#ifdef ETOOMANYREFS
|
||||
itsdefined(ETOOMANYREFS, MRB_SYM(ETOOMANYREFS))
|
||||
#else
|
||||
itsnotdefined(ETOOMANYREFS, MRB_SYM(ETOOMANYREFS))
|
||||
#endif
|
||||
#ifdef ETIMEDOUT
|
||||
itsdefined(ETIMEDOUT, MRB_SYM(ETIMEDOUT))
|
||||
#else
|
||||
itsnotdefined(ETIMEDOUT, MRB_SYM(ETIMEDOUT))
|
||||
#endif
|
||||
#ifdef ECONNREFUSED
|
||||
itsdefined(ECONNREFUSED, MRB_SYM(ECONNREFUSED))
|
||||
#else
|
||||
itsnotdefined(ECONNREFUSED, MRB_SYM(ECONNREFUSED))
|
||||
#endif
|
||||
#ifdef EHOSTDOWN
|
||||
itsdefined(EHOSTDOWN, MRB_SYM(EHOSTDOWN))
|
||||
#else
|
||||
itsnotdefined(EHOSTDOWN, MRB_SYM(EHOSTDOWN))
|
||||
#endif
|
||||
#ifdef EHOSTUNREACH
|
||||
itsdefined(EHOSTUNREACH, MRB_SYM(EHOSTUNREACH))
|
||||
#else
|
||||
itsnotdefined(EHOSTUNREACH, MRB_SYM(EHOSTUNREACH))
|
||||
#endif
|
||||
#ifdef EALREADY
|
||||
itsdefined(EALREADY, MRB_SYM(EALREADY))
|
||||
#else
|
||||
itsnotdefined(EALREADY, MRB_SYM(EALREADY))
|
||||
#endif
|
||||
#ifdef EINPROGRESS
|
||||
itsdefined(EINPROGRESS, MRB_SYM(EINPROGRESS))
|
||||
#else
|
||||
itsnotdefined(EINPROGRESS, MRB_SYM(EINPROGRESS))
|
||||
#endif
|
||||
#ifdef ESTALE
|
||||
itsdefined(ESTALE, MRB_SYM(ESTALE))
|
||||
#else
|
||||
itsnotdefined(ESTALE, MRB_SYM(ESTALE))
|
||||
#endif
|
||||
#ifdef EUCLEAN
|
||||
itsdefined(EUCLEAN, MRB_SYM(EUCLEAN))
|
||||
#else
|
||||
itsnotdefined(EUCLEAN, MRB_SYM(EUCLEAN))
|
||||
#endif
|
||||
#ifdef ENOTNAM
|
||||
itsdefined(ENOTNAM, MRB_SYM(ENOTNAM))
|
||||
#else
|
||||
itsnotdefined(ENOTNAM, MRB_SYM(ENOTNAM))
|
||||
#endif
|
||||
#ifdef ENAVAIL
|
||||
itsdefined(ENAVAIL, MRB_SYM(ENAVAIL))
|
||||
#else
|
||||
itsnotdefined(ENAVAIL, MRB_SYM(ENAVAIL))
|
||||
#endif
|
||||
#ifdef EISNAM
|
||||
itsdefined(EISNAM, MRB_SYM(EISNAM))
|
||||
#else
|
||||
itsnotdefined(EISNAM, MRB_SYM(EISNAM))
|
||||
#endif
|
||||
#ifdef EREMOTEIO
|
||||
itsdefined(EREMOTEIO, MRB_SYM(EREMOTEIO))
|
||||
#else
|
||||
itsnotdefined(EREMOTEIO, MRB_SYM(EREMOTEIO))
|
||||
#endif
|
||||
#ifdef EDQUOT
|
||||
itsdefined(EDQUOT, MRB_SYM(EDQUOT))
|
||||
#else
|
||||
itsnotdefined(EDQUOT, MRB_SYM(EDQUOT))
|
||||
#endif
|
||||
#ifdef ECANCELED
|
||||
itsdefined(ECANCELED, MRB_SYM(ECANCELED))
|
||||
#else
|
||||
itsnotdefined(ECANCELED, MRB_SYM(ECANCELED))
|
||||
#endif
|
||||
#ifdef EKEYEXPIRED
|
||||
itsdefined(EKEYEXPIRED, MRB_SYM(EKEYEXPIRED))
|
||||
#else
|
||||
itsnotdefined(EKEYEXPIRED, MRB_SYM(EKEYEXPIRED))
|
||||
#endif
|
||||
#ifdef EKEYREJECTED
|
||||
itsdefined(EKEYREJECTED, MRB_SYM(EKEYREJECTED))
|
||||
#else
|
||||
itsnotdefined(EKEYREJECTED, MRB_SYM(EKEYREJECTED))
|
||||
#endif
|
||||
#ifdef EKEYREVOKED
|
||||
itsdefined(EKEYREVOKED, MRB_SYM(EKEYREVOKED))
|
||||
#else
|
||||
itsnotdefined(EKEYREVOKED, MRB_SYM(EKEYREVOKED))
|
||||
#endif
|
||||
#ifdef EMEDIUMTYPE
|
||||
itsdefined(EMEDIUMTYPE, MRB_SYM(EMEDIUMTYPE))
|
||||
#else
|
||||
itsnotdefined(EMEDIUMTYPE, MRB_SYM(EMEDIUMTYPE))
|
||||
#endif
|
||||
#ifdef ENOKEY
|
||||
itsdefined(ENOKEY, MRB_SYM(ENOKEY))
|
||||
#else
|
||||
itsnotdefined(ENOKEY, MRB_SYM(ENOKEY))
|
||||
#endif
|
||||
#ifdef ENOMEDIUM
|
||||
itsdefined(ENOMEDIUM, MRB_SYM(ENOMEDIUM))
|
||||
#else
|
||||
itsnotdefined(ENOMEDIUM, MRB_SYM(ENOMEDIUM))
|
||||
#endif
|
||||
#ifdef ENOTRECOVERABLE
|
||||
itsdefined(ENOTRECOVERABLE, MRB_SYM(ENOTRECOVERABLE))
|
||||
#else
|
||||
itsnotdefined(ENOTRECOVERABLE, MRB_SYM(ENOTRECOVERABLE))
|
||||
#endif
|
||||
#ifdef EOWNERDEAD
|
||||
itsdefined(EOWNERDEAD, MRB_SYM(EOWNERDEAD))
|
||||
#else
|
||||
itsnotdefined(EOWNERDEAD, MRB_SYM(EOWNERDEAD))
|
||||
#endif
|
||||
#ifdef EINTEGRITY
|
||||
itsdefined(EINTEGRITY, MRB_SYM(EINTEGRITY))
|
||||
#else
|
||||
itsnotdefined(EINTEGRITY, MRB_SYM(EINTEGRITY))
|
||||
#endif
|
||||
#ifdef ERFKILL
|
||||
itsdefined(ERFKILL, MRB_SYM(ERFKILL))
|
||||
#else
|
||||
itsnotdefined(ERFKILL, MRB_SYM(ERFKILL))
|
||||
#endif
|
||||
#ifdef EAUTH
|
||||
itsdefined(EAUTH, MRB_SYM(EAUTH))
|
||||
#else
|
||||
itsnotdefined(EAUTH, MRB_SYM(EAUTH))
|
||||
#endif
|
||||
#ifdef EBADRPC
|
||||
itsdefined(EBADRPC, MRB_SYM(EBADRPC))
|
||||
#else
|
||||
itsnotdefined(EBADRPC, MRB_SYM(EBADRPC))
|
||||
#endif
|
||||
#ifdef EDOOFUS
|
||||
itsdefined(EDOOFUS, MRB_SYM(EDOOFUS))
|
||||
#else
|
||||
itsnotdefined(EDOOFUS, MRB_SYM(EDOOFUS))
|
||||
#endif
|
||||
#ifdef EFTYPE
|
||||
itsdefined(EFTYPE, MRB_SYM(EFTYPE))
|
||||
#else
|
||||
itsnotdefined(EFTYPE, MRB_SYM(EFTYPE))
|
||||
#endif
|
||||
#ifdef ENEEDAUTH
|
||||
itsdefined(ENEEDAUTH, MRB_SYM(ENEEDAUTH))
|
||||
#else
|
||||
itsnotdefined(ENEEDAUTH, MRB_SYM(ENEEDAUTH))
|
||||
#endif
|
||||
#ifdef ENOATTR
|
||||
itsdefined(ENOATTR, MRB_SYM(ENOATTR))
|
||||
#else
|
||||
itsnotdefined(ENOATTR, MRB_SYM(ENOATTR))
|
||||
#endif
|
||||
#ifdef ENOTSUP
|
||||
itsdefined(ENOTSUP, MRB_SYM(ENOTSUP))
|
||||
#else
|
||||
itsnotdefined(ENOTSUP, MRB_SYM(ENOTSUP))
|
||||
#endif
|
||||
#ifdef EPROCLIM
|
||||
itsdefined(EPROCLIM, MRB_SYM(EPROCLIM))
|
||||
#else
|
||||
itsnotdefined(EPROCLIM, MRB_SYM(EPROCLIM))
|
||||
#endif
|
||||
#ifdef EPROCUNAVAIL
|
||||
itsdefined(EPROCUNAVAIL, MRB_SYM(EPROCUNAVAIL))
|
||||
#else
|
||||
itsnotdefined(EPROCUNAVAIL, MRB_SYM(EPROCUNAVAIL))
|
||||
#endif
|
||||
#ifdef EPROGMISMATCH
|
||||
itsdefined(EPROGMISMATCH, MRB_SYM(EPROGMISMATCH))
|
||||
#else
|
||||
itsnotdefined(EPROGMISMATCH, MRB_SYM(EPROGMISMATCH))
|
||||
#endif
|
||||
#ifdef EPROGUNAVAIL
|
||||
itsdefined(EPROGUNAVAIL, MRB_SYM(EPROGUNAVAIL))
|
||||
#else
|
||||
itsnotdefined(EPROGUNAVAIL, MRB_SYM(EPROGUNAVAIL))
|
||||
#endif
|
||||
#ifdef ERPCMISMATCH
|
||||
itsdefined(ERPCMISMATCH, MRB_SYM(ERPCMISMATCH))
|
||||
#else
|
||||
itsnotdefined(ERPCMISMATCH, MRB_SYM(ERPCMISMATCH))
|
||||
#endif
|
||||
#ifdef EIPSEC
|
||||
itsdefined(EIPSEC, MRB_SYM(EIPSEC))
|
||||
#else
|
||||
itsnotdefined(EIPSEC, MRB_SYM(EIPSEC))
|
||||
#endif
|
||||
#ifdef ENOPOLICY
|
||||
itsdefined(ENOPOLICY, MRB_SYM(ENOPOLICY))
|
||||
#else
|
||||
itsnotdefined(ENOPOLICY, MRB_SYM(ENOPOLICY))
|
||||
#endif
|
||||
#ifdef EQFULL
|
||||
itsdefined(EQFULL, MRB_SYM(EQFULL))
|
||||
#else
|
||||
itsnotdefined(EQFULL, MRB_SYM(EQFULL))
|
||||
#endif
|
||||
@@ -0,0 +1,58 @@
|
||||
assert('Errno') do
|
||||
assert_equal(Module, Errno.class)
|
||||
end
|
||||
|
||||
assert('SystemCallError') do
|
||||
assert_equal(Class, SystemCallError.class)
|
||||
end
|
||||
|
||||
assert('SystemCallError superclass') do
|
||||
assert_equal(StandardError, SystemCallError.superclass)
|
||||
end
|
||||
|
||||
assert('SystemCallError#initialize') do
|
||||
assert_equal("unknown error - a", SystemCallError.new("a").message)
|
||||
assert_equal("Unknown error: 12345 - a", SystemCallError.new("a", 12345).message)
|
||||
assert_equal("Unknown error: 12345", SystemCallError.new(12345).message)
|
||||
end
|
||||
|
||||
assert('SystemCallError#errno') do
|
||||
assert_equal 1, SystemCallError.new("a", 1).errno
|
||||
assert_equal 1, SystemCallError.new(1).errno
|
||||
assert_equal 12345, SystemCallError.new("a", 12345).errno
|
||||
assert_equal 23456, SystemCallError.new(23456).errno
|
||||
end
|
||||
|
||||
assert('SystemCallError#inspect') do
|
||||
assert_equal("unknown error - a (SystemCallError)", SystemCallError.new("a").inspect)
|
||||
end
|
||||
|
||||
assert('Errno::NOERROR') do
|
||||
assert_equal(Class, Errno::NOERROR.class)
|
||||
end
|
||||
|
||||
# Is there any platform does not have EPERM?
|
||||
assert('Errno::EPERM') do
|
||||
assert_equal(Class, Errno::EPERM.class)
|
||||
end
|
||||
|
||||
assert('Errno::EPERM superclass') do
|
||||
assert_equal(SystemCallError, Errno::EPERM.superclass)
|
||||
end
|
||||
|
||||
assert('Errno::EPERM::Errno') do
|
||||
assert_true(Errno::EPERM::Errno.is_a?(Fixnum))
|
||||
end
|
||||
|
||||
assert('Errno::EPERM#message') do
|
||||
msg = Errno::EPERM.new.message
|
||||
assert_equal("#{msg} - a", Errno::EPERM.new("a").message)
|
||||
end
|
||||
|
||||
assert('Errno::EPERM#inspect') do
|
||||
msg = Errno::EPERM.new.message
|
||||
assert_equal("#{msg} (Errno::EPERM)", Errno::EPERM.new.inspect)
|
||||
|
||||
msg = Errno::EPERM.new.message
|
||||
assert_equal("#{msg} - a (Errno::EPERM)", Errno::EPERM.new("a").inspect)
|
||||
end
|
||||
@@ -224,7 +224,7 @@ fiber_switch(mrb_state *mrb, mrb_value self, mrb_int len, const mrb_value *a, mr
|
||||
*b++ = *a++;
|
||||
}
|
||||
}
|
||||
c->cibase->n = len;
|
||||
c->cibase->n = (uint8_t)len;
|
||||
value = c->stbase[0] = MRB_PROC_ENV(c->cibase->proc)->stack[0];
|
||||
}
|
||||
else {
|
||||
|
||||
+129
-129
@@ -16,158 +16,158 @@ Add the line below to your build configuration.
|
||||
|
||||
* <https://doc.ruby-lang.org/ja/1.9.3/class/IO.html>
|
||||
|
||||
| method | mruby-io | memo |
|
||||
| ------------------------- | -------- | ---- |
|
||||
| IO.binread | | |
|
||||
| IO.binwrite | | |
|
||||
| IO.copy_stream | | |
|
||||
| IO.new, IO.for_fd, IO.open | o | |
|
||||
| IO.foreach | | |
|
||||
| IO.pipe | o | |
|
||||
| IO.popen | o | |
|
||||
| IO.read | o | |
|
||||
| IO.readlines | | |
|
||||
| IO.select | o | |
|
||||
| IO.sysopen | o | |
|
||||
| IO.try_convert | | |
|
||||
| IO.write | | |
|
||||
| IO#<< | | |
|
||||
| IO#advise | | |
|
||||
| IO#autoclose= | | |
|
||||
| IO#autoclose? | | |
|
||||
| IO#binmode | | |
|
||||
| IO#binmode? | | |
|
||||
| method | mruby-io | memo |
|
||||
|----------------------------|----------|----------|
|
||||
| IO.binread | | |
|
||||
| IO.binwrite | | |
|
||||
| IO.copy_stream | | |
|
||||
| IO.new, IO.for_fd, IO.open | o | |
|
||||
| IO.foreach | | |
|
||||
| IO.pipe | o | |
|
||||
| IO.popen | o | |
|
||||
| IO.read | o | |
|
||||
| IO.readlines | | |
|
||||
| IO.select | o | |
|
||||
| IO.sysopen | o | |
|
||||
| IO.try_convert | | |
|
||||
| IO.write | | |
|
||||
| IO#<< | | |
|
||||
| IO#advise | | |
|
||||
| IO#autoclose= | | |
|
||||
| IO#autoclose? | | |
|
||||
| IO#binmode | | |
|
||||
| IO#binmode? | | |
|
||||
| IO#bytes | | obsolete |
|
||||
| IO#chars | | obsolete |
|
||||
| IO#clone, IO#dup | o | |
|
||||
| IO#close | o | |
|
||||
| IO#close_on_exec= | o | |
|
||||
| IO#close_on_exec? | o | |
|
||||
| IO#close_read | | |
|
||||
| IO#close_write | | |
|
||||
| IO#closed? | o | |
|
||||
| IO#clone, IO#dup | o | |
|
||||
| IO#close | o | |
|
||||
| IO#close_on_exec= | o | |
|
||||
| IO#close_on_exec? | o | |
|
||||
| IO#close_read | | |
|
||||
| IO#close_write | | |
|
||||
| IO#closed? | o | |
|
||||
| IO#codepoints | | obsolete |
|
||||
| IO#each_byte | o | |
|
||||
| IO#each_char | o | |
|
||||
| IO#each_codepoint | | |
|
||||
| IO#each_line | o | |
|
||||
| IO#eof, IO#eof? | o | |
|
||||
| IO#external_encoding | | |
|
||||
| IO#fcntl | | |
|
||||
| IO#fdatasync | | |
|
||||
| IO#fileno, IO#to_i | o | |
|
||||
| IO#flush | o | |
|
||||
| IO#fsync | | |
|
||||
| IO#getbyte | o | |
|
||||
| IO#getc | o | |
|
||||
| IO#gets | o | |
|
||||
| IO#internal_encoding | | |
|
||||
| IO#ioctl | | |
|
||||
| IO#isatty, IO#tty? | o | |
|
||||
| IO#lineno | | |
|
||||
| IO#lineno= | | |
|
||||
| IO#each_byte | o | |
|
||||
| IO#each_char | o | |
|
||||
| IO#each_codepoint | | |
|
||||
| IO#each_line | o | |
|
||||
| IO#eof, IO#eof? | o | |
|
||||
| IO#external_encoding | | |
|
||||
| IO#fcntl | | |
|
||||
| IO#fdatasync | | |
|
||||
| IO#fileno, IO#to_i | o | |
|
||||
| IO#flush | o | |
|
||||
| IO#fsync | | |
|
||||
| IO#getbyte | o | |
|
||||
| IO#getc | o | |
|
||||
| IO#gets | o | |
|
||||
| IO#internal_encoding | | |
|
||||
| IO#ioctl | | |
|
||||
| IO#isatty, IO#tty? | o | |
|
||||
| IO#lineno | | |
|
||||
| IO#lineno= | | |
|
||||
| IO#lines | | obsolete |
|
||||
| IO#pid | o | |
|
||||
| IO#pos, IO#tell | o | |
|
||||
| IO#pos= | o | |
|
||||
| IO#print | o | |
|
||||
| IO#printf | o | |
|
||||
| IO#putc | | |
|
||||
| IO#puts | o | |
|
||||
| IO#read | o | |
|
||||
| IO#read_nonblock | | |
|
||||
| IO#readbyte | o | |
|
||||
| IO#readchar | o | |
|
||||
| IO#readline | o | |
|
||||
| IO#readlines | o | |
|
||||
| IO#readpartial | | |
|
||||
| IO#reopen | | |
|
||||
| IO#rewind | | |
|
||||
| IO#seek | o | |
|
||||
| IO#set_encoding | | |
|
||||
| IO#stat | | |
|
||||
| IO#sync | o | |
|
||||
| IO#sync= | o | |
|
||||
| IO#sysread | o | |
|
||||
| IO#sysseek | o | |
|
||||
| IO#syswrite | o | |
|
||||
| IO#to_io | | |
|
||||
| IO#ungetbyte | o | |
|
||||
| IO#ungetc | o | |
|
||||
| IO#write | o | |
|
||||
| IO#write_nonblock | | |
|
||||
| IO#pid | o | |
|
||||
| IO#pos, IO#tell | o | |
|
||||
| IO#pos= | o | |
|
||||
| IO#print | o | |
|
||||
| IO#printf | o | |
|
||||
| IO#putc | | |
|
||||
| IO#puts | o | |
|
||||
| IO#read | o | |
|
||||
| IO#read_nonblock | | |
|
||||
| IO#readbyte | o | |
|
||||
| IO#readchar | o | |
|
||||
| IO#readline | o | |
|
||||
| IO#readlines | o | |
|
||||
| IO#readpartial | | |
|
||||
| IO#reopen | | |
|
||||
| IO#rewind | | |
|
||||
| IO#seek | o | |
|
||||
| IO#set_encoding | | |
|
||||
| IO#stat | | |
|
||||
| IO#sync | o | |
|
||||
| IO#sync= | o | |
|
||||
| IO#sysread | o | |
|
||||
| IO#sysseek | o | |
|
||||
| IO#syswrite | o | |
|
||||
| IO#to_io | | |
|
||||
| IO#ungetbyte | o | |
|
||||
| IO#ungetc | o | |
|
||||
| IO#write | o | |
|
||||
| IO#write_nonblock | | |
|
||||
|
||||
### File
|
||||
|
||||
* <https://doc.ruby-lang.org/ja/1.9.3/class/File.html>
|
||||
|
||||
| method | mruby-io | memo |
|
||||
| --------------------------- | -------- | ---- |
|
||||
| File.absolute_path | | |
|
||||
| File.atime | | |
|
||||
| File.basename | o | |
|
||||
| method | mruby-io | memo |
|
||||
|-----------------------------|----------|----------|
|
||||
| File.absolute_path | | |
|
||||
| File.atime | | |
|
||||
| File.basename | o | |
|
||||
| File.blockdev? | | FileTest |
|
||||
| File.chardev? | | FileTest |
|
||||
| File.chmod | o | |
|
||||
| File.chown | | |
|
||||
| File.ctime | | |
|
||||
| File.delete, File.unlink | o | |
|
||||
| File.directory? | o | FileTest |
|
||||
| File.dirname | o | |
|
||||
| File.chmod | o | |
|
||||
| File.chown | | |
|
||||
| File.ctime | | |
|
||||
| File.delete, File.unlink | o | |
|
||||
| File.directory? | o | FileTest |
|
||||
| File.dirname | o | |
|
||||
| File.executable? | | FileTest |
|
||||
| File.executable_real? | | FileTest |
|
||||
| File.exist?, exists? | o | FileTest |
|
||||
| File.expand_path | o | |
|
||||
| File.extname | o | |
|
||||
| File.file? | o | FileTest |
|
||||
| File.fnmatch, File.fnmatch? | | |
|
||||
| File.ftype | | |
|
||||
| File.exist?, exists? | o | FileTest |
|
||||
| File.expand_path | o | |
|
||||
| File.extname | o | |
|
||||
| File.file? | o | FileTest |
|
||||
| File.fnmatch, File.fnmatch? | | |
|
||||
| File.ftype | | |
|
||||
| File.grpowned? | | FileTest |
|
||||
| File.identical? | | FileTest |
|
||||
| File.join | o | |
|
||||
| File.lchmod | | |
|
||||
| File.lchown | | |
|
||||
| File.link | | |
|
||||
| File.lstat | | |
|
||||
| File.mtime | | |
|
||||
| File.new, File.open | o | |
|
||||
| File.join | o | |
|
||||
| File.lchmod | | |
|
||||
| File.lchown | | |
|
||||
| File.link | | |
|
||||
| File.lstat | | |
|
||||
| File.mtime | | |
|
||||
| File.new, File.open | o | |
|
||||
| File.owned? | | FileTest |
|
||||
| File.path | | |
|
||||
| File.pipe? | o | FileTest |
|
||||
| File.path | | |
|
||||
| File.pipe? | o | FileTest |
|
||||
| File.readable? | | FileTest |
|
||||
| File.readable_real? | | FileTest |
|
||||
| File.readlink | o | |
|
||||
| File.realdirpath | | |
|
||||
| File.realpath | o | |
|
||||
| File.rename | o | |
|
||||
| File.readlink | o | |
|
||||
| File.realdirpath | | |
|
||||
| File.realpath | o | |
|
||||
| File.rename | o | |
|
||||
| File.setgid? | | FileTest |
|
||||
| File.setuid? | | FileTest |
|
||||
| File.size | o | |
|
||||
| File.size? | o | FileTest |
|
||||
| File.socket? | o | FileTest |
|
||||
| File.split | | |
|
||||
| File.stat | | |
|
||||
| File.size | o | |
|
||||
| File.size? | o | FileTest |
|
||||
| File.socket? | o | FileTest |
|
||||
| File.split | | |
|
||||
| File.stat | | |
|
||||
| File.sticky? | | FileTest |
|
||||
| File.symlink | | |
|
||||
| File.symlink? | o | FileTest |
|
||||
| File.truncate | | |
|
||||
| File.umask | o | |
|
||||
| File.utime | | |
|
||||
| File.world_readable? | | |
|
||||
| File.world_writable? | | |
|
||||
| File.symlink | | |
|
||||
| File.symlink? | o | FileTest |
|
||||
| File.truncate | | |
|
||||
| File.umask | o | |
|
||||
| File.utime | | |
|
||||
| File.world_readable? | | |
|
||||
| File.world_writable? | | |
|
||||
| File.writable? | | FileTest |
|
||||
| File.writable_real? | | FileTest |
|
||||
| File.zero? | o | FileTest |
|
||||
| File#atime | | |
|
||||
| File#chmod | | |
|
||||
| File#chown | | |
|
||||
| File#ctime | | |
|
||||
| File#flock | o | |
|
||||
| File#lstat | | |
|
||||
| File#mtime | | |
|
||||
| File#path, File#to_path | o | |
|
||||
| File#size | | |
|
||||
| File#truncate | | |
|
||||
| File.zero? | o | FileTest |
|
||||
| File#atime | | |
|
||||
| File#chmod | | |
|
||||
| File#chown | | |
|
||||
| File#ctime | | |
|
||||
| File#flock | o | |
|
||||
| File#lstat | | |
|
||||
| File#mtime | | |
|
||||
| File#path, File#to_path | o | |
|
||||
| File#size | | |
|
||||
| File#truncate | | |
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "mruby/variable.h"
|
||||
#include "mruby/ext/io.h"
|
||||
#include "mruby/error.h"
|
||||
#include "mruby/internal.h"
|
||||
#include "mruby/presym.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <mruby/string.h>
|
||||
#include <mruby/numeric.h>
|
||||
#include <mruby/proc.h>
|
||||
#include <mruby/internal.h>
|
||||
#include <mruby/presym.h>
|
||||
|
||||
static mrb_value
|
||||
@@ -166,7 +167,7 @@ arg_error:
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "base specified for non string value");
|
||||
}
|
||||
/* to raise TypeError */
|
||||
return mrb_to_integer(mrb, val);
|
||||
return mrb_ensure_integer_type(mrb, val);
|
||||
}
|
||||
|
||||
#ifndef MRB_NO_FLOAT
|
||||
@@ -190,7 +191,7 @@ mrb_f_float(mrb_state *mrb, mrb_value self)
|
||||
if (mrb_string_p(arg)) {
|
||||
return mrb_float_value(mrb, mrb_str_to_dbl(mrb, arg, TRUE));
|
||||
}
|
||||
return mrb_to_float(mrb, arg);
|
||||
return mrb_ensure_float_type(mrb, arg);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "mruby/proc.h"
|
||||
#include "mruby/class.h"
|
||||
#include "mruby/string.h"
|
||||
#include <mruby/internal.h>
|
||||
#include "mruby/presym.h"
|
||||
|
||||
typedef enum {
|
||||
@@ -575,6 +576,39 @@ mrb_mod_instance_methods(mrb_state *mrb, mrb_value mod)
|
||||
return mrb_class_instance_method_list(mrb, recur, c);
|
||||
}
|
||||
|
||||
static int
|
||||
undefined_method_i(mrb_state *mrb, mrb_sym mid, mrb_method_t m, void *p)
|
||||
{
|
||||
mrb_value ary = *(mrb_value*)p;
|
||||
|
||||
if (MRB_METHOD_UNDEF_P(m)) {
|
||||
mrb_ary_push(mrb, ary, mrb_symbol_value(mid));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* mod.undefined_methods() -> array
|
||||
*
|
||||
* Returns an array containing the names of the undefined methods of the module/class.
|
||||
*/
|
||||
static mrb_value
|
||||
mrb_mod_undefined_methods(mrb_state *mrb, mrb_value mod)
|
||||
{
|
||||
struct RClass *m = mrb_class_ptr(mod);
|
||||
mrb_get_args(mrb, ""); /* no argument */
|
||||
|
||||
mrb_value ary = mrb_ary_new(mrb);
|
||||
|
||||
if (m->flags & MRB_FL_CLASS_IS_PREPENDED) {
|
||||
MRB_CLASS_ORIGIN(m);
|
||||
}
|
||||
mrb_mt_foreach(mrb, m, undefined_method_i, (void*)&ary);
|
||||
|
||||
return ary;
|
||||
}
|
||||
|
||||
/* 15.2.2.4.41 */
|
||||
/*
|
||||
* call-seq:
|
||||
@@ -663,6 +697,7 @@ mrb_mruby_metaprog_gem_init(mrb_state* mrb)
|
||||
mrb_define_method(mrb, mod, "class_variable_set", mrb_mod_cvar_set, MRB_ARGS_REQ(2)); /* 15.2.2.4.18 */
|
||||
mrb_define_method(mrb, mod, "included_modules", mrb_mod_included_modules, MRB_ARGS_NONE()); /* 15.2.2.4.30 */
|
||||
mrb_define_method(mrb, mod, "instance_methods", mrb_mod_instance_methods, MRB_ARGS_ANY()); /* 15.2.2.4.33 */
|
||||
mrb_define_method(mrb, mod, "undefined_instance_methods", mrb_mod_undefined_methods, MRB_ARGS_NONE());
|
||||
mrb_define_method(mrb, mod, "remove_method", mrb_mod_remove_method, MRB_ARGS_ANY()); /* 15.2.2.4.41 */
|
||||
mrb_define_method(mrb, mod, "method_removed", mrb_f_nil, MRB_ARGS_REQ(1));
|
||||
mrb_define_method(mrb, mod, "constants", mrb_mod_constants, MRB_ARGS_OPT(1)); /* 15.2.2.4.24 */
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "mruby/variable.h"
|
||||
#include "mruby/proc.h"
|
||||
#include "mruby/string.h"
|
||||
#include "mruby/internal.h"
|
||||
#include "mruby/presym.h"
|
||||
|
||||
mrb_noreturn void mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args);
|
||||
|
||||
@@ -1,7 +1,39 @@
|
||||
#include <mruby.h>
|
||||
#include <mruby/numeric.h>
|
||||
#include <mruby/internal.h>
|
||||
#include <mruby/presym.h>
|
||||
|
||||
#ifdef MRB_USE_BIGINT
|
||||
static mrb_value
|
||||
bint_allbits(mrb_state *mrb, mrb_value x, mrb_value y)
|
||||
{
|
||||
y = mrb_as_bint(mrb, y);
|
||||
x = mrb_bint_and(mrb, x, y);
|
||||
if (mrb_bint_cmp(mrb, x, y) == 0) return mrb_true_value();
|
||||
return mrb_false_value();
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
bint_anybits(mrb_state *mrb, mrb_value x, mrb_value y)
|
||||
{
|
||||
y = mrb_as_bint(mrb, y);
|
||||
x = mrb_bint_and(mrb, x, y);
|
||||
if (mrb_bint_cmp(mrb, x, mrb_fixnum_value(0)) != 0)
|
||||
return mrb_true_value();
|
||||
return mrb_false_value();
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
bint_nobits(mrb_state *mrb, mrb_value x, mrb_value y)
|
||||
{
|
||||
y = mrb_as_bint(mrb, y);
|
||||
x = mrb_bint_and(mrb, x, y);
|
||||
if (mrb_bint_cmp(mrb, x, mrb_fixnum_value(0)) == 0)
|
||||
return mrb_true_value();
|
||||
return mrb_false_value();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* int.allbits?(mask) -> true or false
|
||||
@@ -11,6 +43,9 @@
|
||||
static mrb_value
|
||||
int_allbits(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
#ifdef MRB_USE_BIGINT
|
||||
return bint_allbits(mrb, self, mrb_get_arg1(mrb));
|
||||
#endif
|
||||
mrb_int n, m;
|
||||
|
||||
mrb_get_args(mrb, "i", &m);
|
||||
@@ -27,6 +62,9 @@ int_allbits(mrb_state *mrb, mrb_value self)
|
||||
static mrb_value
|
||||
int_anybits(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
#ifdef MRB_USE_BIGINT
|
||||
return bint_anybits(mrb, self, mrb_get_arg1(mrb));
|
||||
#endif
|
||||
mrb_int n, m;
|
||||
|
||||
mrb_get_args(mrb, "i", &m);
|
||||
@@ -43,6 +81,9 @@ int_anybits(mrb_state *mrb, mrb_value self)
|
||||
static mrb_value
|
||||
int_nobits(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
#ifdef MRB_USE_BIGINT
|
||||
return bint_nobits(mrb, self, mrb_get_arg1(mrb));
|
||||
#endif
|
||||
mrb_int n, m;
|
||||
|
||||
mrb_get_args(mrb, "i", &m);
|
||||
@@ -50,11 +91,9 @@ int_nobits(mrb_state *mrb, mrb_value self)
|
||||
return mrb_bool_value((n & m) == 0);
|
||||
}
|
||||
|
||||
static void
|
||||
zerodiv(mrb_state *mrb)
|
||||
{
|
||||
mrb_raise(mrb, E_ZERODIV_ERROR, "divided by 0");
|
||||
}
|
||||
#ifndef MRB_NO_FLOAT
|
||||
static mrb_value flo_remainder(mrb_state *mrb, mrb_value self);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
@@ -70,24 +109,82 @@ int_remainder(mrb_state *mrb, mrb_value x)
|
||||
mrb_value y = mrb_get_arg1(mrb);
|
||||
mrb_int a, b;
|
||||
|
||||
#ifdef MRB_USE_BIGINT
|
||||
if (mrb_bigint_p(x)) {
|
||||
if (mrb_integer_p(y) || mrb_bigint_p(y)) {
|
||||
return mrb_bint_rem(mrb, x, y);
|
||||
}
|
||||
return flo_remainder(mrb, mrb_float_value(mrb, mrb_as_float(mrb, x)));
|
||||
}
|
||||
#endif
|
||||
a = mrb_integer(x);
|
||||
if (mrb_integer_p(y)) {
|
||||
b = mrb_integer(y);
|
||||
if (b == 0) zerodiv(mrb);
|
||||
if (b == 0) mrb_int_zerodiv(mrb);
|
||||
if (a == MRB_INT_MIN && b == -1) return mrb_fixnum_value(0);
|
||||
return mrb_int_value(mrb, a % b);
|
||||
}
|
||||
#ifdef MRB_NO_FLOAT
|
||||
mrb_raise(mrb, E_TYPE_ERROR, "non integer remainder");
|
||||
#else
|
||||
mrb_float n = (mrb_float)a;
|
||||
mrb_float m = mrb_as_float(mrb, y);
|
||||
|
||||
if (isinf(m)) return mrb_float_value(mrb, n);
|
||||
return mrb_float_value(mrb, n-m*trunc(n/m));
|
||||
return flo_remainder(mrb, mrb_float_value(mrb, mrb_as_float(mrb, x)));
|
||||
#endif
|
||||
}
|
||||
|
||||
mrb_value mrb_int_pow(mrb_state *mrb, mrb_value x);
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* integer.pow(numeric) -> numeric
|
||||
* integer.pow(integer, integer) -> integer
|
||||
*
|
||||
* Returns (modular) exponentiation as:
|
||||
*
|
||||
* a.pow(b) #=> same as a**b
|
||||
* a.pow(b, m) #=> same as (a**b) % m, but avoids huge temporary values
|
||||
*/
|
||||
static mrb_value
|
||||
int_powm(mrb_state *mrb, mrb_value x)
|
||||
{
|
||||
mrb_value m;
|
||||
mrb_int base, exp, mod, result = 1;
|
||||
|
||||
if (mrb_get_argc(mrb) == 1) {
|
||||
return mrb_int_pow(mrb, x);
|
||||
}
|
||||
mrb_get_args(mrb, "io", &exp, &m);
|
||||
if (exp < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "int.pow(n,m): n must be positive");
|
||||
#ifdef MRB_USE_BIGINT
|
||||
if (mrb_bigint_p(x)) {
|
||||
return mrb_bint_powm(mrb, x, exp, m);
|
||||
}
|
||||
if (mrb_bigint_p(m)) {
|
||||
return mrb_bint_powm(mrb, mrb_bint_new_int(mrb, mrb_integer(x)), exp, m);
|
||||
}
|
||||
#endif
|
||||
if (!mrb_integer_p(m)) mrb_raise(mrb, E_TYPE_ERROR, "int.pow(n,m): m must be integer");
|
||||
mod = mrb_integer(m);
|
||||
if (mod < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "int.pow(n,m): m must be positive");
|
||||
if (mod == 0) mrb_int_zerodiv(mrb);
|
||||
if (mod == 1) return mrb_fixnum_value(0);
|
||||
base = mrb_integer(x);
|
||||
for (;;) {
|
||||
if (exp & 1) {
|
||||
if (mrb_int_mul_overflow(result, base, &result)) {
|
||||
mrb_int_overflow(mrb, "pow");
|
||||
}
|
||||
result %= mod;
|
||||
}
|
||||
exp >>= 1;
|
||||
if (exp == 0) break;
|
||||
if (mrb_int_mul_overflow(base, base, &base)) {
|
||||
mrb_int_overflow(mrb, "pow");
|
||||
}
|
||||
base %= mod;
|
||||
}
|
||||
return mrb_int_value(mrb, result);
|
||||
}
|
||||
|
||||
#ifndef MRB_NO_FLOAT
|
||||
static mrb_value
|
||||
flo_remainder(mrb_state *mrb, mrb_value self)
|
||||
@@ -96,7 +193,7 @@ flo_remainder(mrb_state *mrb, mrb_value self)
|
||||
|
||||
a = mrb_float(self);
|
||||
mrb_get_args(mrb, "f", &b);
|
||||
if (b == 0) zerodiv(mrb);
|
||||
if (b == 0) mrb_int_zerodiv(mrb);
|
||||
if (isinf(b)) return mrb_float_value(mrb, a);
|
||||
return mrb_float_value(mrb, a-b*trunc(a/b));
|
||||
}
|
||||
@@ -114,6 +211,8 @@ mrb_mruby_numeric_ext_gem_init(mrb_state* mrb)
|
||||
mrb_define_alias(mrb, i, "modulo", "%");
|
||||
mrb_define_method(mrb, i, "remainder", int_remainder, MRB_ARGS_REQ(1));
|
||||
|
||||
mrb_define_method_id(mrb, i, MRB_SYM(pow), int_powm, MRB_ARGS_ARG(1,1));
|
||||
|
||||
#ifndef MRB_NO_FLOAT
|
||||
struct RClass *f = mrb_class_get(mrb, "Float");
|
||||
|
||||
|
||||
@@ -19,3 +19,9 @@ assert('Integer#nonzero?') do
|
||||
assert_equal nil, 0.nonzero?
|
||||
assert_equal 1000, 1000.nonzero?
|
||||
end
|
||||
|
||||
assert('Integer#pow') do
|
||||
assert_equal(8, 2.pow(3))
|
||||
assert_equal(-8, (-2).pow(3))
|
||||
assert_equal(361, 9.pow(1024,1000))
|
||||
end
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <mruby/proc.h>
|
||||
#include <mruby/value.h>
|
||||
#include <mruby/range.h>
|
||||
#include <mruby/internal.h>
|
||||
|
||||
static size_t
|
||||
os_memsize_of_irep(mrb_state* state, const struct mrb_irep *irep)
|
||||
@@ -127,23 +128,24 @@ os_memsize_of_object(mrb_state* mrb, mrb_value obj)
|
||||
case MRB_TT_INTEGER:
|
||||
if (mrb_immediate_p(obj))
|
||||
break;
|
||||
case MRB_TT_RATIONAL:
|
||||
case MRB_TT_RATIONAL:
|
||||
#if defined(MRB_USE_RATIONAL)
|
||||
#if defined(MRB_INT64) && defined(MRB_32BIT)
|
||||
size += sizeof(mrb_int)*2;
|
||||
size += sizeof(mrb_int)*2;
|
||||
#endif
|
||||
size += mrb_objspace_page_slot_size();
|
||||
size += mrb_objspace_page_slot_size();
|
||||
#endif
|
||||
break;
|
||||
break;
|
||||
|
||||
case MRB_TT_COMPLEX:
|
||||
case MRB_TT_COMPLEX:
|
||||
#if defined(MRB_USE_COMPLEX)
|
||||
#if defined(MRB_32BIT) && !defined(MRB_USE_FLOAT32)
|
||||
size += sizeof(mrb_float)*2;
|
||||
size += sizeof(mrb_float)*2;
|
||||
#endif
|
||||
size += mrb_objspace_page_slot_size();
|
||||
size += mrb_objspace_page_slot_size();
|
||||
#endif
|
||||
break;
|
||||
break;
|
||||
case MRB_TT_BIGINT:
|
||||
case MRB_TT_DATA:
|
||||
case MRB_TT_ISTRUCT:
|
||||
size += mrb_objspace_page_slot_size();
|
||||
|
||||
@@ -387,13 +387,13 @@ static int
|
||||
pack_BER(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int flags)
|
||||
{
|
||||
mrb_int n = mrb_integer(o);
|
||||
size_t i;
|
||||
int i;
|
||||
char *p;
|
||||
|
||||
if (n < 0) {
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "can't compress negative numbers");
|
||||
}
|
||||
for (i=1; i<sizeof(mrb_int)+1; i++) {
|
||||
for (i=1; i<(int)sizeof(mrb_int)+1; i++) {
|
||||
mrb_int mask = ~((1L<<(7*i))-1);
|
||||
if ((n & mask) == 0) break;
|
||||
}
|
||||
@@ -410,10 +410,12 @@ pack_BER(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int
|
||||
static int
|
||||
unpack_BER(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, unsigned int flags)
|
||||
{
|
||||
mrb_int i, n = 0;
|
||||
int i;
|
||||
mrb_int n = 0;
|
||||
const unsigned char *p = src;
|
||||
const unsigned char *e = p + srclen;
|
||||
|
||||
if (srclen == 0) return 0;
|
||||
for (i=1; p<e; p++,i++) {
|
||||
if (n > (MRB_INT_MAX>>7)) {
|
||||
mrb_raise(mrb, E_RANGE_ERROR, "BER unpacking 'w' overflow");
|
||||
@@ -620,6 +622,7 @@ utf8_to_uv(mrb_state *mrb, const char *p, long *lenp)
|
||||
}
|
||||
if (!(uv & 0x40)) {
|
||||
*lenp = 1;
|
||||
malformed:
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "malformed UTF-8 character");
|
||||
}
|
||||
|
||||
@@ -630,7 +633,7 @@ utf8_to_uv(mrb_state *mrb, const char *p, long *lenp)
|
||||
else if (!(uv & 0x02)) { n = 6; uv &= 0x01; }
|
||||
else {
|
||||
*lenp = 1;
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "malformed UTF-8 character");
|
||||
goto malformed;
|
||||
}
|
||||
if (n > *lenp) {
|
||||
mrb_raisef(mrb, E_ARGUMENT_ERROR, "malformed UTF-8 character (expected %d bytes, given %d bytes)",
|
||||
@@ -642,7 +645,7 @@ utf8_to_uv(mrb_state *mrb, const char *p, long *lenp)
|
||||
c = *p++ & 0xff;
|
||||
if ((c & 0xc0) != 0x80) {
|
||||
*lenp -= n + 1;
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "malformed UTF-8 character");
|
||||
goto malformed;
|
||||
}
|
||||
else {
|
||||
c &= 0x3f;
|
||||
@@ -1300,7 +1303,7 @@ alias:
|
||||
mrb_raise(mrb, E_RUNTIME_ERROR, "too big template length");
|
||||
}
|
||||
count = (int)n;
|
||||
tmpl->idx = e - tptr;
|
||||
tmpl->idx = (int)(e - tptr);
|
||||
continue;
|
||||
} else if (ch == '*') {
|
||||
if (type == PACK_TYPE_NONE)
|
||||
@@ -1387,13 +1390,12 @@ mrb_pack_pack(mrb_state *mrb, mrb_value ary)
|
||||
|
||||
o = mrb_ary_ref(mrb, ary, aidx);
|
||||
if (type == PACK_TYPE_INTEGER) {
|
||||
o = mrb_to_integer(mrb, o);
|
||||
o = mrb_ensure_int_type(mrb, o);
|
||||
}
|
||||
#ifndef MRB_NO_FLOAT
|
||||
else if (type == PACK_TYPE_FLOAT) {
|
||||
if (!mrb_float_p(o)) {
|
||||
mrb_float f = mrb_as_float(mrb, o);
|
||||
o = mrb_float_value(mrb, f);
|
||||
o = mrb_ensure_float_type(mrb, o);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1524,7 +1526,7 @@ pack_unpack(mrb_state *mrb, mrb_value str, int single)
|
||||
break;
|
||||
}
|
||||
|
||||
while (count != 0) {
|
||||
while (count != 0 && srcidx < srclen) {
|
||||
if (srclen - srcidx < size) {
|
||||
while (count-- > 0) {
|
||||
mrb_ary_push(mrb, result, mrb_nil_value());
|
||||
|
||||
@@ -137,7 +137,7 @@ random_rand(mrb_state *mrb, rand_state *t, mrb_int max)
|
||||
}
|
||||
|
||||
static mrb_int
|
||||
random_rand_i(mrb_state *mrb, rand_state *t, mrb_int max)
|
||||
rand_i(rand_state *t, mrb_int max)
|
||||
{
|
||||
return rand_uint32(t) % max;
|
||||
}
|
||||
@@ -167,6 +167,7 @@ random_default(mrb_state *mrb) {
|
||||
|
||||
#define random_ptr(v) (rand_state*)mrb_istruct_ptr(v)
|
||||
#define random_default_state(mrb) random_ptr(random_default(mrb))
|
||||
#define ID_RANDOM_STRICT MRB_SYM(mruby_Random)
|
||||
|
||||
static mrb_value
|
||||
random_m_init(mrb_state *mrb, mrb_value self)
|
||||
@@ -241,14 +242,22 @@ random_m_bytes(mrb_state *mrb, mrb_value self)
|
||||
static mrb_value
|
||||
mrb_ary_shuffle_bang(mrb_state *mrb, mrb_value ary)
|
||||
{
|
||||
mrb_int i, max;
|
||||
rand_state *random;
|
||||
|
||||
if (RARRAY_LEN(ary) > 1) {
|
||||
struct RClass *c = mrb_class_get_id(mrb, MRB_SYM(Random));
|
||||
if (mrb_get_args(mrb, "|I", &random, c) == 0) {
|
||||
mrb_int i, max;
|
||||
mrb_value r;
|
||||
rand_state *random;
|
||||
|
||||
struct RClass *c = mrb_class_get_id(mrb, ID_RANDOM_STRICT);
|
||||
if (mrb_get_args(mrb, "|o", &r) == 0) {
|
||||
random = random_default_state(mrb);
|
||||
}
|
||||
else if (mrb_obj_is_kind_of(mrb, r, c)){
|
||||
random = (rand_state*)mrb_istruct_ptr(r);
|
||||
}
|
||||
else {
|
||||
mrb_raise(mrb, E_TYPE_ERROR, "Random object required");
|
||||
}
|
||||
mrb_ary_modify(mrb, mrb_ary_ptr(ary));
|
||||
max = RARRAY_LEN(ary);
|
||||
for (i = RARRAY_LEN(ary) - 1; i > 0; i--) {
|
||||
@@ -256,7 +265,7 @@ mrb_ary_shuffle_bang(mrb_state *mrb, mrb_value ary)
|
||||
mrb_value *ptr = RARRAY_PTR(ary);
|
||||
mrb_value tmp;
|
||||
|
||||
j = random_rand_i(mrb, random, max);
|
||||
j = rand_i(random, max);
|
||||
|
||||
tmp = ptr[i];
|
||||
ptr[i] = ptr[j];
|
||||
@@ -303,13 +312,20 @@ mrb_ary_sample(mrb_state *mrb, mrb_value ary)
|
||||
{
|
||||
mrb_int n = 0;
|
||||
mrb_bool given;
|
||||
mrb_value r;
|
||||
rand_state *random;
|
||||
mrb_int len;
|
||||
struct RClass *c = mrb_class_get_id(mrb, MRB_SYM(Random));
|
||||
struct RClass *c = mrb_class_get_id(mrb, ID_RANDOM_STRICT);
|
||||
|
||||
if (mrb_get_args(mrb, "|i?I", &n, &given, &random, c) < 2) {
|
||||
if (mrb_get_args(mrb, "|i?o", &n, &given, &r) < 2) {
|
||||
random = random_default_state(mrb);
|
||||
}
|
||||
else if (mrb_obj_is_kind_of(mrb, r, c)){
|
||||
random = (rand_state*)mrb_istruct_ptr(r);
|
||||
}
|
||||
else {
|
||||
mrb_raise(mrb, E_TYPE_ERROR, "Random object required");
|
||||
}
|
||||
len = RARRAY_LEN(ary);
|
||||
if (!given) { /* pick one element */
|
||||
switch (len) {
|
||||
@@ -318,7 +334,7 @@ mrb_ary_sample(mrb_state *mrb, mrb_value ary)
|
||||
case 1:
|
||||
return RARRAY_PTR(ary)[0];
|
||||
default:
|
||||
return RARRAY_PTR(ary)[rand_uint32(random) % len];
|
||||
return RARRAY_PTR(ary)[rand_i(random, len)];
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -333,7 +349,7 @@ mrb_ary_sample(mrb_state *mrb, mrb_value ary)
|
||||
|
||||
for (;;) {
|
||||
retry:
|
||||
r = (mrb_int)(rand_uint32(random) % len);
|
||||
r = rand_i(random, len);
|
||||
|
||||
for (j=0; j<i; j++) {
|
||||
if (mrb_integer(RARRAY_PTR(result)[j]) == r) {
|
||||
@@ -386,6 +402,7 @@ void mrb_mruby_random_gem_init(mrb_state *mrb)
|
||||
mrb_define_method(mrb, mrb->kernel_module, "srand", random_f_srand, MRB_ARGS_OPT(1));
|
||||
|
||||
random = mrb_define_class(mrb, "Random", mrb->object_class);
|
||||
mrb_const_set(mrb, mrb_obj_value(mrb->object_class), ID_RANDOM_STRICT, mrb_obj_value(random)); // for class check
|
||||
MRB_SET_INSTANCE_TT(random, MRB_TT_ISTRUCT);
|
||||
mrb_define_class_method(mrb, random, "rand", random_f_rand, MRB_ARGS_OPT(1));
|
||||
mrb_define_class_method(mrb, random, "srand", random_f_srand, MRB_ARGS_OPT(1));
|
||||
@@ -401,7 +418,7 @@ void mrb_mruby_random_gem_init(mrb_state *mrb)
|
||||
mrb_define_method(mrb, array, "sample", mrb_ary_sample, MRB_ARGS_OPT(2));
|
||||
|
||||
mrb_const_set(mrb, mrb_obj_value(random), MRB_SYM(DEFAULT),
|
||||
mrb_obj_new(mrb, random, 0, NULL));
|
||||
mrb_obj_new(mrb, random, 0, NULL));
|
||||
}
|
||||
|
||||
void mrb_mruby_random_gem_final(mrb_state *mrb)
|
||||
|
||||
@@ -2,29 +2,33 @@
|
||||
#include <mruby/range.h>
|
||||
|
||||
static mrb_bool
|
||||
r_le(mrb_state *mrb, mrb_value a, mrb_value b)
|
||||
r_less(mrb_state *mrb, mrb_value a, mrb_value b, mrb_bool excl)
|
||||
{
|
||||
mrb_int n = mrb_cmp(mrb, a, b);
|
||||
|
||||
if (n == 0 || n == -1) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static mrb_bool
|
||||
r_lt(mrb_state *mrb, mrb_value a, mrb_value b)
|
||||
{
|
||||
return mrb_cmp(mrb, a, b) == -1;
|
||||
switch (mrb_cmp(mrb, a, b)) {
|
||||
case -2: /* failure */
|
||||
case 1:
|
||||
return FALSE;
|
||||
case 0:
|
||||
return !excl;
|
||||
case -1:
|
||||
default: /* just in case */
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* rng.cover?(obj) -> true or false
|
||||
* rng.cover?(range) -> true or false
|
||||
*
|
||||
* Returns <code>true</code> if +obj+ is between the begin and end of
|
||||
* the range.
|
||||
* Returns +true+ if the given argument is within +self+, +false+ otherwise.
|
||||
*
|
||||
* This tests <code>begin <= obj <= end</code> when #exclude_end? is +false+
|
||||
* and <code>begin <= obj < end</code> when #exclude_end? is +true+.
|
||||
* With non-range argument +object+, evaluates with <tt><=</tt> and <tt><</tt>.
|
||||
*
|
||||
* For range +self+ with included end value (<tt>#exclude_end? == false</tt>),
|
||||
* evaluates thus:
|
||||
*
|
||||
* self.begin <= object <= self.end
|
||||
*
|
||||
* ("a".."z").cover?("c") #=> true
|
||||
* ("a".."z").cover?("5") #=> false
|
||||
@@ -40,20 +44,53 @@ range_cover(mrb_state *mrb, mrb_value range)
|
||||
beg = RANGE_BEG(r);
|
||||
end = RANGE_END(r);
|
||||
|
||||
if (r_le(mrb, beg, val)) {
|
||||
if (mrb_nil_p(end)) {
|
||||
if (mrb_nil_p(beg) && mrb_nil_p(end)) return mrb_true_value();
|
||||
|
||||
if (mrb_range_p(val)) {
|
||||
struct RRange *r2 = mrb_range_ptr(mrb, val);
|
||||
mrb_value beg2 = RANGE_BEG(r2);
|
||||
mrb_value end2 = RANGE_END(r2);
|
||||
|
||||
/* range.cover?(nil..nil) => true */
|
||||
if (mrb_nil_p(beg2) && mrb_nil_p(end2)) return mrb_true_value();
|
||||
|
||||
/* (a..b).cover?(c..d) */
|
||||
if (mrb_nil_p(end)) { /* a.. */
|
||||
/* (a..).cover?(c..) => true */
|
||||
if (mrb_nil_p(end2)) return mrb_bool_value(mrb_cmp(mrb, beg, beg2) != -2);
|
||||
/* (a..).cover?(c..d) where d<a => false */
|
||||
if (r_less(mrb, end2, beg, RANGE_EXCL(r2))) return mrb_false_value();
|
||||
return mrb_true_value();
|
||||
}
|
||||
if (RANGE_EXCL(r)) {
|
||||
if (r_lt(mrb, val, end))
|
||||
return mrb_true_value();
|
||||
else if (mrb_nil_p(beg)) { /* ..b */
|
||||
/* (..b).cover?(..d) => true */
|
||||
if (mrb_nil_p(beg2)) return mrb_bool_value(mrb_cmp(mrb, end, end2) != -2);
|
||||
/* (..b).cover?(c..d) where b<c => false */
|
||||
if (r_less(mrb, end, beg2, RANGE_EXCL(r))) return mrb_false_value();
|
||||
return mrb_true_value();
|
||||
}
|
||||
else {
|
||||
if (r_le(mrb, val, end))
|
||||
return mrb_true_value();
|
||||
else { /* a..b */
|
||||
/* (a..b).cover?(c..) => (c<b) */
|
||||
if (mrb_nil_p(end2))
|
||||
return mrb_bool_value(r_less(mrb, beg2, end, RANGE_EXCL(r)));
|
||||
/* (a..b).cover?(..d) => (a<d) */
|
||||
if (mrb_nil_p(beg2))
|
||||
return mrb_bool_value(r_less(mrb, beg, end2, RANGE_EXCL(r2)));
|
||||
/* (a..b).cover?(c..d) where (b<c) => false */
|
||||
if (r_less(mrb, end, beg2, RANGE_EXCL(r))) return mrb_false_value();
|
||||
/* (a..b).cover?(c..d) where (d<a) => false */
|
||||
if (r_less(mrb, end2, beg, RANGE_EXCL(r2))) return mrb_false_value();
|
||||
return mrb_true_value();
|
||||
}
|
||||
}
|
||||
|
||||
if (mrb_nil_p(beg) || r_less(mrb, beg, val, FALSE)) {
|
||||
if (mrb_nil_p(end)) {
|
||||
return mrb_true_value();
|
||||
}
|
||||
if (r_less(mrb, val, end, RANGE_EXCL(r)))
|
||||
return mrb_true_value();
|
||||
}
|
||||
return mrb_false_value();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,11 +3,25 @@
|
||||
|
||||
assert('Range#cover?') do
|
||||
assert_true ("a".."z").cover?("c")
|
||||
assert_true !("a".."z").cover?("5")
|
||||
assert_false ("a".."z").cover?("5")
|
||||
assert_true ("a".."z").cover?("cc")
|
||||
assert_false ("a".."z").cover?(nil)
|
||||
assert_true ("a"..).cover?("c")
|
||||
assert_false ("a"..).cover?("5")
|
||||
assert_true ("a"..).cover?("cc")
|
||||
assert_true (.."z").cover?("a")
|
||||
assert_false (..."z").cover?("z")
|
||||
assert_true (.."z").cover?("z")
|
||||
assert_true (nil..nil).cover?(nil)
|
||||
|
||||
assert_true ("a".."c").cover?("b".."d")
|
||||
assert_true ("a"..).cover?("b"..)
|
||||
assert_false ("a"..).cover?(1..)
|
||||
assert_false ("d"..).cover?(.."b")
|
||||
assert_true (.."c").cover?("b".."d")
|
||||
assert_true (.."c").cover?(.."d")
|
||||
assert_false (.."c").cover?(..2)
|
||||
assert_false (.."c").cover?("d"..)
|
||||
end
|
||||
|
||||
assert('Range#first') do
|
||||
|
||||
@@ -3,6 +3,13 @@
|
||||
#include <mruby/numeric.h>
|
||||
#include <mruby/presym.h>
|
||||
|
||||
mrb_value mrb_complex_new(mrb_state *, mrb_float, mrb_float);
|
||||
mrb_bool mrb_complex_eq(mrb_state *mrb, mrb_value, mrb_value);
|
||||
mrb_value mrb_complex_add(mrb_state *mrb, mrb_value, mrb_value);
|
||||
mrb_value mrb_complex_sub(mrb_state *mrb, mrb_value, mrb_value);
|
||||
mrb_value mrb_complex_mul(mrb_state *mrb, mrb_value, mrb_value);
|
||||
mrb_value mrb_complex_div(mrb_state *mrb, mrb_value, mrb_value);
|
||||
|
||||
struct mrb_rational {
|
||||
mrb_int numerator;
|
||||
mrb_int denominator;
|
||||
@@ -393,7 +400,6 @@ rational_eq(mrb_state *mrb, mrb_value x)
|
||||
#ifdef MRB_USE_COMPLEX
|
||||
case MRB_TT_COMPLEX:
|
||||
{
|
||||
mrb_bool mrb_complex_eq(mrb_state *mrb, mrb_value, mrb_value);
|
||||
result = mrb_complex_eq(mrb, y, mrb_rational_to_f(mrb, x));
|
||||
break;
|
||||
}
|
||||
@@ -405,10 +411,6 @@ rational_eq(mrb_state *mrb, mrb_value x)
|
||||
return mrb_bool_value(result);
|
||||
}
|
||||
|
||||
#ifndef MRB_NO_FLOAT
|
||||
mrb_value mrb_complex_new(mrb_state *, mrb_float, mrb_float);
|
||||
#endif
|
||||
|
||||
static mrb_value
|
||||
rational_cmp(mrb_state *mrb, mrb_value x)
|
||||
{
|
||||
@@ -454,11 +456,6 @@ rational_cmp(mrb_state *mrb, mrb_value x)
|
||||
return mrb_fixnum_value(-1);
|
||||
return mrb_fixnum_value(0);
|
||||
}
|
||||
#endif
|
||||
#ifdef MRB_USE_COMPLEX
|
||||
case MRB_TT_COMPLEX:
|
||||
x = mrb_complex_new(mrb, rat_float(p1), 0);
|
||||
return mrb_funcall_id(mrb, x, MRB_OPSYM(cmp), 1, y);
|
||||
#endif
|
||||
default:
|
||||
x = mrb_funcall_id(mrb, y, MRB_OPSYM(cmp), 1, x);
|
||||
@@ -479,11 +476,10 @@ rational_minus(mrb_state *mrb, mrb_value x)
|
||||
return rational_new(mrb, -n, p->denominator);
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
rational_add(mrb_state *mrb, mrb_value x)
|
||||
mrb_value
|
||||
mrb_rational_add(mrb_state *mrb, mrb_value x, mrb_value y)
|
||||
{
|
||||
struct mrb_rational *p1 = rational_ptr(mrb, x);
|
||||
mrb_value y = mrb_get_arg1(mrb);
|
||||
|
||||
switch (mrb_type(y)) {
|
||||
case MRB_TT_INTEGER:
|
||||
@@ -513,16 +509,27 @@ rational_add(mrb_state *mrb, mrb_value x)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MRB_USE_COMPLEX)
|
||||
case MRB_TT_COMPLEX:
|
||||
return mrb_complex_add(mrb, mrb_complex_new(mrb, rat_float(p1), 0), y);
|
||||
#endif
|
||||
|
||||
default:
|
||||
return mrb_funcall_id(mrb, y, MRB_OPSYM(add), 1, x);
|
||||
}
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
rational_sub(mrb_state *mrb, mrb_value x)
|
||||
rational_add(mrb_state *mrb, mrb_value x)
|
||||
{
|
||||
mrb_value y = mrb_get_arg1(mrb);
|
||||
return mrb_rational_add(mrb, x, y);
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_rational_sub(mrb_state *mrb, mrb_value x, mrb_value y)
|
||||
{
|
||||
struct mrb_rational *p1 = rational_ptr(mrb, x);
|
||||
mrb_value y = mrb_get_arg1(mrb);
|
||||
|
||||
switch (mrb_type(y)) {
|
||||
case MRB_TT_INTEGER:
|
||||
@@ -546,8 +553,7 @@ rational_sub(mrb_state *mrb, mrb_value x)
|
||||
|
||||
#if defined(MRB_USE_COMPLEX)
|
||||
case MRB_TT_COMPLEX:
|
||||
x = mrb_complex_new(mrb, rat_float(p1), 0);
|
||||
return mrb_funcall_id(mrb, x, MRB_OPSYM(sub), 1, y);
|
||||
return mrb_complex_sub(mrb, mrb_complex_new(mrb, rat_float(p1), 0), y);
|
||||
#endif
|
||||
|
||||
#ifndef MRB_NO_FLOAT
|
||||
@@ -565,10 +571,16 @@ rational_sub(mrb_state *mrb, mrb_value x)
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
rational_mul(mrb_state *mrb, mrb_value x)
|
||||
rational_sub(mrb_state *mrb, mrb_value x)
|
||||
{
|
||||
mrb_value y = mrb_get_arg1(mrb);
|
||||
return mrb_rational_sub(mrb, x, y);
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_rational_mul(mrb_state *mrb, mrb_value x, mrb_value y)
|
||||
{
|
||||
struct mrb_rational *p1 = rational_ptr(mrb, x);
|
||||
mrb_value y = mrb_get_arg1(mrb);
|
||||
|
||||
switch (mrb_type(y)) {
|
||||
case MRB_TT_INTEGER:
|
||||
@@ -595,16 +607,27 @@ rational_mul(mrb_state *mrb, mrb_value x)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MRB_USE_COMPLEX)
|
||||
case MRB_TT_COMPLEX:
|
||||
return mrb_complex_mul(mrb, mrb_complex_new(mrb, rat_float(p1), 0), y);
|
||||
#endif
|
||||
|
||||
default:
|
||||
return mrb_funcall_id(mrb, y, MRB_OPSYM(mul), 1, x);
|
||||
}
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
rational_mul(mrb_state *mrb, mrb_value x)
|
||||
{
|
||||
mrb_value y = mrb_get_arg1(mrb);
|
||||
return mrb_rational_mul(mrb, x, y);
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_rational_div(mrb_state *mrb, mrb_value x)
|
||||
mrb_rational_div(mrb_state *mrb, mrb_value x, mrb_value y)
|
||||
{
|
||||
struct mrb_rational *p1 = rational_ptr(mrb, x);
|
||||
mrb_value y = mrb_get_arg1(mrb);
|
||||
|
||||
switch (mrb_type(y)) {
|
||||
case MRB_TT_INTEGER:
|
||||
@@ -625,8 +648,7 @@ mrb_rational_div(mrb_state *mrb, mrb_value x)
|
||||
|
||||
#if defined(MRB_USE_COMPLEX)
|
||||
case MRB_TT_COMPLEX:
|
||||
x = mrb_complex_new(mrb, rat_float(p1), 0);
|
||||
return mrb_funcall_id(mrb, x, MRB_OPSYM(div), 1, y);
|
||||
return mrb_complex_div(mrb, mrb_complex_new(mrb, rat_float(p1), 0), y);
|
||||
#endif
|
||||
|
||||
default:
|
||||
@@ -642,65 +664,15 @@ mrb_rational_div(mrb_state *mrb, mrb_value x)
|
||||
}
|
||||
}
|
||||
|
||||
#define rational_div mrb_rational_div
|
||||
static mrb_value
|
||||
rational_div(mrb_state *mrb, mrb_value x)
|
||||
{
|
||||
mrb_value y = mrb_get_arg1(mrb);
|
||||
return mrb_rational_div(mrb, x, y);
|
||||
}
|
||||
|
||||
mrb_int mrb_div_int(mrb_state *, mrb_int, mrb_int);
|
||||
|
||||
#ifndef MRB_USE_COMPLEX
|
||||
/* 15.2.8.3.4 */
|
||||
/*
|
||||
* redefine Integer#/
|
||||
*/
|
||||
static mrb_value
|
||||
rational_int_div(mrb_state *mrb, mrb_value x)
|
||||
{
|
||||
mrb_value y = mrb_get_arg1(mrb);
|
||||
mrb_int a = mrb_integer(x);
|
||||
|
||||
if (mrb_integer_p(y)) {
|
||||
mrb_int div = mrb_div_int(mrb, a, mrb_integer(y));
|
||||
return mrb_int_value(mrb, div);
|
||||
}
|
||||
switch (mrb_type(y)) {
|
||||
case MRB_TT_RATIONAL:
|
||||
return rational_div(mrb, rational_new(mrb, a, 1));
|
||||
default:
|
||||
#ifdef MRB_NO_FLOAT
|
||||
case MRB_TT_FLOAT:
|
||||
mrb_raise(mrb, E_TYPE_ERROR, "non integer multiplication");
|
||||
#else
|
||||
return mrb_float_value(mrb, mrb_div_float((mrb_float)a, mrb_as_float(mrb, y)));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* 15.2.9.3.19(x) */
|
||||
/*
|
||||
* redefine Integer#quo
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
rational_int_quo(mrb_state *mrb, mrb_value x)
|
||||
{
|
||||
mrb_value y = mrb_get_arg1(mrb);
|
||||
mrb_int a = mrb_integer(x);
|
||||
|
||||
if (mrb_integer_p(y)) {
|
||||
return rational_new(mrb, a, mrb_integer(y));
|
||||
}
|
||||
switch (mrb_type(y)) {
|
||||
case MRB_TT_RATIONAL:
|
||||
x = rational_new(mrb, a, 1);
|
||||
return mrb_funcall_id(mrb, x, MRB_OPSYM(div), 1, y);
|
||||
default:
|
||||
#ifdef MRB_NO_FLOAT
|
||||
mrb_raise(mrb, E_TYPE_ERROR, "non integer multiplication");
|
||||
#else
|
||||
return mrb_float_value(mrb, mrb_div_float((mrb_float)a, mrb_as_float(mrb, y)));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif /* !MRB_USE_COMPLEX */
|
||||
|
||||
void mrb_mruby_rational_gem_init(mrb_state *mrb)
|
||||
{
|
||||
struct RClass *rat;
|
||||
@@ -726,10 +698,6 @@ void mrb_mruby_rational_gem_init(mrb_state *mrb)
|
||||
mrb_define_method(mrb, rat, "/", rational_div, MRB_ARGS_REQ(1));
|
||||
mrb_define_method(mrb, rat, "quo", rational_div, MRB_ARGS_REQ(1));
|
||||
mrb_define_method(mrb, mrb->integer_class, "to_r", fix_to_r, MRB_ARGS_NONE());
|
||||
#ifndef MRB_USE_COMPLEX
|
||||
mrb_define_method(mrb, mrb->integer_class, "/", rational_int_div, MRB_ARGS_REQ(1)); /* override */
|
||||
mrb_define_method(mrb, mrb->integer_class, "quo", rational_int_quo, MRB_ARGS_REQ(1)); /* override */
|
||||
#endif
|
||||
mrb_define_method(mrb, mrb->kernel_module, "Rational", rational_m, MRB_ARGS_ARG(1,1));
|
||||
}
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ mrb_f_usleep(mrb_state *mrb, mrb_value self)
|
||||
if (usec >= 0) {
|
||||
usleep(usec);
|
||||
} else {
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "time interval must not be negative integer");
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "time interval must not be negative");
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "mruby/string.h"
|
||||
#include "mruby/variable.h"
|
||||
#include "mruby/error.h"
|
||||
#include "mruby/internal.h"
|
||||
#include "mruby/presym.h"
|
||||
|
||||
#include "mruby/ext/io.h"
|
||||
@@ -52,12 +53,6 @@
|
||||
|
||||
#define E_SOCKET_ERROR mrb_class_get_id(mrb, MRB_SYM(SocketError))
|
||||
|
||||
#if !defined(mrb_cptr)
|
||||
#define mrb_cptr_value(m,p) mrb_voidp_value((m),(p))
|
||||
#define mrb_cptr(o) mrb_voidp(o)
|
||||
#define mrb_cptr_p(o) mrb_voidp_p(o)
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
static const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt)
|
||||
{
|
||||
@@ -262,10 +257,12 @@ sa2addrlist(mrb_state *mrb, const struct sockaddr *sa, socklen_t salen)
|
||||
return ary;
|
||||
}
|
||||
|
||||
int mrb_io_fileno(mrb_state *mrb, mrb_value io);
|
||||
|
||||
static int
|
||||
socket_fd(mrb_state *mrb, mrb_value sock)
|
||||
{
|
||||
return (int)mrb_integer(mrb_funcall_id(mrb, sock, MRB_SYM(fileno), 0));
|
||||
return mrb_io_fileno(mrb, sock);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -468,9 +465,10 @@ mrb_basicsocket_setsockopt(mrb_state *mrb, mrb_value self)
|
||||
} else if (argc == 1) {
|
||||
if (strcmp(mrb_obj_classname(mrb, so), "Socket::Option") != 0)
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "not an instance of Socket::Option");
|
||||
level = mrb_integer(mrb_funcall_id(mrb, so, MRB_SYM(level), 0));
|
||||
optname = mrb_integer(mrb_funcall_id(mrb, so, MRB_SYM(optname), 0));
|
||||
level = mrb_as_int(mrb, mrb_funcall_id(mrb, so, MRB_SYM(level), 0));
|
||||
optname = mrb_as_int(mrb, mrb_funcall_id(mrb, so, MRB_SYM(optname), 0));
|
||||
optval = mrb_funcall_id(mrb, so, MRB_SYM(data), 0);
|
||||
mrb_ensure_string_type(mrb, optval);
|
||||
} else {
|
||||
mrb_argnum_error(mrb, argc, 3, 3);
|
||||
}
|
||||
@@ -515,9 +513,8 @@ mrb_ipsocket_ntop(mrb_state *mrb, mrb_value klass)
|
||||
char buf[50];
|
||||
|
||||
mrb_get_args(mrb, "is", &af, &addr, &n);
|
||||
if ((af == AF_INET && n != 4) || (af == AF_INET6 && n != 16))
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid address");
|
||||
if (inet_ntop((int)af, addr, buf, sizeof(buf)) == NULL)
|
||||
if ((af == AF_INET && n != 4) || (af == AF_INET6 && n != 16) ||
|
||||
inet_ntop((int)af, addr, buf, sizeof(buf)) == NULL)
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid address");
|
||||
return mrb_str_new_cstr(mrb, buf);
|
||||
}
|
||||
@@ -530,8 +527,7 @@ mrb_ipsocket_pton(mrb_state *mrb, mrb_value klass)
|
||||
char buf[50];
|
||||
|
||||
mrb_get_args(mrb, "is", &af, &bp, &n);
|
||||
if ((size_t)n > sizeof(buf) - 1)
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid address");
|
||||
if ((size_t)n > sizeof(buf) - 1) goto invalid;
|
||||
memcpy(buf, bp, n);
|
||||
buf[n] = '\0';
|
||||
|
||||
@@ -623,7 +619,7 @@ mrb_socket_accept2(mrb_state *mrb, mrb_value klass)
|
||||
|
||||
mrb_get_args(mrb, "i", &s0);
|
||||
socklen = sizeof(struct sockaddr_storage);
|
||||
sastr = mrb_str_new_capa(mrb, socklen);
|
||||
sastr = mrb_str_new_capa(mrb, (mrb_int)socklen);
|
||||
s1 = (int)accept(s0, (struct sockaddr *)RSTRING_PTR(sastr), &socklen);
|
||||
if (s1 == -1) {
|
||||
mrb_sys_fail(mrb, "accept");
|
||||
|
||||
@@ -1002,12 +1002,14 @@ retry:
|
||||
}
|
||||
break;
|
||||
|
||||
#ifndef MRB_NO_FLOAT
|
||||
case 'f':
|
||||
case 'g':
|
||||
case 'G':
|
||||
case 'e':
|
||||
case 'E': {
|
||||
#ifdef MRB_NO_FLOAT
|
||||
mrb_raisef(mrb, E_ARGUMENT_ERROR, "%%%c not supported with MRB_NO_FLOAT defined", *p);
|
||||
#else
|
||||
mrb_value val = GETARG();
|
||||
double fval;
|
||||
mrb_int need = 6;
|
||||
@@ -1077,9 +1079,9 @@ retry:
|
||||
mrb_raise(mrb, E_RUNTIME_ERROR, "formatting error");
|
||||
}
|
||||
blen += n;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
flags = FNONE;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <mruby/class.h>
|
||||
#include <mruby/string.h>
|
||||
#include <mruby/range.h>
|
||||
#include <mruby/internal.h>
|
||||
|
||||
#define ENC_ASCII_8BIT "ASCII-8BIT"
|
||||
#define ENC_BINARY "BINARY"
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <mruby/hash.h>
|
||||
#include <mruby/range.h>
|
||||
#include <mruby/proc.h>
|
||||
#include <mruby/internal.h>
|
||||
#include <mruby/presym.h>
|
||||
|
||||
#define RSTRUCT_LEN(st) RARRAY_LEN(st)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <mruby.h>
|
||||
#include <mruby/array.h>
|
||||
#include <mruby/string.h>
|
||||
#include <mruby/internal.h>
|
||||
#ifdef MRB_USE_ALL_SYMBOLS
|
||||
# include <mruby/presym.h>
|
||||
#endif
|
||||
|
||||
@@ -56,10 +56,18 @@ istruct_test_test_receive(mrb_state *mrb, mrb_value self)
|
||||
static mrb_value
|
||||
istruct_test_test_receive_direct(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
char *ptr;
|
||||
mrb_value is;
|
||||
struct RClass *klass = mrb_class_get(mrb, "InlineStructTest");
|
||||
mrb_get_args(mrb, "I", &ptr, klass);
|
||||
return mrb_bool_value(ptr[0] == 's');
|
||||
mrb_get_args(mrb, "o", &is);
|
||||
/* if you need to protect istruct retrieval from untrusted code,
|
||||
you need to care about class replacing.
|
||||
See mrbgem/mruby-random/src/random.c for detail */
|
||||
if (mrb_istruct_p(is) && mrb_obj_is_kind_of(mrb, is, klass)) {
|
||||
char *ptr = (char*)mrb_istruct_ptr(is);;
|
||||
return mrb_bool_value(ptr[0] == 's');
|
||||
}
|
||||
mrb_raise(mrb, E_TYPE_ERROR, "InlineStructTest");
|
||||
return mrb_false_value();
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
|
||||
@@ -459,7 +459,7 @@ time_mktime(mrb_state *mrb, mrb_int ayear, mrb_int amonth, mrb_int aday,
|
||||
#define OUTINT(x) 0
|
||||
#endif
|
||||
|
||||
if (OUTINT(ayear-1900) ||
|
||||
if (ayear < 1900 || OUTINT(ayear-1900) ||
|
||||
amonth < 1 || amonth > 12 ||
|
||||
aday < 1 || aday > 31 ||
|
||||
ahour < 0 || ahour > 24 ||
|
||||
@@ -476,14 +476,21 @@ time_mktime(mrb_state *mrb, mrb_int ayear, mrb_int amonth, mrb_int aday,
|
||||
nowtime.tm_sec = (int)asec;
|
||||
nowtime.tm_isdst = -1;
|
||||
|
||||
time_t (*mk)(struct tm*);
|
||||
if (timezone == MRB_TIMEZONE_UTC) {
|
||||
nowsecs = timegm(&nowtime);
|
||||
mk = timegm;
|
||||
}
|
||||
else {
|
||||
nowsecs = mktime(&nowtime);
|
||||
mk = mktime;
|
||||
}
|
||||
nowsecs = (*mk)(&nowtime);
|
||||
if (nowsecs == (time_t)-1) {
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "Not a valid time");
|
||||
nowtime.tm_sec += 1; /* maybe Epoch-1 sec */
|
||||
nowsecs = (*mk)(&nowtime);
|
||||
if (nowsecs != 0) { /* check if Epoch */
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "Not a valid time");
|
||||
}
|
||||
nowsecs = (time_t)-1; /* valid Epoch-1 */
|
||||
}
|
||||
|
||||
return time_alloc_time(mrb, nowsecs, ausec, timezone);
|
||||
|
||||
@@ -267,7 +267,3 @@ assert('2000 times 500us make a second') do
|
||||
end
|
||||
assert_equal(0, t.usec)
|
||||
end
|
||||
|
||||
assert('Time.gm with Dec 31 23:59:59 1969 raise ArgumentError') do
|
||||
assert_raise(ArgumentError) {Time.gm(1969, 12, 31, 23, 59, 59)}
|
||||
end
|
||||
|
||||
@@ -51,4 +51,7 @@ MRuby::GemBox.new do |conf|
|
||||
|
||||
# Use class/module extension
|
||||
conf.gem :core => "mruby-class-ext"
|
||||
|
||||
# Use errno extension
|
||||
conf.gem :core => "mruby-errno"
|
||||
end
|
||||
|
||||
+4
-2
@@ -22,7 +22,8 @@ class Module
|
||||
|
||||
# 15.2.2.4.27
|
||||
def include(*args)
|
||||
args.reverse.each do |m|
|
||||
args.reverse!
|
||||
args.each do |m|
|
||||
m.append_features(self)
|
||||
m.included(self)
|
||||
end
|
||||
@@ -30,7 +31,8 @@ class Module
|
||||
end
|
||||
|
||||
def prepend(*args)
|
||||
args.reverse.each do |m|
|
||||
args.reverse!
|
||||
args.each do |m|
|
||||
m.prepend_features(self)
|
||||
m.prepended(self)
|
||||
end
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
module Kernel
|
||||
##
|
||||
# call-seq:
|
||||
# obj.extend(module, ...) -> obj
|
||||
#
|
||||
# Adds to _obj_ the instance methods from each module given as a
|
||||
# parameter.
|
||||
#
|
||||
# module Mod
|
||||
# def hello
|
||||
# "Hello from Mod.\n"
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# class Klass
|
||||
# def hello
|
||||
# "Hello from Klass.\n"
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# k = Klass.new
|
||||
# k.hello #=> "Hello from Klass.\n"
|
||||
# k.extend(Mod) #=> #<Klass:0x401b3bc8>
|
||||
# k.hello #=> "Hello from Mod.\n"
|
||||
#
|
||||
# ISO 15.3.1.3.13
|
||||
def extend(*args)
|
||||
args.reverse!
|
||||
args.each do |m|
|
||||
m.extend_object(self)
|
||||
m.extended(self)
|
||||
end
|
||||
self
|
||||
end
|
||||
end
|
||||
@@ -1,3 +1,16 @@
|
||||
class Exception
|
||||
##
|
||||
# call-seq:
|
||||
# exception.message -> string
|
||||
#
|
||||
# Returns the result of invoking <code>exception.to_s</code>.
|
||||
# Normally this returns the exception's message or name.
|
||||
#
|
||||
def message
|
||||
to_s
|
||||
end
|
||||
end
|
||||
|
||||
# ISO 15.2.24
|
||||
class ArgumentError < StandardError
|
||||
end
|
||||
|
||||
+8
-4
@@ -167,10 +167,14 @@ class Array
|
||||
n = other.size
|
||||
len = n if len > n
|
||||
i = 0
|
||||
while i < len
|
||||
n = (self[i] <=> other[i])
|
||||
return n if n.nil? || n != 0
|
||||
i += 1
|
||||
begin
|
||||
while i < len
|
||||
n = (self[i] <=> other[i])
|
||||
return n if n.nil? || n != 0
|
||||
i += 1
|
||||
end
|
||||
rescue NoMethodError
|
||||
return nil
|
||||
end
|
||||
len = self.size - other.size
|
||||
if len == 0
|
||||
|
||||
+2
-3
@@ -150,10 +150,9 @@ class String
|
||||
# Call the given block for each byte of +self+.
|
||||
def each_byte(&block)
|
||||
return to_enum(:each_byte, &block) unless block
|
||||
bytes = self.bytes
|
||||
pos = 0
|
||||
while pos < bytes.size
|
||||
block.call(bytes[pos])
|
||||
while pos < bytesize
|
||||
block.call(getbyte(pos))
|
||||
pos += 1
|
||||
end
|
||||
self
|
||||
|
||||
+32
-19
@@ -10,6 +10,7 @@
|
||||
#include <mruby/string.h>
|
||||
#include <mruby/range.h>
|
||||
#include <mruby/proc.h>
|
||||
#include <mruby/internal.h>
|
||||
#include <mruby/presym.h>
|
||||
#include "value_array.h"
|
||||
|
||||
@@ -18,15 +19,26 @@
|
||||
#define ARY_C_MAX_SIZE (SIZE_MAX / sizeof(mrb_value))
|
||||
#define ARY_MAX_SIZE ((mrb_int)((ARY_C_MAX_SIZE < (size_t)MRB_INT_MAX) ? ARY_C_MAX_SIZE : MRB_INT_MAX-1))
|
||||
|
||||
static void
|
||||
ary_too_big(mrb_state *mrb)
|
||||
{
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");
|
||||
}
|
||||
|
||||
static void
|
||||
ary_check_too_big(mrb_state *mrb, mrb_int a, mrb_int b)
|
||||
{
|
||||
if (a > ARY_MAX_SIZE - b || a < 0)
|
||||
ary_too_big(mrb);
|
||||
}
|
||||
|
||||
static struct RArray*
|
||||
ary_new_capa(mrb_state *mrb, mrb_int capa)
|
||||
{
|
||||
struct RArray *a;
|
||||
size_t blen;
|
||||
|
||||
if (capa > ARY_MAX_SIZE) {
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");
|
||||
}
|
||||
ary_check_too_big(mrb, capa, 0);
|
||||
blen = capa * sizeof(mrb_value);
|
||||
|
||||
a = MRB_OBJ_ALLOC(mrb, MRB_TT_ARRAY, mrb->array_class);
|
||||
@@ -188,11 +200,7 @@ ary_expand_capa(mrb_state *mrb, struct RArray *a, mrb_int len)
|
||||
{
|
||||
mrb_int capa = ARY_CAPA(a);
|
||||
|
||||
if (len > ARY_MAX_SIZE || len < 0) {
|
||||
size_error:
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");
|
||||
}
|
||||
|
||||
ary_check_too_big(mrb, len, 0);
|
||||
if (capa < ARY_DEFAULT_LEN) {
|
||||
capa = ARY_DEFAULT_LEN;
|
||||
}
|
||||
@@ -205,7 +213,7 @@ ary_expand_capa(mrb_state *mrb, struct RArray *a, mrb_int len)
|
||||
}
|
||||
}
|
||||
if (capa < len || capa > ARY_MAX_SIZE) {
|
||||
goto size_error;
|
||||
ary_too_big(mrb);
|
||||
}
|
||||
|
||||
if (ARY_EMBED_P(a)) {
|
||||
@@ -302,9 +310,7 @@ ary_concat(mrb_state *mrb, struct RArray *a, struct RArray *a2)
|
||||
ary_replace(mrb, a, a2);
|
||||
return;
|
||||
}
|
||||
if (ARY_LEN(a2) > ARY_MAX_SIZE - ARY_LEN(a)) {
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");
|
||||
}
|
||||
ary_check_too_big(mrb, ARY_LEN(a2), ARY_LEN(a));
|
||||
len = ARY_LEN(a) + ARY_LEN(a2);
|
||||
|
||||
ary_modify(mrb, a);
|
||||
@@ -343,9 +349,7 @@ mrb_ary_plus(mrb_state *mrb, mrb_value self)
|
||||
mrb_int blen, len1;
|
||||
|
||||
mrb_get_args(mrb, "a", &ptr, &blen);
|
||||
if (ARY_MAX_SIZE - blen < ARY_LEN(a1)) {
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");
|
||||
}
|
||||
ary_check_too_big(mrb, ARY_LEN(a1), blen);
|
||||
len1 = ARY_LEN(a1);
|
||||
a2 = ary_new_capa(mrb, len1 + blen);
|
||||
array_copy(ARY_PTR(a2), ARY_PTR(a1), len1);
|
||||
@@ -425,16 +429,22 @@ mrb_ary_times(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
struct RArray *a1 = mrb_ary_ptr(self);
|
||||
struct RArray *a2;
|
||||
mrb_value *ptr;
|
||||
mrb_value *ptr, sep, tmp;
|
||||
mrb_int times, len1;
|
||||
|
||||
mrb_get_args(mrb, "o", &sep);
|
||||
tmp = mrb_check_string_type(mrb, sep);
|
||||
if (!mrb_nil_p(tmp)) {
|
||||
return mrb_ary_join(mrb, self, tmp);
|
||||
}
|
||||
|
||||
mrb_get_args(mrb, "i", ×);
|
||||
if (times < 0) {
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "negative argument");
|
||||
}
|
||||
if (times == 0) return mrb_ary_new(mrb);
|
||||
if (ARY_MAX_SIZE / times < ARY_LEN(a1)) {
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");
|
||||
ary_too_big(mrb);
|
||||
}
|
||||
len1 = ARY_LEN(a1);
|
||||
a2 = ary_new_capa(mrb, len1 * times);
|
||||
@@ -710,6 +720,9 @@ mrb_ary_set(mrb_state *mrb, mrb_value ary, mrb_int n, mrb_value val)
|
||||
mrb_raisef(mrb, E_INDEX_ERROR, "index %i out of array", n - len);
|
||||
}
|
||||
}
|
||||
if (n >= ARY_MAX_SIZE) {
|
||||
mrb_raise(mrb, E_INDEX_ERROR, "index too big");
|
||||
}
|
||||
if (len <= n) {
|
||||
if (ARY_CAPA(a) <= n)
|
||||
ary_expand_capa(mrb, a, n + 1);
|
||||
@@ -834,7 +847,7 @@ ary_subseq(mrb_state *mrb, struct RArray *a, mrb_int beg, mrb_int len)
|
||||
return mrb_ary_new_from_values(mrb, len, ARY_PTR(a)+beg);
|
||||
}
|
||||
ary_make_shared(mrb, a);
|
||||
b = MRB_OBJ_ALLOC(mrb, MRB_TT_ARRAY, mrb->array_class);
|
||||
b = MRB_OBJ_ALLOC(mrb, MRB_TT_ARRAY, mrb->array_class);
|
||||
b->as.heap.ptr = a->as.heap.ptr + beg;
|
||||
b->as.heap.len = len;
|
||||
b->as.heap.aux.shared = a->as.heap.aux.shared;
|
||||
@@ -1003,7 +1016,7 @@ mrb_ary_aset(mrb_state *mrb, mrb_value self)
|
||||
return v3;
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
mrb_value
|
||||
mrb_ary_delete_at(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
struct RArray *a = mrb_ary_ptr(self);
|
||||
|
||||
+42
-36
@@ -14,6 +14,7 @@
|
||||
#include <mruby/error.h>
|
||||
#include <mruby/numeric.h>
|
||||
#include <mruby/data.h>
|
||||
#include <mruby/internal.h>
|
||||
#include <mruby/presym.h>
|
||||
|
||||
struct backtrace_location {
|
||||
@@ -26,8 +27,7 @@ typedef void (*each_backtrace_func)(mrb_state*, const struct backtrace_location*
|
||||
|
||||
static const mrb_data_type bt_type = { "Backtrace", mrb_free };
|
||||
|
||||
mrb_value mrb_exc_inspect(mrb_state *mrb, mrb_value exc);
|
||||
mrb_value mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace);
|
||||
struct RObject *mrb_unpack_backtrace(mrb_state *mrb, struct RObject *backtrace);
|
||||
|
||||
static void
|
||||
each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, each_backtrace_func func, void *data)
|
||||
@@ -97,17 +97,17 @@ each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, each_backtrace_func func, void *
|
||||
#ifndef MRB_NO_STDIO
|
||||
|
||||
static void
|
||||
print_backtrace(mrb_state *mrb, struct RObject *exc, mrb_value backtrace)
|
||||
print_backtrace(mrb_state *mrb, struct RObject *exc, struct RArray *backtrace)
|
||||
{
|
||||
mrb_int i;
|
||||
mrb_int n = RARRAY_LEN(backtrace);
|
||||
mrb_int n = ARY_LEN(backtrace);
|
||||
mrb_value *loc, mesg;
|
||||
|
||||
if (n != 0) {
|
||||
if (n > 1) {
|
||||
fprintf(stderr, "trace (most recent call last):\n");
|
||||
}
|
||||
for (i=n-1,loc=&RARRAY_PTR(backtrace)[i]; i>0; i--,loc--) {
|
||||
for (i=n-1,loc=&ARY_PTR(backtrace)[i]; i>0; i--,loc--) {
|
||||
if (mrb_string_p(*loc)) {
|
||||
fprintf(stderr, "\t[%d] %.*s\n",
|
||||
(int)i, (int)RSTRING_LEN(*loc), RSTRING_PTR(*loc));
|
||||
@@ -130,16 +130,14 @@ print_backtrace(mrb_state *mrb, struct RObject *exc, mrb_value backtrace)
|
||||
MRB_API void
|
||||
mrb_print_backtrace(mrb_state *mrb)
|
||||
{
|
||||
mrb_value backtrace;
|
||||
|
||||
if (!mrb->exc) {
|
||||
return;
|
||||
}
|
||||
|
||||
backtrace = mrb_obj_iv_get(mrb, mrb->exc, MRB_SYM(backtrace));
|
||||
if (mrb_nil_p(backtrace)) return;
|
||||
if (!mrb_array_p(backtrace)) backtrace = mrb_unpack_backtrace(mrb, backtrace);
|
||||
print_backtrace(mrb, mrb->exc, backtrace);
|
||||
struct RObject *backtrace = ((struct RException*)mrb->exc)->backtrace;
|
||||
if (!backtrace) return;
|
||||
if (backtrace->tt != MRB_TT_ARRAY) backtrace = mrb_unpack_backtrace(mrb, backtrace);
|
||||
print_backtrace(mrb, mrb->exc, (struct RArray*)backtrace);
|
||||
}
|
||||
#else
|
||||
|
||||
@@ -172,7 +170,7 @@ pack_backtrace_i(mrb_state *mrb,
|
||||
*pptr = ptr+1;
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
static struct RObject*
|
||||
packed_backtrace(mrb_state *mrb)
|
||||
{
|
||||
struct RData *backtrace;
|
||||
@@ -183,44 +181,51 @@ packed_backtrace(mrb_state *mrb)
|
||||
|
||||
each_backtrace(mrb, ciidx, count_backtrace_i, &len);
|
||||
size = len * sizeof(struct backtrace_location);
|
||||
backtrace = mrb_data_object_alloc(mrb, NULL, NULL, &bt_type);
|
||||
ptr = mrb_malloc(mrb, size);
|
||||
backtrace = mrb_data_object_alloc(mrb, NULL, ptr, &bt_type);
|
||||
backtrace->data = ptr;
|
||||
backtrace->flags = (uint32_t)len;
|
||||
each_backtrace(mrb, ciidx, pack_backtrace_i, &ptr);
|
||||
return mrb_obj_value(backtrace);
|
||||
return (struct RObject*)backtrace;
|
||||
}
|
||||
|
||||
static void
|
||||
store_backtrace(mrb_state *mrb, mrb_value exc, struct RObject *backtrace)
|
||||
{
|
||||
struct RException *e = mrb_exc_ptr(exc);
|
||||
e->backtrace = backtrace;
|
||||
mrb_field_write_barrier(mrb, (struct RBasic*)e, (struct RBasic*)backtrace);
|
||||
}
|
||||
|
||||
void
|
||||
mrb_keep_backtrace(mrb_state *mrb, mrb_value exc)
|
||||
{
|
||||
mrb_sym sym = MRB_SYM(backtrace);
|
||||
mrb_value backtrace;
|
||||
int ai;
|
||||
|
||||
if (mrb_iv_defined(mrb, exc, sym)) return;
|
||||
if (mrb_exc_ptr(exc)->backtrace) return;
|
||||
ai = mrb_gc_arena_save(mrb);
|
||||
backtrace = packed_backtrace(mrb);
|
||||
mrb_iv_set(mrb, exc, sym, backtrace);
|
||||
struct RObject *backtrace = packed_backtrace(mrb);
|
||||
store_backtrace(mrb, exc, backtrace);
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace)
|
||||
struct RObject*
|
||||
mrb_unpack_backtrace(mrb_state *mrb, struct RObject *backtrace)
|
||||
{
|
||||
const struct backtrace_location *bt;
|
||||
mrb_int n, i;
|
||||
int ai;
|
||||
|
||||
if (mrb_nil_p(backtrace)) {
|
||||
if (backtrace == NULL) {
|
||||
empty_backtrace:
|
||||
return mrb_ary_new_capa(mrb, 0);
|
||||
return mrb_obj_ptr(mrb_ary_new_capa(mrb, 0));
|
||||
}
|
||||
if (mrb_array_p(backtrace)) return backtrace;
|
||||
bt = (struct backtrace_location*)mrb_data_check_get_ptr(mrb, backtrace, &bt_type);
|
||||
if (backtrace->tt == MRB_TT_ARRAY) return backtrace;
|
||||
bt = (struct backtrace_location*)mrb_data_check_get_ptr(mrb, mrb_obj_value(backtrace), &bt_type);
|
||||
if (bt == NULL) goto empty_backtrace;
|
||||
n = (mrb_int)RDATA(backtrace)->flags;
|
||||
n = (mrb_int)backtrace->flags;
|
||||
if (n == 0) goto empty_backtrace;
|
||||
backtrace = mrb_ary_new_capa(mrb, n);
|
||||
backtrace = mrb_obj_ptr(mrb_ary_new_capa(mrb, n));
|
||||
ai = mrb_gc_arena_save(mrb);
|
||||
for (i = 0; i < n; i++) {
|
||||
const struct backtrace_location *entry = &bt[i];
|
||||
@@ -236,7 +241,7 @@ mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace)
|
||||
mrb_str_cat_lit(mrb, btline, ":in ");
|
||||
mrb_str_cat_cstr(mrb, btline, mrb_sym_name(mrb, entry->method_id));
|
||||
}
|
||||
mrb_ary_push(mrb, backtrace, btline);
|
||||
mrb_ary_push(mrb, mrb_obj_value(backtrace), btline);
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
}
|
||||
|
||||
@@ -246,20 +251,21 @@ mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace)
|
||||
mrb_value
|
||||
mrb_exc_backtrace(mrb_state *mrb, mrb_value exc)
|
||||
{
|
||||
mrb_value backtrace;
|
||||
|
||||
backtrace = mrb_iv_get(mrb, exc, MRB_SYM(backtrace));
|
||||
if (mrb_nil_p(backtrace) || mrb_array_p(backtrace)) {
|
||||
return backtrace;
|
||||
struct RObject *backtrace = mrb_exc_ptr(exc)->backtrace;
|
||||
if (backtrace == NULL) {
|
||||
return mrb_nil_value();
|
||||
}
|
||||
if (backtrace->tt == MRB_TT_ARRAY) {
|
||||
return mrb_obj_value(backtrace);
|
||||
}
|
||||
/* unpack packed-backtrace */
|
||||
backtrace = mrb_unpack_backtrace(mrb, backtrace);
|
||||
mrb_iv_set(mrb, exc, MRB_SYM(backtrace), backtrace);
|
||||
return backtrace;
|
||||
store_backtrace(mrb, exc, backtrace);
|
||||
return mrb_obj_value(backtrace);
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_get_backtrace(mrb_state *mrb)
|
||||
{
|
||||
return mrb_unpack_backtrace(mrb, packed_backtrace(mrb));
|
||||
return mrb_obj_value(mrb_unpack_backtrace(mrb, packed_backtrace(mrb)));
|
||||
}
|
||||
|
||||
+4
-3
@@ -9,6 +9,7 @@
|
||||
#include <mruby/dump.h>
|
||||
#include <mruby/irep.h>
|
||||
#include <mruby/debug.h>
|
||||
#include <mruby/internal.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@@ -302,7 +303,7 @@ cdump_debug(mrb_state *mrb, const char *name, int n, mrb_irep_debug_info *info,
|
||||
line_type = "mrb_debug_line_flat_map";
|
||||
fprintf(fp, "static struct mrb_irep_debug_info_line %s_debug_lines_%d[%d] = {", name, n, len);
|
||||
for (i=0; i<len; i++) {
|
||||
mrb_irep_debug_info_line *fmap = &info->files[0]->lines.flat_map[i];
|
||||
const mrb_irep_debug_info_line *fmap = &info->files[0]->lines.flat_map[i];
|
||||
fprintf(fp, "\t{.start_pos=0x%04x,.line=%d},\n", fmap->start_pos, fmap->line);
|
||||
}
|
||||
fputs("};\n", fp);
|
||||
@@ -310,8 +311,8 @@ cdump_debug(mrb_state *mrb, const char *name, int n, mrb_irep_debug_info *info,
|
||||
|
||||
case mrb_debug_line_packed_map:
|
||||
line_type = "mrb_debug_line_packed_map";
|
||||
fprintf(fp, "static char %s_debug_lines_%d[] = \"", name, n);
|
||||
uint8_t *pmap = info->files[0]->lines.packed_map;
|
||||
fprintf(fp, "static const char %s_debug_lines_%d[] = \"", name, n);
|
||||
const uint8_t *pmap = info->files[0]->lines.packed_map;
|
||||
for (i=0; i<len; i++) {
|
||||
fprintf(fp, "\\x%02x", pmap[i]&0xff);
|
||||
}
|
||||
|
||||
+25
-46
@@ -16,6 +16,7 @@
|
||||
#include <mruby/data.h>
|
||||
#include <mruby/istruct.h>
|
||||
#include <mruby/opcode.h>
|
||||
#include <mruby/internal.h>
|
||||
#include <mruby/presym.h>
|
||||
|
||||
union mt_ptr {
|
||||
@@ -150,9 +151,11 @@ mt_get(mrb_state *mrb, mt_tbl *t, mrb_sym sym, union mt_ptr *pp)
|
||||
hash = kh_int_hash_func(mrb, sym);
|
||||
#ifdef MRB_USE_INLINE_METHOD_CACHE
|
||||
int cpos = (hash^(uintptr_t)t) % MT_CACHE_SIZE;
|
||||
mrb_sym key;
|
||||
pos = mt_cache[cpos];
|
||||
if (cpos < t->alloc && t->table[cpos].key == sym) {
|
||||
return &t->table[cpos];
|
||||
if (cpos < t->alloc && key = keys[pos] && MT_KEY_SYM(key) == sym) {
|
||||
*pp = vals[pos];
|
||||
return key;
|
||||
}
|
||||
#endif
|
||||
start = pos = hash & (t->alloc-1);
|
||||
@@ -161,7 +164,7 @@ mt_get(mrb_state *mrb, mt_tbl *t, mrb_sym sym, union mt_ptr *pp)
|
||||
if (MT_KEY_SYM(key) == sym) {
|
||||
*pp = vals[pos];
|
||||
#ifdef MRB_USE_INLINE_METHOD_CACHE
|
||||
if (pos < 0xff) {
|
||||
if (pos < 0x100) {
|
||||
mt_cache[cpos] = pos;
|
||||
}
|
||||
#endif
|
||||
@@ -545,7 +548,7 @@ mrb_define_class(mrb_state *mrb, const char *name, struct RClass *super)
|
||||
return mrb_define_class_id(mrb, mrb_intern_cstr(mrb, name), super);
|
||||
}
|
||||
|
||||
static mrb_value mrb_bob_init(mrb_state *mrb, mrb_value);
|
||||
static mrb_value mrb_do_nothing(mrb_state *mrb, mrb_value);
|
||||
#ifndef MRB_NO_METHOD_CACHE
|
||||
static void mc_clear(mrb_state *mrb);
|
||||
#else
|
||||
@@ -564,7 +567,7 @@ mrb_class_inherited(mrb_state *mrb, struct RClass *super, struct RClass *klass)
|
||||
s = mrb_obj_value(super);
|
||||
mrb_mc_clear_by_class(mrb, klass);
|
||||
mid = MRB_SYM(inherited);
|
||||
if (!mrb_func_basic_p(mrb, s, mid, mrb_bob_init)) {
|
||||
if (!mrb_func_basic_p(mrb, s, mid, mrb_do_nothing)) {
|
||||
mrb_value c = mrb_obj_value(klass);
|
||||
mrb_funcall_argv(mrb, s, mid, 1, &c);
|
||||
}
|
||||
@@ -877,8 +880,6 @@ mrb_get_arg1(mrb_state *mrb)
|
||||
return array_argv[0];
|
||||
}
|
||||
|
||||
mrb_int mrb_ci_bidx(mrb_callinfo *ci);
|
||||
|
||||
MRB_API mrb_bool
|
||||
mrb_block_given_p(mrb_state *mrb)
|
||||
{
|
||||
@@ -913,7 +914,6 @@ mrb_block_given_p(mrb_state *mrb)
|
||||
b: boolean [mrb_bool]
|
||||
n: String/Symbol [mrb_sym]
|
||||
d: data [void*,mrb_data_type const] 2nd argument will be used to check data type so it won't be modified; when ! follows, the value may be nil
|
||||
I: inline struct [void*,struct RClass] I! gives NULL for nil
|
||||
&: block [mrb_value] &! raises exception if no block given
|
||||
*: rest argument [const mrb_value*,mrb_int] The rest of the arguments as an array; *! avoid copy of the stack
|
||||
|: optional Following arguments are optional
|
||||
@@ -932,10 +932,10 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
|
||||
{
|
||||
const char *fmt = format;
|
||||
char c;
|
||||
int i = 0;
|
||||
mrb_int i = 0;
|
||||
va_list ap;
|
||||
mrb_callinfo *ci = mrb->c->ci;
|
||||
int argc = ci->n;
|
||||
mrb_int argc = ci->n;
|
||||
const mrb_value *argv = ci->stack+1;
|
||||
mrb_bool argv_on_stack;
|
||||
mrb_bool opt = FALSE;
|
||||
@@ -1161,29 +1161,6 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'I':
|
||||
{
|
||||
void* *p;
|
||||
struct RClass *klass;
|
||||
|
||||
p = va_arg(ap, void**);
|
||||
klass = va_arg(ap, struct RClass*);
|
||||
if (pickarg) {
|
||||
if (altmode && mrb_nil_p(*pickarg)) {
|
||||
*p = NULL;
|
||||
}
|
||||
else {
|
||||
if (!mrb_obj_is_kind_of(mrb, *pickarg, klass)) {
|
||||
mrb_raisef(mrb, E_TYPE_ERROR, "%v is not a %C", *pickarg, klass);
|
||||
}
|
||||
if (!mrb_istruct_p(*pickarg)) {
|
||||
mrb_raisef(mrb, E_TYPE_ERROR, "%v is not inline struct", *pickarg);
|
||||
}
|
||||
*p = mrb_istruct_ptr(*pickarg);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
#ifndef MRB_NO_FLOAT
|
||||
case 'f':
|
||||
{
|
||||
@@ -1376,6 +1353,7 @@ boot_defclass(mrb_state *mrb, struct RClass *super)
|
||||
if (super) {
|
||||
c->super = super;
|
||||
mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)super);
|
||||
c->flags |= MRB_FL_CLASS_IS_INHERITED;
|
||||
}
|
||||
else {
|
||||
c->super = mrb->object_class;
|
||||
@@ -1970,7 +1948,7 @@ mrb_instance_new(mrb_state *mrb, mrb_value cv)
|
||||
mrb_get_args(mrb, "*!&", &argv, &argc, &blk);
|
||||
obj = mrb_instance_alloc(mrb, cv);
|
||||
init = MRB_SYM(initialize);
|
||||
if (!mrb_func_basic_p(mrb, obj, init, mrb_bob_init)) {
|
||||
if (!mrb_func_basic_p(mrb, obj, init, mrb_do_nothing)) {
|
||||
mrb_funcall_with_block(mrb, obj, init, argc, argv, blk);
|
||||
}
|
||||
return obj;
|
||||
@@ -1984,7 +1962,7 @@ mrb_obj_new(mrb_state *mrb, struct RClass *c, mrb_int argc, const mrb_value *arg
|
||||
|
||||
obj = mrb_instance_alloc(mrb, mrb_obj_value(c));
|
||||
mid = MRB_SYM(initialize);
|
||||
if (!mrb_func_basic_p(mrb, obj, mid, mrb_bob_init)) {
|
||||
if (!mrb_func_basic_p(mrb, obj, mid, mrb_do_nothing)) {
|
||||
mrb_funcall_argv(mrb, obj, mid, argc, argv);
|
||||
}
|
||||
return obj;
|
||||
@@ -2041,7 +2019,7 @@ mrb_class_superclass(mrb_state *mrb, mrb_value klass)
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
mrb_bob_init(mrb_state *mrb, mrb_value cv)
|
||||
mrb_do_nothing(mrb_state *mrb, mrb_value cv)
|
||||
{
|
||||
return mrb_nil_value();
|
||||
}
|
||||
@@ -2305,8 +2283,6 @@ mrb_mod_to_s(mrb_state *mrb, mrb_value klass)
|
||||
}
|
||||
}
|
||||
|
||||
void mrb_method_added(mrb_state *mrb, struct RClass *c, mrb_sym mid);
|
||||
|
||||
static mrb_value
|
||||
mrb_mod_alias(mrb_state *mrb, mrb_value mod)
|
||||
{
|
||||
@@ -2363,7 +2339,10 @@ mrb_remove_method(mrb_state *mrb, struct RClass *c, mrb_sym mid)
|
||||
MRB_CLASS_ORIGIN(c);
|
||||
h = c->mt;
|
||||
|
||||
if (h && mt_del(mrb, h, mid)) return;
|
||||
if (h && mt_del(mrb, h, mid)) {
|
||||
mrb_mc_clear_by_class(mrb, c);
|
||||
return;
|
||||
}
|
||||
mrb_name_error(mrb, mid, "method '%n' not defined in %C", mid, c);
|
||||
}
|
||||
|
||||
@@ -2930,32 +2909,32 @@ mrb_init_class(mrb_state *mrb)
|
||||
MRB_SET_INSTANCE_TT(mrb->proc_class, MRB_TT_PROC);
|
||||
|
||||
MRB_SET_INSTANCE_TT(cls, MRB_TT_CLASS);
|
||||
mrb_define_method(mrb, bob, "initialize", mrb_bob_init, MRB_ARGS_NONE());
|
||||
mrb_define_method(mrb, bob, "initialize", mrb_do_nothing, MRB_ARGS_NONE());
|
||||
mrb_define_method(mrb, bob, "!", mrb_bob_not, MRB_ARGS_NONE());
|
||||
mrb_define_method(mrb, bob, "==", mrb_obj_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.1 */
|
||||
mrb_define_method(mrb, bob, "__id__", mrb_obj_id_m, MRB_ARGS_NONE()); /* 15.3.1.3.4 */
|
||||
mrb_define_method(mrb, bob, "__send__", mrb_f_send, MRB_ARGS_REQ(1)|MRB_ARGS_REST()|MRB_ARGS_BLOCK()); /* 15.3.1.3.5 */
|
||||
mrb_define_method(mrb, bob, "equal?", mrb_obj_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.11 */
|
||||
mrb_define_method(mrb, bob, "instance_eval", mrb_obj_instance_eval, MRB_ARGS_OPT(1)|MRB_ARGS_BLOCK()); /* 15.3.1.3.18 */
|
||||
mrb_define_method(mrb, bob, "singleton_method_added", mrb_bob_init, MRB_ARGS_REQ(1));
|
||||
mrb_define_method(mrb, bob, "singleton_method_added", mrb_do_nothing, MRB_ARGS_REQ(1));
|
||||
|
||||
mrb_define_class_method(mrb, cls, "new", mrb_class_new_class, MRB_ARGS_OPT(1)|MRB_ARGS_BLOCK());
|
||||
mrb_define_method(mrb, cls, "allocate", mrb_instance_alloc, MRB_ARGS_NONE());
|
||||
mrb_define_method(mrb, cls, "superclass", mrb_class_superclass, MRB_ARGS_NONE()); /* 15.2.3.3.4 */
|
||||
mrb_define_method(mrb, cls, "initialize", mrb_class_initialize, MRB_ARGS_OPT(1)); /* 15.2.3.3.1 */
|
||||
mrb_define_method(mrb, cls, "inherited", mrb_bob_init, MRB_ARGS_REQ(1));
|
||||
mrb_define_method(mrb, cls, "inherited", mrb_do_nothing, MRB_ARGS_REQ(1));
|
||||
|
||||
init_class_new(mrb, cls);
|
||||
|
||||
MRB_SET_INSTANCE_TT(mod, MRB_TT_MODULE);
|
||||
mrb_define_method(mrb, mod, "extend_object", mrb_mod_extend_object, MRB_ARGS_REQ(1)); /* 15.2.2.4.25 */
|
||||
mrb_define_method(mrb, mod, "extended", mrb_bob_init, MRB_ARGS_REQ(1)); /* 15.2.2.4.26 */
|
||||
mrb_define_method(mrb, mod, "prepended", mrb_bob_init, MRB_ARGS_REQ(1));
|
||||
mrb_define_method(mrb, mod, "extended", mrb_do_nothing, MRB_ARGS_REQ(1)); /* 15.2.2.4.26 */
|
||||
mrb_define_method(mrb, mod, "prepended", mrb_do_nothing, MRB_ARGS_REQ(1));
|
||||
mrb_define_method(mrb, mod, "prepend_features", mrb_mod_prepend_features, MRB_ARGS_REQ(1));
|
||||
mrb_define_method(mrb, mod, "include?", mrb_mod_include_p, MRB_ARGS_REQ(1)); /* 15.2.2.4.28 */
|
||||
mrb_define_method(mrb, mod, "append_features", mrb_mod_append_features, MRB_ARGS_REQ(1)); /* 15.2.2.4.10 */
|
||||
mrb_define_method(mrb, mod, "class_eval", mrb_mod_module_eval, MRB_ARGS_ANY()); /* 15.2.2.4.15 */
|
||||
mrb_define_method(mrb, mod, "included", mrb_bob_init, MRB_ARGS_REQ(1)); /* 15.2.2.4.29 */
|
||||
mrb_define_method(mrb, mod, "included", mrb_do_nothing, MRB_ARGS_REQ(1)); /* 15.2.2.4.29 */
|
||||
mrb_define_method(mrb, mod, "initialize", mrb_mod_initialize, MRB_ARGS_NONE()); /* 15.2.2.4.31 */
|
||||
mrb_define_method(mrb, mod, "module_eval", mrb_mod_module_eval, MRB_ARGS_ANY()); /* 15.2.2.4.35 */
|
||||
mrb_define_method(mrb, mod, "module_function", mrb_mod_module_function, MRB_ARGS_ANY());
|
||||
@@ -2978,7 +2957,7 @@ mrb_init_class(mrb_state *mrb)
|
||||
mrb_define_method(mrb, mod, "define_method", mod_define_method, MRB_ARGS_ARG(1,1));
|
||||
mrb_define_method(mrb, mod, "===", mrb_mod_eqq, MRB_ARGS_REQ(1)); /* 15.2.2.4.7 */
|
||||
mrb_define_method(mrb, mod, "dup", mrb_mod_dup, MRB_ARGS_NONE());
|
||||
mrb_define_method(mrb, bob, "method_added", mrb_bob_init, MRB_ARGS_REQ(1));
|
||||
mrb_define_method(mrb, mod, "method_added", mrb_do_nothing, MRB_ARGS_REQ(1));
|
||||
|
||||
mrb_undef_method(mrb, cls, "append_features");
|
||||
mrb_undef_method(mrb, cls, "prepend_features");
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user