Unverified Commit 9cebddf9 authored by Yukihiro "Matz" Matsumoto's avatar Yukihiro "Matz" Matsumoto Committed by GitHub

Merge pull request #5084 from mruby/mruby3

Mruby3
parents 8c276f95 21e07d61
......@@ -6,73 +6,67 @@ jobs:
Ubuntu-1604:
runs-on: ubuntu-16.04
env:
MRUBY_CONFIG: travis_config.rb
MRUBY_TARGET: travis
steps:
- uses: actions/checkout@v1
- name: apt
run: sudo apt install ruby gperf
- name: build
run: rake -m
- name: test
run: rake test
- name: build and test
run: rake -m -j4 gensym all test
Ubuntu-1804-gcc:
runs-on: ubuntu-18.04
env:
MRUBY_CONFIG: travis_config.rb
MRUBY_TARGET: travis
CC: gcc
CXX: g++
steps:
- uses: actions/checkout@v1
- name: apt
run: sudo apt install ruby gperf gcc g++
- name: build
run: rake -m
- name: test
run: rake test
- name: build and test
run: rake -m -j4 gensym all test
Ubuntu-1804-clang:
runs-on: ubuntu-18.04
env:
MRUBY_CONFIG: travis_config.rb
MRUBY_TARGET: travis
CC: clang
CXX: clang++
steps:
- uses: actions/checkout@v1
- name: apt
run: sudo apt install ruby gperf
- name: build
run: rake -m
- name: test
run: rake test
- name: build and test
run: rake -m -j4 gensym all test
macOS:
runs-on: macos-latest
env:
MRUBY_CONFIG: travis_config.rb
MRUBY_TARGET: travis
steps:
- uses: actions/checkout@v1
- name: brew
run: brew install ruby gperf
- name: build
run: rake -m
- name: test
run: rake test
- name: build and test
run: rake -m -j4 gensym all test
Windows-MinGW:
runs-on: windows-latest
env:
MRUBY_TARGET: travis
CFLAGS: -g -O1 -Wall -Wundef
steps:
- uses: actions/checkout@v1
- name: chocolatey
run: choco install -y ruby gperf
- name: build
run: rake -E 'STDOUT.sync=true' test
env:
MRUBY_CONFIG: travis_config.rb
CFLAGS: -g -O1 -Wall -Wundef
run: rake -E 'STDOUT.sync=true' -j4 gensym all test
Windows-Cygwin:
runs-on: windows-latest
env:
MRUBY_TARGET: travis
steps:
- uses: actions/checkout@v1
- uses: actions/cache@v1
......@@ -90,13 +84,23 @@ jobs:
- name: Set ENV
run: |
echo '::set-env name=PATH::C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin'
- name: build
- name: build and test
shell: cmd
run: C:\tools\cygwin\bin\ruby.exe /usr/bin/rake -E 'STDOUT.sync=true' -m
env:
MRUBY_CONFIG: travis_config.rb
- name: test
run: C:\tools\cygwin\bin\ruby.exe /usr/bin/rake -E 'STDOUT.sync=true' -m gensym all test
Windows-VC:
runs-on: windows-latest
env:
MRUBY_TARGET: appveyor
# TODO(take-cheeze): Re-enable /O2
CFLAGS: "/c /nologo /W3 /we4013 /Zi /MD /D_CRT_SECURE_NO_WARNINGS"
CXXFLAGS: "/c /nologo /W3 /Zi /MD /EHs /D_CRT_SECURE_NO_WARNINGS"
steps:
- uses: actions/checkout@v1
- name: chocolatey
run: choco install -y ruby gperf
- name: build and test
shell: cmd
run: C:\tools\cygwin\bin\ruby.exe /usr/bin/rake -E 'STDOUT.sync=true' test
env:
MRUBY_CONFIG: travis_config.rb
run: |
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
rake -E "STDOUT.sync=true" gensym all test
......@@ -3,9 +3,12 @@ language: c
jobs:
- os: linux
- os: osx
before_install:
- HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALL_CLEANUP=1 brew install bison
- export PATH="/usr/local/opt/bison/bin:$PATH"
env:
- MRUBY_CONFIG=travis_config.rb
- MRUBY_TARGET=travis
script:
- rake -m && rake test
- rake gensym && rake -m && rake test
......@@ -56,7 +56,7 @@ on-demand.
Use C++ style comments only for temporary comment e.g. commenting out some code lines.
#### Insert a break after the method return value:
#### Insert a break after the function return value:
int
main(void)
......@@ -72,4 +72,5 @@ language itself. Please note the following hints for your Ruby code:
#### Comply with the Ruby standard (ISO/IEC 30170:2012)
mruby is currently targeting to execute Ruby code which complies to ISO/IEC
30170:2012 (http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=59579).
30170:2012 (http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=59579),
unless there's a clear reason, e.g. the latest Ruby has changed behavior from ISO.
......@@ -40,11 +40,13 @@ We don't have a mailing list, but you can use [GitHub issues](https://github.com
See the [compile.md](https://github.com/mruby/mruby/blob/master/doc/guides/compile.md) file.
## Running Tests
## How to Build
To run the tests, execute the following from the project's root directory.
To build mruby, execute the following from the project's root directory.
$ rake test
$ rake TARGET=<target> test
The default `TARGET` is `host`. `TARGET` will be loaded from `target` directory.
Note: `bison` bundled with MacOS is too old to compile `mruby`.
Try `brew install bison` and follow the instuction shown to update
......
......@@ -14,7 +14,13 @@ require "mruby-core-ext"
require "mruby/build"
# load configuration file
MRUBY_CONFIG = (ENV['MRUBY_CONFIG'] && ENV['MRUBY_CONFIG'] != '') ? ENV['MRUBY_CONFIG'] : "#{MRUBY_ROOT}/build_config.rb"
if ENV['MRUBY_CONFIG']
MRUBY_CONFIG = ENV['MRUBY_CONFIG']
MRUBY_TARGET = File.basename(MRUBY_CONFIG, ".rb")
else
MRUBY_TARGET = ENV['MRUBY_TARGET'] || ENV['TARGET'] || "host"
MRUBY_CONFIG = "#{MRUBY_ROOT}/target/#{MRUBY_TARGET}.rb"
end
load MRUBY_CONFIG
# load basic rules
......@@ -46,15 +52,19 @@ task :default => :all
bin_path = ENV['INSTALL_DIR'] || "#{MRUBY_ROOT}/bin"
depfiles = MRuby.targets['host'].bins.map do |bin|
install_path = MRuby.targets['host'].exefile("#{bin_path}/#{bin}")
source_path = MRuby.targets['host'].exefile("#{MRuby.targets['host'].build_dir}/bin/#{bin}")
if MRuby.targets['host']
target = MRuby.targets['host']
depfiles = target.bins.map do |bin|
install_path = target.exefile("#{bin_path}/#{bin}")
source_path = target.exefile("#{target.build_dir}/bin/#{bin}")
file install_path => source_path do |t|
install_D t.prerequisites.first, t.name
file install_path => source_path do |t|
install_D t.prerequisites.first, t.name
end
install_path
end
install_path
else
depfiles = []
end
MRuby.each_target do |target|
......@@ -87,15 +97,6 @@ MRuby.each_target do |target|
install_D t.prerequisites.first, t.name
end
depfiles += [ install_path ]
elsif target == MRuby.targets['host-debug']
unless MRuby.targets['host'].gems.map {|g| g.bins}.include?([bin])
install_path = MRuby.targets['host-debug'].exefile("#{bin_path}/#{bin}")
file install_path => exec do |t|
install_D t.prerequisites.first, t.name
end
depfiles += [ install_path ]
end
else
depfiles += [ exec ]
end
......@@ -103,6 +104,143 @@ MRuby.each_target do |target|
end
end
mkdir_p "#{MRUBY_ROOT}/build"
cfiles = (
Dir.glob("#{MRUBY_ROOT}/src/*.c")+
Dir.glob("#{MRUBY_ROOT}/mrbgems/**/*.c")+
Dir.glob("#{MRUBY_ROOT}/build/repos/**/{src,core}/*.c")
).uniq
rbfiles = (
Dir.glob("#{MRUBY_ROOT}/mrblib/**/*.rb")+
Dir.glob("#{MRUBY_ROOT}/mrbgems/*/mrblib/**/*.rb")+
Dir.glob("#{MRUBY_ROOT}/build/repos/**/mrblib/**/*.rb")
).uniq
psfiles = Dir.glob("#{MRUBY_ROOT}/{mrblib,mrbgems,build/repos}/**/presym")
symbols = []
psfiles.each do |file|
symbols += File.readlines(file).grep_v(/^# /)
end
symbols.each{|x| x.chomp!}
presym_file="#{MRUBY_ROOT}/build/presym"
op_table = {
"!" => "not",
"!=" => "neq",
"!~" => "nmatch",
"%" => "mod",
"&" => "and",
"&&" => "andand",
"*" => "mul",
"**" => "pow",
"+" => "add",
"+@" => "plus",
"-" => "sub",
"-@" => "minus",
"/" => "div",
"<" => "lt",
"<=" => "le",
"<<" => "lshift",
"<=>" => "cmp",
"==" => "eq",
"===" => "eqq",
"=~" => "match",
">" => "gt",
">=" => "ge",
">>" => "rshift",
"[]" => "aref",
"[]=" => "aset",
"^" => "xor",
"`" => "tick",
"|" => "or",
"||" => "oror",
"~" => "neg",
}
file presym_file => cfiles+rbfiles+psfiles+[__FILE__] do
csymbols = cfiles.map do |f|
src = File.read(f)
src.gsub!(/\/\/.+(\n|$)/, "\n")
[src.scan(/intern_lit\([^\n"]*"([^\n "]*)"/),
src.scan(/mrb_define_method\([^\n"]*"([^\n"]*)"/),
src.scan(/mrb_define_class_method\([^\n"]*"([^\n"]*)"/),
src.scan(/mrb_define_class\([^\n"]*"([^\n"]*)"/),
src.scan(/mrb_define_module\([^\n"]*"([^\n"]*)"/),
src.scan(/mrb_define_module_function\([^\n"]*"([^\n"]*)"/),
src.scan(/mrb_define_const\([^\n"]*"([^\n"]*)"/),
src.scan(/mrb_define_global_const\([^\n"]*"([^\n"]*)"/),
src.scan(/MRB_SYM\((\w+)\)/),
src.scan(/MRB_QSYM\((\w+)\)/).map{|x,|
x.sub!(/_p$/, "?") || x.sub!(/_b$/, "!") || x.sub!(/_e$/, "=") || x.sub!(/^0_/, "@") || x.sub!(/^00_/, "@@")
}.compact]
end
rbsymbols = rbfiles.map do |f|
src = File.read(f)
src.force_encoding(Encoding::BINARY)
[src.scan(/\bclass +([A-Z]\w*)/),
src.scan(/\bmodule +([A-Z]\w*)/),
src.scan(/\bdef +(\w+[!?=]?)/),
src.scan(/\balias +(\w+[!?]?)/),
src.scan(/\b([A-Z]\w*) *=[^=]/),
src.scan(/(\$[a-zA-Z_]\w*)/),
src.scan(/(\$[$!?0-9]\w*)/),
src.scan(/(@@?[a-zA-Z_]\w*)/),
src.scan(/[^.]\.([a-zA-Z_]\w*[!?]?)/),
src.scan(/\.([a-zA-Z_]\w* *=)/).map{|x|x.map{|s|s.gsub(' ', '')}},
src.scan(/\b([a-zA-Z_]\w*):/),
src.scan(/:([a-zA-Z_]\w*[!?=]?)/),
src.scan(/[\(\[\{ ]:"([^"]+)"/).map{|x|x.map{|s|s.gsub('\#', '#')}},
src.scan(/[ \(\[\{]:'([^']+)'/)
]
end
symbols = (symbols+csymbols+rbsymbols+op_table.keys).flatten.compact.uniq.sort.map{|x| x.gsub("\n", '\n')}
presyms = File.readlines(presym_file) rescue []
presyms.each{|x| x.chomp!}
if presyms != symbols
File.write(presym_file, symbols.join("\n"))
end
end
presym_inc=presym_file+".inc"
file presym_inc => presym_file do
presyms = File.readlines(presym_file)
presyms.each{|x| x.chomp!}
File.open(presym_inc, "w") do |f|
f.print "/* MRB_PRESYM_CSYM(sym, num) - symbol which is valid C id name */\n"
f.print "/* MRB_PRESYM_QSYM(name, sym, num) - symbol with alias name */\n"
f.print "/* MRB_PRESYM_SYM(name, num) - symbol which is not valid C id */\n"
presyms.each.with_index do |sym,i|
if sym.bytes.detect{|x|x>0x80} || /\A\$/ =~ sym
f.print "MRB_PRESYM_SYM(\"#{sym}\", #{i+1})\n"
elsif /\A\w+\Z/ =~ sym
f.print "MRB_PRESYM_CSYM(#{sym}, #{i+1})\n"
elsif op_table.key?(sym)
f.print "MRB_PRESYM_QSYM(\"#{sym}\", #{op_table[sym]}, #{i+1})\n"
elsif /\A[A-Za-z_]\w*\?\Z/ =~ sym
s = sym.dup; s[-1] = "_p"
f.print "MRB_PRESYM_QSYM(\"#{sym}\", #{s}, #{i+1})\n"
elsif /\A[A-Za-z_]\w*\!\Z/ =~ sym
s = sym.dup; s[-1] = "_b"
f.print "MRB_PRESYM_QSYM(\"#{sym}\", #{s}, #{i+1})\n"
elsif /\A[A-Za-z_]\w*\=\Z/ =~ sym
s = sym.dup; s[-1] = "_e"
f.print "MRB_PRESYM_QSYM(\"#{sym}\", #{s}, #{i+1})\n"
elsif /\A@@/ =~ sym
s = sym.dup; s[0,2] = "00_"
f.print "MRB_PRESYM_QSYM(\"#{sym}\", #{s}, #{i+1})\n"
elsif /\A@/ =~ sym
s = sym.dup; s[0] = "0_"
f.print "MRB_PRESYM_QSYM(\"#{sym}\", #{s}, #{i+1})\n"
else
f.print "MRB_PRESYM_SYM(\"#{sym}\", #{i+1})\n"
end
end
f.print "#define MRB_PRESYM_MAX #{presyms.size}"
end
end
desc "preallocated symbols"
task :gensym => presym_inc
task :all => :gensym
depfiles += MRuby.targets.map { |n, t|
t.libraries
}.flatten
......@@ -156,5 +294,7 @@ task :deep_clean => ["clean", "clean_doc"] do
MRuby.each_target do |t|
rm_rf t.gem_clone_dir
end
rm_f presym_file
rm_f presym_inc
puts "Cleaned up mrbgems build folder"
end
......@@ -38,7 +38,9 @@ init:
- set PATH=C:\Ruby26-x64\bin;%PATH%
- ruby --version
build_script:
- set MRUBY_CONFIG=appveyor_config.rb
- rake -m -j4
- rake -E STDOUT.sync=true test
- set MRUBY_TARGET=appveyor
- rake gensym
- rake -m all
- rake -E $stdout.sync=true test
......@@ -14,37 +14,53 @@ To compile mruby out of the source code you need the following tools:
Note that `bison` bundled with MacOS is too old to compile `mruby`.
Try `brew install bison` and follow the instuction shown to update
the `$PATH` to compile `mruby`.
the `$PATH` to compile `mruby`. We also encourage to upgrade `ruby`
on MacOS in similar manner.
Optional:
* GIT (to update mruby source and integrate mrbgems easier)
* git (to update mruby source and integrate mrbgems easier)
* C++ compiler (to use GEMs which include \*.cpp, \*.cxx, \*.cc)
* Assembler (to use GEMs which include \*.asm)
## Usage
## Build
To compile `mruby`, just call `rake` inside of the mruby source
root. To generate and execute the test tools call `rake test`. To
clean all build files call `rake clean`. To see full command line on
build, call `rake -v`.
If you want to compile for the specific configuration, specify
`MRUBY_TARGET` or `TARGET` environment variable, e.g
```sh
rake TAGRET=host
```
The default target is `host`. The compilation target desciption files
(with `.rb` suffix) are contained in the `target` directory.
A build description file contains the build configuration of mruby and
looks like the following for example:
Inside of the root directory of the mruby source a file exists
called *build_config.rb*. This file contains the build configuration
of mruby and looks like this for example:
```ruby
MRuby::Build.new do |conf|
toolchain :gcc
end
```
All tools necessary to compile mruby can be set or modified here. In case
you want to maintain an additional *build_config.rb* you can define a
customized path using the *$MRUBY_CONFIG* environment variable.
To compile just call `rake` inside of the mruby source root. To
generate and execute the test tools call `rake test`. To clean
all build files call `rake clean`. To see full command line on
build, call `rake -v`.
All tools necessary to compile mruby can be set or modified here. In
case you want to try different configuration, you can create a new
configuration file under `target` and specify the configuration using
the `MRUBY_TARGET` environment variable.
## Build Configuration
Inside of the *build_config.rb* the following options can be configured
based on your environment.
To create a new configuration, copy the existing configuration in the
`target` directory, and modify it. We wish you submit a pull-request,
once you created a new configuration for a new platform.
Inside of the configuration file, the following options can be
configured based on your environment.
### Toolchains
......@@ -88,15 +104,12 @@ in `ANDROID_STANDALONE_TOOLCHAIN`.
### Binaries
It is possible to select which tools should be compiled during the compilation
process. The following tools can be selected:
* mruby (mruby interpreter)
* mirb (mruby interactive shell)
process. For example,
To select them declare conf.gem as follows:
```ruby
conf.gem "#{root}/mrbgems/mruby-bin-mruby"
conf.gem "#{root}/mrbgems/mruby-bin-mirb"
```
* `mruby`
* `mirb`
The configuration are done via `mrbgems`. See `Mrbgems` section.
### File Separator
......@@ -209,17 +222,33 @@ end
### Mrbgems
Integrate GEMs in the build process.
`mruby` comes with the (sort of) packaging system named `mrbgems`. To
specify `gem`, you can use `conf.gem` in the configuration file.
```ruby
# Integrate GEM with additional configuration
conf.gem 'path/to/gem' do |g|
g.cc.flags << ...
end
# Integrate a bundled Gem you see in `mrbgems` directory
conf.gem :core => 'mruby-something'
# Integrate a Gem from GitHub
conf.gem :github => 'someone/mruby-another'
# Integrate GEM without additional configuration
conf.gem 'path/to/another/gem'
# Integrate a mruby binary Gem
conf.gem :core => 'mruby-bin-mruby'
# Integrate a interactive mruby binary Gem
conf.gem :core => 'mruby-bin-mirb'
# Integrate GemBox (set of Gems)
conf.gembox "default"
```
A GemBox is a set of Gems defined in `mrbgems/default.gembox` for example.
It's just a set of `mrbgem` configurations.
There is a `RubyGem` (gem for CRuby) named `mgem` that help you to
manage `mrbgems`. Try `gem install mgem`. `mgem` can show you the list
of registered `mrbgems`.
See doc/mrbgems/README.md for more option about mrbgems.
### Mrbtest
......@@ -327,6 +356,10 @@ root directory. The structure of this directory will look like this:
+- build
|
+- presym <- List of preallocated symbolx
|
+- presym.inc <- C source file for preallocated symbols
|
+- host
|
+- bin <- Binaries (mirb, mrbc and mruby)
......@@ -378,6 +411,10 @@ In case of a cross-compilation to *i386* the *build* directory structure looks
like this:
+- build
|
+- presym <- List of preallocated symbolx
|
+- presym.inc <- C source file for preallocated symbols
|
+- host
| |
......
......@@ -46,11 +46,11 @@ You can use mrbconfs with following ways:
## Primitive type configuration.
`MRB_USE_FLOAT`
`MRB_USE_FLOAT32`
* When defined single precision floating point type(C type `float`) is used as `mrb_float`.
* Else double precision floating point type(C type `double`) is used as `mrb_float`.
* Otherwise double precision floating point type(C type `double`) is used as `mrb_float`.
`MRB_WITHOUT_FLOAT`
`MRB_NO_FLOAT`
* When defined removes floating point numbers from mruby.
* It makes mruby easier to handle in "Microcontroller without FPU" and "Kernel Space".
......@@ -117,7 +117,7 @@ largest value of required alignment.
`MRB_NAN_BOXING`
* If defined represent `mrb_value` in boxed `double`.
* Conflicts with `MRB_USE_FLOAT` and `MRB_WITHOUT_FLOAT`.
* Conflicts with `MRB_USE_FLOAT32` and `MRB_NO_FLOAT`.
`MRB_WORD_BOXING`
* If defined represent `mrb_value` as a word.
......@@ -163,17 +163,17 @@ largest value of required alignment.
* Default value is `128`.
* Specifies initial capacity of `RString` created by `mrb_str_buf_new` function..
`MRB_METHOD_CACHE`
* Improve performance for method dispatch.
`MRB_NO_METHOD_CACHE`
* Disable method cache to save memory.
`MRB_METHOD_CACHE_SIZE`
* Default value is `128`.
* Ignored if `MRB_METHOD_CACHE` is not defined.
* Default value is `256`.
* Ignored if `MRB_NO_METHOD_CACHE` is defined.
* Need to be the power of 2.
`MRB_METHOD_T_STRUCT`
`MRB_USE_METHOD_T_STRUCT`
* Use C struct to represent `mrb_method_t`
* No `MRB_METHOD_T_STRUCT` requires highest 2 bits of function pointers to be zero
* No `MRB_USE_METHOD_T_STRUCT` requires highest 2 bits of function pointers to be zero
* Define this macro on machines that use higher bits of pointers
`MRB_ENABLE_ALL_SYMBOLS`
......
......@@ -17,7 +17,7 @@ Please help to improve it by submitting your findings.
## `1/2` gives `0.5`
Since mruby does not have `Bignum`, bigger integers are represented
by `Float` numbers. To enhance interoperability between `Fixnum`
by `Float` numbers. To enhance interoperability between `Integer`
and `Float`, mruby provides `Float#upto` and other iterating
methods for the `Float` class. As a side effect, `1/2` gives `0.5`
not `0`.
......@@ -63,8 +63,15 @@ end
#### mruby [2.1.2 (2020-08-06)]
No exception is raised.
No exception is raised. Instead you have to do:
```ruby
begin
1 / 0
rescue => e
raise e
end
```
## Fiber execution can't cross C function boundary
mruby's `Fiber` is implemented in a similar way to Lua's co-routine. This
......@@ -245,8 +252,7 @@ trace (most recent call last):
## Keyword arguments
mruby keyword arguments behave slightly different from CRuby 2.5
to make the behavior simpler and less confusing. Maybe in the
future, the simpler behavior will be adopted to CRuby as well.
to make the behavior simpler and less confusing.
#### Ruby [ruby 2.5.1p57 (2018-03-29 revision 63029)]
......@@ -264,6 +270,20 @@ trace (most recent call last):
-e:1: keyword argument hash with non symbol keys (ArgumentError)
```
## `nil?` redefinition in conditional expressions
Redefinition of `nil?` is ignored in conditional expressions.
```ruby
a = "a"
def a.nil?
true
end
puts(a.nil? ? "truthy" : "falsy")
```
Ruby outputs `falsy`. mruby outputs `truthy`.
## Argument Destructuring
```ruby
......@@ -283,17 +303,3 @@ f(1,[2,3])
```
CRuby gives `[1,2,3,nil]`. mruby raises `NoMethodError` for `b`.
## `nil?` redefinition in conditional expressions
Redefinition of `nil?` is ignored in conditional expressions.
```ruby
a = "a"
def a.nil?
true
end
puts(a.nil? ? "truthy" : "falsy")
```
Ruby outputs `falsy`. mruby outputs `truthy`.
User visible changes in `mruby3`
===
# Build System
You can specify `TARGET` option to `rake` via a command line
option, or via an environment variable, e.g.
`rake TARGET=host all`
or
`TARGET=host rake all`
It's much easier to switch multiple targets than the
previous `build_config.rb` system.
## `presym` target
The first compilation of `mruby` may require generation of a
static symbol table named `build/presym`. You can generate
the table by `rake gensym`.
## `target` directory
Build target specification files are loaded from `target`
directory. The default `TARGET` is `host` which is described
in `target/host.rb`. There are many other targets for example:
* `host-gprof`: compiles with `gprof` for performance tuning
* `host-m32`: compiles in gcc 32bit mode on 64bit platforms
* `boxing`: compiles all three boxing options
* `clang-asan`: compiles with `clang`'s Address Sanitizer
`target/host.rb` comes with comments to help writing a new
target description.
If you want to have your target description out of the
source tree, you can specify the path to the description
file in `MRUBY_CONFIG`.
# Build Target Contribution
When you write a new target description, please
contribute. We welcome your contribution as a GitHub
pull-request.
# Languge Changes
## New Syntax
We have ported some new syntax from CRuby.
* R-assignment (`12 => x`)
* Numbered block parameter (`x.map{_1 * 2}`)
* End-less `def` (`def double(x) = x*2`)
# Configuration Options Changed
Some configuration macro names are changed for consistency
## `MRB_NO_FLOAT`
Changed from `MRB_WITHOUT_FLOAT` to conform `USE_XXX` naming
convention.
## `MRB_USE_FLOAT32`
Changed from `MRB_USE_FLOAT` to make sure `float` here means
using single precision float, and not the opposite of
`MRB_NO_FLOAT`.
## `MRB_USE_METHOD_T_STRUCT`
Changed from `MRB_METHOD_T_STRUCT`.
To use `struct` version of `mrb_method_t`. More portable but consumes more memory.
Turned on by default on 32bit platforms.
## `MRB_NO_BOXING`
Uses `struct` to represent `mrb_value`. Consumes more memory
but easier to inveticate the internal and to debug. It used
to be default `mrb_value` representation. Now the default is
`MRB_WORD_BOXING`.
## `MRB_WORD_BOXING`
Pack `mrb_value` in an `intptr_t` integer. Consumes less
memory compared to `MRB_NO_BOXING` especially on 32 bit
platforms. `Fixnum` size is 31 bits so some integer values
does not fit in `Fixnum` integers.
## `MRB_NAN_BOXING`
Pack `mrb_value` in a floating pointer number. Nothing
changed from previous versions.
## `MRB_USE_MALLOC_TRIM`
Call `malloc_trim(0)` from mrb_full_gc() if this macro is defined.
If you are using glibc malloc, this macro could reduce memory consumption.
# Internal Changes
## `Random` now use `xoshiro128++`.
For better and faster random number generation.
This diff is collapsed.
......@@ -25,33 +25,69 @@
#endif
/* configuration options: */
/* add -DMRB_USE_FLOAT to use float instead of double for floating point numbers */
//#define MRB_USE_FLOAT
/* add -DMRB_USE_FLOAT32 to use float instead of double for floating point numbers */
//#define MRB_USE_FLOAT32
/* exclude floating point numbers */
//#define MRB_WITHOUT_FLOAT
//#define MRB_NO_FLOAT
/* add -DMRB_METHOD_CACHE to use method cache to improve performance */
//#define MRB_METHOD_CACHE
/* obsolete configuration */
#if defined(MRB_USE_FLOAT)
# define MRB_USE_FLOAT32
#endif
/* obsolete configuration */
#if defined(MRB_WITHOUT_FLOAT)
# define MRB_NO_FLOAT
#endif
#if defined(MRB_USE_FLOAT32) && defined(MRB_NO_FLOAT)
#error Cannot define MRB_USE_FLOAT32 and MRB_NO_FLOAT at the same time
#endif
/* add -DMRB_NO_METHOD_CACHE to disable method cache to save memory */
//#define MRB_NO_METHOD_CACHE
/* size of the method cache (need to be the power of 2) */
//#define MRB_METHOD_CACHE_SIZE (1<<7)
//#define MRB_METHOD_CACHE_SIZE (1<<8)
/* add -DMRB_METHOD_T_STRUCT on machines that use higher bits of pointers */
/* no MRB_METHOD_T_STRUCT requires highest 2 bits of function pointers to be zero */
#ifndef MRB_METHOD_T_STRUCT
/* add -DMRB_USE_METHOD_T_STRUCT on machines that use higher bits of function pointers */
/* no MRB_USE_METHOD_T_STRUCT requires highest 2 bits of function pointers to be zero */
#ifndef MRB_USE_METHOD_T_STRUCT
// can't use highest 2 bits of function pointers at least on 32bit
// Windows and 32bit Linux.
# ifdef MRB_32BIT
# define MRB_METHOD_T_STRUCT
# define MRB_USE_METHOD_T_STRUCT
# endif
#endif
/* define on big endian machines; used by MRB_NAN_BOXING, etc. */
#ifndef MRB_ENDIAN_BIG
# if (defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN) || \
(defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
# define MRB_ENDIAN_BIG
# endif
#endif
/* represent mrb_value in boxed double; conflict with MRB_USE_FLOAT32 and MRB_NO_FLOAT */
//#define MRB_NAN_BOXING
/* represent mrb_value as a word (natural unit of data for the processor) */
//#define MRB_WORD_BOXING
/* represent mrb_value as a struct; occupies 2 words */
//#define MRB_NO_BOXING
/* if no specific boxing type is chosen */
#if !defined(MRB_NAN_BOXING) && !defined(MRB_WORD_BOXING) && !defined(MRB_NO_BOXING)
# define MRB_WORD_BOXING
#endif
/* add -DMRB_INT32 to use 32bit integer for mrb_int; conflict with MRB_INT64;
Default for 32-bit CPU mode. */
//#define MRB_INT32
/* add -DMRB_INT64 to use 64bit integer for mrb_int; conflict with MRB_INT32;
Default for 64-bit CPU mode. */
Default for 64-bit CPU mode (unless using MRB_NAN_BOXING). */
//#define MRB_INT64
/* if no specific integer type is chosen */
......@@ -65,19 +101,8 @@
# endif
#endif
/* define on big endian machines; used by MRB_NAN_BOXING, etc. */
#ifndef MRB_ENDIAN_BIG
# if (defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN) || \
(defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
# define MRB_ENDIAN_BIG
# endif
#endif
/* represent mrb_value in boxed double; conflict with MRB_USE_FLOAT and MRB_WITHOUT_FLOAT */
//#define MRB_NAN_BOXING
/* represent mrb_value as a word (natural unit of data for the processor) */
//#define MRB_WORD_BOXING
/* call malloc_trim(0) from mrb_full_gc() */
//#define MRB_USE_MALLOC_TRIM
/* string class to handle UTF-8 encoding */
//#define MRB_UTF8_STRING
......@@ -160,6 +185,10 @@
/* A profile for micro controllers */
#if defined(MRB_CONSTRAINED_BASELINE_PROFILE)
# ifndef MRB_NO_METHOD_CACHE
# define MRB_NO_METHOD_CACHE
# endif
# ifndef KHASH_DEFAULT_SIZE
# define KHASH_DEFAULT_SIZE 16
# endif
......@@ -177,10 +206,6 @@
/* A profile for desktop computers or workstations; rich memory! */
#elif defined(MRB_MAIN_PROFILE)
# ifndef MRB_METHOD_CACHE
# define MRB_METHOD_CACHE
# endif
# ifndef MRB_METHOD_CACHE_SIZE
# define MRB_METHOD_CACHE_SIZE (1<<10)
# endif
......@@ -195,10 +220,6 @@
/* A profile for server; mruby vm is long life */
#elif defined(MRB_HIGH_PROFILE)
# ifndef MRB_METHOD_CACHE
# define MRB_METHOD_CACHE
# endif
# ifndef MRB_METHOD_CACHE_SIZE
# define MRB_METHOD_CACHE_SIZE (1<<12)
# endif
......
This diff is collapsed.
......@@ -21,7 +21,14 @@ typedef struct mrb_shared_array {
mrb_value *ptr;
} mrb_shared_array;
#define MRB_ARY_EMBED_LEN_MAX ((mrb_int)(sizeof(void*)*3/sizeof(mrb_value)))
#if defined(MRB_32BIT) && defined(MRB_NO_BOXING)
# define MRB_ARY_NO_EMBED
# define MRB_ARY_EMBED_LEN_MAX 0
#else
# define MRB_ARY_EMBED_LEN_MAX ((mrb_int)(sizeof(void*)*3/sizeof(mrb_value)))
mrb_static_assert(MRB_ARY_EMBED_LEN_MAX > 0, "MRB_ARY_EMBED_LEN_MAX > 0");
#endif
struct RArray {
MRB_OBJECT_HEADER;
union {
......@@ -33,7 +40,9 @@ struct RArray {
} aux;
mrb_value *ptr;
} heap;
void *ary[3];
#ifndef MRB_ARY_NO_EMBED
mrb_value ary[MRB_ARY_EMBED_LEN_MAX];
#endif
} as;
};
......@@ -41,13 +50,21 @@ struct RArray {
#define mrb_ary_value(p) mrb_obj_value((void*)(p))
#define RARRAY(v) ((struct RArray*)(mrb_ptr(v)))
#ifdef MRB_ARY_NO_EMBED
#define ARY_EMBED_P(a) 0
#define ARY_UNSET_EMBED_FLAG(a) (void)0
#define ARY_EMBED_LEN(a) 0
#define ARY_SET_EMBED_LEN(a,len) (void)0
#define ARY_EMBED_PTR(a) 0
#else
#define MRB_ARY_EMBED_MASK 7
#define ARY_EMBED_P(a) ((a)->flags & MRB_ARY_EMBED_MASK)
#define ARY_UNSET_EMBED_FLAG(a) ((a)->flags &= ~(MRB_ARY_EMBED_MASK))
#define ARY_EMBED_LEN(a) ((mrb_int)(((a)->flags & MRB_ARY_EMBED_MASK) - 1))
#define ARY_SET_EMBED_LEN(a,len) ((a)->flags = ((a)->flags&~MRB_ARY_EMBED_MASK) | ((uint32_t)(len) + 1))
#define ARY_EMBED_PTR(a) ((mrb_value*)(&(a)->as.ary))
#define ARY_EMBED_PTR(a) ((a)->as.ary)
#endif
#define ARY_LEN(a) (ARY_EMBED_P(a)?ARY_EMBED_LEN(a):(a)->as.heap.len)
#define ARY_PTR(a) (ARY_EMBED_P(a)?ARY_EMBED_PTR(a):(a)->as.heap.ptr)
#define RARRAY_LEN(a) ARY_LEN(RARRAY(a))
......
......@@ -7,12 +7,12 @@
#ifndef MRUBY_BOXING_NAN_H
#define MRUBY_BOXING_NAN_H
#ifdef MRB_USE_FLOAT
# error ---->> MRB_NAN_BOXING and MRB_USE_FLOAT conflict <<----
#ifdef MRB_USE_FLOAT32
# error ---->> MRB_NAN_BOXING and MRB_USE_FLOAT32 conflict <<----
#endif
#ifdef MRB_WITHOUT_FLOAT
# error ---->> MRB_NAN_BOXING and MRB_WITHOUT_FLOAT conflict <<----
#ifdef MRB_NO_FLOAT
# error ---->> MRB_NAN_BOXING and MRB_NO_FLOAT conflict <<----
#endif
#ifdef MRB_INT64
......@@ -30,76 +30,91 @@
* In order to get enough bit size to save TT, all pointers are shifted 2 bits
* in the right direction. Also, TTTTTT is the mrb_vtype + 1;
*/
typedef struct mrb_value {
union {
mrb_float f;
union {
void *p;
struct {
MRB_ENDIAN_LOHI(
uint32_t ttt;
,union {
mrb_int i;
mrb_sym sym;
};
)
};
typedef uint64_t mrb_value;
union mrb_value_ {
mrb_float f;
uint64_t u;
#ifdef MRB_64BIT
struct RCptr *vp;
void *p;
#endif
} value;
struct {
MRB_ENDIAN_LOHI(
uint32_t ttt;
,uint32_t i;
)
};
} mrb_value;
};
#define mrb_float_pool(mrb,f) mrb_float_value(mrb,f)
static inline union mrb_value_
mrb_val_union(mrb_value v)
{
union mrb_value_ x;
x.u = v;
return x;
}
#define mrb_tt(o) ((enum mrb_vtype)(((o).value.ttt & 0xfc000)>>14)-1)
#define mrb_type(o) (enum mrb_vtype)((uint32_t)0xfff00000 < (o).value.ttt ? mrb_tt(o) : MRB_TT_FLOAT)
#define mrb_ptr(o) ((void*)((((uintptr_t)0x3fffffffffff)&((uintptr_t)((o).value.p)))<<2))
#define mrb_float(o) (o).f
#define mrb_fixnum(o) (o).value.i
#define mrb_symbol(o) (o).value.sym
#define mrb_tt(o) ((enum mrb_vtype)((mrb_val_union(o).ttt & 0xfc000)>>14)-1)
#define mrb_type(o) (enum mrb_vtype)((uint32_t)0xfff00000 < mrb_val_union(o).ttt ? mrb_tt(o) : MRB_TT_FLOAT)
#define mrb_float(o) mrb_val_union(o).f
#define mrb_fixnum(o) ((mrb_int)mrb_val_union(o).i)
#define mrb_integer(o) mrb_fixnum(o)
#define mrb_symbol(o) ((mrb_sym)mrb_val_union(o).i)
#ifdef MRB_64BIT
MRB_API mrb_value mrb_nan_boxing_cptr_value(struct mrb_state*, void*);
#define mrb_ptr(o) ((void*)((((uintptr_t)0x3fffffffffff)&((uintptr_t)(mrb_val_union(o).p)))<<2))
#define mrb_cptr(o) (((struct RCptr*)mrb_ptr(o))->p)
#define BOXNAN_SHIFT_LONG_POINTER(v) (((uintptr_t)(v)>>34)&0x3fff)
#else
#define mrb_cptr(o) ((o).value.p)
#define mrb_ptr(o) ((void*)mrb_val_union(o).i)
#define mrb_cptr(o) mrb_ptr(o)
#define BOXNAN_SHIFT_LONG_POINTER(v) 0
#endif
#define BOXNAN_SET_VALUE(o, tt, attr, v) do {\
(o).attr = (v);\
(o).value.ttt = 0xfff00000 | (((tt)+1)<<14);\
#define BOXNAN_SET_VALUE(o, tt, attr, v) do { \
union mrb_value_ mrb_value_union_variable; \
mrb_value_union_variable.attr = (v);\
mrb_value_union_variable.ttt = 0xfff00000 | (((tt)+1)<<14);\
o = mrb_value_union_variable.u;\
} while (0)
#ifdef MRB_64BIT
#define BOXNAN_SET_OBJ_VALUE(o, tt, v) do {\
(o).value.p = (void*)((uintptr_t)(v)>>2);\
(o).value.ttt = (0xfff00000|(((tt)+1)<<14)|BOXNAN_SHIFT_LONG_POINTER(v));\
union mrb_value_ mrb_value_union_variable;\
mrb_value_union_variable.p = (void*)((uintptr_t)(v)>>2);\
mrb_value_union_variable.ttt = (0xfff00000|(((tt)+1)<<14)|BOXNAN_SHIFT_LONG_POINTER(v));\
o = mrb_value_union_variable.u;\
} while (0)
#else
#define BOXNAN_SET_OBJ_VALUE(o, tt, v) BOXNAN_SET_VALUE(o, tt, i, (uint32_t)v)
#endif
#define SET_FLOAT_VALUE(mrb,r,v) do { \
if ((v) != (v)) { \
(r).value.ttt = 0x7ff80000; \
(r).value.i = 0; \
union mrb_value_ mrb_value_union_variable; \
if ((v) != (v)) { /* NaN */ \
mrb_value_union_variable.ttt = 0x7ff80000; \
mrb_value_union_variable.i = 0; \
} \
else { \
(r).f = v; \
}} while(0)
mrb_value_union_variable.f = (v); \
} \
r = mrb_value_union_variable.u; \
} while(0)
#define SET_NIL_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_FALSE, value.i, 0)
#define SET_FALSE_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_FALSE, value.i, 1)
#define SET_TRUE_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_TRUE, value.i, 1)
#define SET_BOOL_VALUE(r,b) BOXNAN_SET_VALUE(r, b ? MRB_TT_TRUE : MRB_TT_FALSE, value.i, 1)
#define SET_INT_VALUE(r,n) BOXNAN_SET_VALUE(r, MRB_TT_FIXNUM, value.i, (n))
#define SET_SYM_VALUE(r,v) BOXNAN_SET_VALUE(r, MRB_TT_SYMBOL, value.sym, (v))
#define SET_NIL_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_FALSE, i, 0)
#define SET_FALSE_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_FALSE, i, 1)
#define SET_TRUE_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_TRUE, i, 1)
#define SET_BOOL_VALUE(r,b) BOXNAN_SET_VALUE(r, b ? MRB_TT_TRUE : MRB_TT_FALSE, i, 1)
#define SET_INT_VALUE(mrb, r,n) BOXNAN_SET_VALUE(r, MRB_TT_INTEGER, i, (uint32_t)(n))
#define SET_FIXNUM_VALUE(r,n) BOXNAN_SET_VALUE(r, MRB_TT_INTEGER, i, (uint32_t)(n))
#define SET_SYM_VALUE(r,v) BOXNAN_SET_VALUE(r, MRB_TT_SYMBOL, i, (uint32_t)(v))
#define SET_OBJ_VALUE(r,v) BOXNAN_SET_OBJ_VALUE(r, (((struct RObject*)(v))->tt), (v))
#ifdef MRB_64BIT
MRB_API mrb_value mrb_nan_boxing_cptr_value(struct mrb_state*, void*);
#define SET_CPTR_VALUE(mrb,r,v) ((r) = mrb_nan_boxing_cptr_value(mrb, v))
#else
#define SET_CPTR_VALUE(mrb,r,v) BOXNAN_SET_VALUE(r, MRB_TT_CPTR, value.p, v)
#define SET_CPTR_VALUE(mrb,r,v) BOXNAN_SET_VALUE(r, MRB_TT_CPTR, p, v)
#endif
#define SET_UNDEF_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_UNDEF, value.i, 0)
#define SET_UNDEF_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_UNDEF, i, 0)
#endif /* MRUBY_BOXING_NAN_H */
......@@ -11,7 +11,7 @@
#define MRB_SYMBOL_SHIFT 0
union mrb_value_union {
#ifndef MRB_WITHOUT_FLOAT
#ifndef MRB_NO_FLOAT
mrb_float f;
#endif
void *p;
......@@ -24,16 +24,13 @@ typedef struct mrb_value {
enum mrb_vtype tt;
} mrb_value;
#ifndef MRB_WITHOUT_FLOAT
#define mrb_float_pool(mrb,f) mrb_float_value(mrb,f)
#endif
#define mrb_ptr(o) (o).value.p
#define mrb_cptr(o) mrb_ptr(o)
#ifndef MRB_WITHOUT_FLOAT
#ifndef MRB_NO_FLOAT
#define mrb_float(o) (o).value.f
#endif
#define mrb_fixnum(o) (o).value.i
#define mrb_integer(o) mrb_fixnum(o)
#define mrb_symbol(o) (o).value.sym
#define mrb_type(o) (o).tt
......@@ -46,8 +43,9 @@ typedef struct mrb_value {
#define SET_FALSE_VALUE(r) BOXNIX_SET_VALUE(r, MRB_TT_FALSE, value.i, 1)
#define SET_TRUE_VALUE(r) BOXNIX_SET_VALUE(r, MRB_TT_TRUE, value.i, 1)
#define SET_BOOL_VALUE(r,b) BOXNIX_SET_VALUE(r, b ? MRB_TT_TRUE : MRB_TT_FALSE, value.i, 1)
#define SET_INT_VALUE(r,n) BOXNIX_SET_VALUE(r, MRB_TT_FIXNUM, value.i, (n))
#ifndef MRB_WITHOUT_FLOAT
#define SET_INT_VALUE(mrb,r,n) BOXNIX_SET_VALUE(r, MRB_TT_INTEGER, value.i, (n))
#define SET_FIXNUM_VALUE(r,n) BOXNIX_SET_VALUE(r, MRB_TT_INTEGER, value.i, (n))
#ifndef MRB_NO_FLOAT
#define SET_FLOAT_VALUE(mrb,r,v) BOXNIX_SET_VALUE(r, MRB_TT_FLOAT, value.f, (v))
#endif
#define SET_SYM_VALUE(r,v) BOXNIX_SET_VALUE(r, MRB_TT_SYMBOL, value.sym, (v))
......
......@@ -11,13 +11,18 @@
#error MRB_INT64 cannot be used with MRB_WORD_BOXING in 32-bit mode.
#endif
#ifndef MRB_WITHOUT_FLOAT
#ifndef MRB_NO_FLOAT
struct RFloat {
MRB_OBJECT_HEADER;
mrb_float f;
};
#endif
struct RInteger {
MRB_OBJECT_HEADER;
mrb_int i;
};
enum mrb_special_consts {
MRB_Qnil = 0,
MRB_Qfalse = 4,
......@@ -47,13 +52,13 @@ enum mrb_special_consts {
#define BOXWORD_IMMEDIATE_MASK 0x07
#define BOXWORD_SHIFT_VALUE(o,n,t) \
(t)(((long)(o).w) >> BOXWORD_##n##_SHIFT)
(t)(((intptr_t)(o)) >> BOXWORD_##n##_SHIFT)
#define BOXWORD_SET_SHIFT_VALUE(o,n,v) \
((o).w = (((unsigned long)(v)) << BOXWORD_##n##_SHIFT) | BOXWORD_##n##_FLAG)
((o) = (((uintptr_t)(v)) << BOXWORD_##n##_SHIFT) | BOXWORD_##n##_FLAG)
#define BOXWORD_SHIFT_VALUE_P(o,n) \
(((o).w & BOXWORD_##n##_MASK) == BOXWORD_##n##_FLAG)
(((o) & BOXWORD_##n##_MASK) == BOXWORD_##n##_FLAG)
#define BOXWORD_OBJ_TYPE_P(o,n) \
(!mrb_immediate_p(o) && (o).value.bp->tt == MRB_TT_##n)
(!mrb_immediate_p(o) && mrb_val_union(o).bp->tt == MRB_TT_##n)
/*
* mrb_value representation:
......@@ -66,62 +71,74 @@ enum mrb_special_consts {
* symbol: ...SSSS SS10 (use only upper 32-bit as symbol value on 64-bit CPU)
* object: ...PPPP P000 (any bits are 1)
*/
typedef union mrb_value {
union {
void *p;
typedef uintptr_t mrb_value;
union mrb_value_ {
void *p;
#ifdef MRB_64BIT
/* use struct to avoid bit shift. */
struct {
MRB_ENDIAN_LOHI(
mrb_sym sym;
,uint32_t sym_flag;
)
};
/* use struct to avoid bit shift. */
struct {
MRB_ENDIAN_LOHI(
mrb_sym sym;
,uint32_t sym_flag;
)
};
#endif
struct RBasic *bp;
#ifndef MRB_WITHOUT_FLOAT
struct RFloat *fp;
struct RBasic *bp;
#ifndef MRB_NO_FLOAT
struct RFloat *fp;
#endif
struct RCptr *vp;
} value;
unsigned long w;
} mrb_value;
struct RInteger *ip;
struct RCptr *vp;
uintptr_t w;
};
static inline union mrb_value_
mrb_val_union(mrb_value v)
{
union mrb_value_ x;
x.w = v;
return x;
}
MRB_API mrb_value mrb_word_boxing_cptr_value(struct mrb_state*, void*);
#ifndef MRB_WITHOUT_FLOAT
#ifndef MRB_NO_FLOAT
MRB_API mrb_value mrb_word_boxing_float_value(struct mrb_state*, mrb_float);
MRB_API mrb_value mrb_word_boxing_float_pool(struct mrb_state*, mrb_float);
#endif
MRB_API mrb_value mrb_word_boxing_int_value(struct mrb_state*, mrb_int);
#ifndef MRB_WITHOUT_FLOAT
#define mrb_float_pool(mrb,f) mrb_word_boxing_float_pool(mrb,f)
#endif
#define mrb_immediate_p(o) ((o) & BOXWORD_IMMEDIATE_MASK || (o) == MRB_Qnil)
#define mrb_ptr(o) (o).value.p
#define mrb_cptr(o) (o).value.vp->p
#ifndef MRB_WITHOUT_FLOAT
#define mrb_float(o) (o).value.fp->f
#define mrb_ptr(o) mrb_val_union(o).p
#define mrb_cptr(o) mrb_val_union(o).vp->p
#ifndef MRB_NO_FLOAT
#define mrb_float(o) mrb_val_union(o).fp->f
#endif
#define mrb_fixnum(o) BOXWORD_SHIFT_VALUE(o, FIXNUM, mrb_int)
MRB_INLINE mrb_int
mrb_integer_func(mrb_value o) {
if (mrb_immediate_p(o)) return mrb_fixnum(o);
return mrb_val_union(o).ip->i;
}
#define mrb_integer(o) mrb_integer_func(o)
#ifdef MRB_64BIT
#define mrb_symbol(o) (o).value.sym
#define mrb_symbol(o) mrb_val_union(o).sym
#else
#define mrb_symbol(o) BOXWORD_SHIFT_VALUE(o, SYMBOL, mrb_sym)
#endif
#define mrb_bool(o) (((o).w & ~(unsigned long)MRB_Qfalse) != 0)
#define mrb_bool(o) (((o) & ~(unsigned long)MRB_Qfalse) != 0)
#define mrb_immediate_p(o) ((o).w & BOXWORD_IMMEDIATE_MASK || (o).w == MRB_Qnil)
#define mrb_fixnum_p(o) BOXWORD_SHIFT_VALUE_P(o, FIXNUM)
#define mrb_integer_p(o) (BOXWORD_SHIFT_VALUE_P(o, FIXNUM)||BOXWORD_OBJ_TYPE_P(o, INTEGER))
#ifdef MRB_64BIT
#define mrb_symbol_p(o) ((o).value.sym_flag == BOXWORD_SYMBOL_FLAG)
#define mrb_symbol_p(o) (mrb_val_union(o).sym_flag == BOXWORD_SYMBOL_FLAG)
#else
#define mrb_symbol_p(o) BOXWORD_SHIFT_VALUE_P(o, SYMBOL)
#endif
#define mrb_undef_p(o) ((o).w == MRB_Qundef)
#define mrb_nil_p(o) ((o).w == MRB_Qnil)
#define mrb_false_p(o) ((o).w == MRB_Qfalse)
#define mrb_true_p(o) ((o).w == MRB_Qtrue)
#ifndef MRB_WITHOUT_FLOAT
#define mrb_undef_p(o) ((o) == MRB_Qundef)
#define mrb_nil_p(o) ((o) == MRB_Qnil)
#define mrb_false_p(o) ((o) == MRB_Qfalse)
#define mrb_true_p(o) ((o) == MRB_Qtrue)
#ifndef MRB_NO_FLOAT
#define mrb_float_p(o) BOXWORD_OBJ_TYPE_P(o, FLOAT)
#endif
#define mrb_array_p(o) BOXWORD_OBJ_TYPE_P(o, ARRAY)
......@@ -143,32 +160,38 @@ MRB_API mrb_value mrb_word_boxing_float_pool(struct mrb_state*, mrb_float);
#define mrb_istruct_p(o) BOXWORD_OBJ_TYPE_P(o, ISTRUCT)
#define mrb_break_p(o) BOXWORD_OBJ_TYPE_P(o, BREAK)
#ifndef MRB_WITHOUT_FLOAT
#ifndef MRB_NO_FLOAT
#define SET_FLOAT_VALUE(mrb,r,v) ((r) = mrb_word_boxing_float_value(mrb, v))
#endif
#define SET_CPTR_VALUE(mrb,r,v) ((r) = mrb_word_boxing_cptr_value(mrb, v))
#define SET_UNDEF_VALUE(r) ((r).w = MRB_Qundef)
#define SET_NIL_VALUE(r) ((r).w = MRB_Qnil)
#define SET_FALSE_VALUE(r) ((r).w = MRB_Qfalse)
#define SET_TRUE_VALUE(r) ((r).w = MRB_Qtrue)
#define SET_UNDEF_VALUE(r) ((r) = MRB_Qundef)
#define SET_NIL_VALUE(r) ((r) = MRB_Qnil)
#define SET_FALSE_VALUE(r) ((r) = MRB_Qfalse)
#define SET_TRUE_VALUE(r) ((r) = MRB_Qtrue)
#define SET_BOOL_VALUE(r,b) ((b) ? SET_TRUE_VALUE(r) : SET_FALSE_VALUE(r))
#define SET_INT_VALUE(r,n) BOXWORD_SET_SHIFT_VALUE(r, FIXNUM, n)
#define SET_INT_VALUE(mrb,r,n) ((r) = mrb_word_boxing_int_value(mrb, n))
#define SET_FIXNUM_VALUE(r,n) BOXWORD_SET_SHIFT_VALUE(r, FIXNUM, n)
#ifdef MRB_64BIT
#define SET_SYM_VALUE(r,v) ((r).value.sym = v, (r).value.sym_flag = BOXWORD_SYMBOL_FLAG)
#define SET_SYM_VALUE(r,v) do {\
union mrb_value_ mrb_value_union_variable;\
mrb_value_union_variable.sym = v;\
mrb_value_union_variable.sym_flag = BOXWORD_SYMBOL_FLAG;\
(r) = mrb_value_union_variable.w;\
} while (0)
#else
#define SET_SYM_VALUE(r,n) BOXWORD_SET_SHIFT_VALUE(r, SYMBOL, n)
#endif
#define SET_OBJ_VALUE(r,v) ((r).value.p = v)
#define SET_OBJ_VALUE(r,v) ((r) = (uintptr_t)v)
MRB_INLINE enum mrb_vtype
mrb_type(mrb_value o)
{
return !mrb_bool(o) ? MRB_TT_FALSE :
mrb_true_p(o) ? MRB_TT_TRUE :
mrb_fixnum_p(o) ? MRB_TT_FIXNUM :
mrb_fixnum_p(o) ? MRB_TT_INTEGER :
mrb_symbol_p(o) ? MRB_TT_SYMBOL :
mrb_undef_p(o) ? MRB_TT_UNDEF :
o.value.bp->tt;
mrb_val_union(o).bp->tt;
}
#endif /* MRUBY_BOXING_WORD_H */
......@@ -17,7 +17,7 @@ MRB_BEGIN_DECL
struct RClass {
MRB_OBJECT_HEADER;
struct iv_tbl *iv;
struct kh_mt *mt;
struct mt_tbl *mt;
struct RClass *super;
};
......@@ -35,9 +35,9 @@ mrb_class(mrb_state *mrb, mrb_value v)
return mrb->true_class;
case MRB_TT_SYMBOL:
return mrb->symbol_class;
case MRB_TT_FIXNUM:
return mrb->fixnum_class;
#ifndef MRB_WITHOUT_FLOAT
case MRB_TT_INTEGER:
return mrb->integer_class;
#ifndef MRB_NO_FLOAT
case MRB_TT_FLOAT:
return mrb->float_class;
#endif
......@@ -73,13 +73,11 @@ mrb_class(mrb_state *mrb, mrb_value v)
#define MRB_SET_INSTANCE_TT(c, tt) ((c)->flags = (((c)->flags & ~MRB_INSTANCE_TT_MASK) | (char)(tt)))
#define MRB_INSTANCE_TT(c) (enum mrb_vtype)((c)->flags & MRB_INSTANCE_TT_MASK)
MRB_API struct RClass* mrb_define_class_id(mrb_state*, mrb_sym, struct RClass*);
MRB_API struct RClass* mrb_define_module_id(mrb_state*, mrb_sym);
struct RClass *mrb_vm_define_class(mrb_state*, mrb_value, mrb_value, mrb_sym);
struct RClass *mrb_vm_define_module(mrb_state*, mrb_value, mrb_sym);
MRB_API void mrb_define_method_raw(mrb_state*, struct RClass*, mrb_sym, mrb_method_t);
MRB_API void mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, mrb_aspec aspec);
MRB_API void mrb_alias_method(mrb_state*, struct RClass *c, mrb_sym a, mrb_sym b);
MRB_API void mrb_remove_method(mrb_state *mrb, struct RClass *c, mrb_sym sym);
MRB_API mrb_method_t mrb_method_search_vm(mrb_state*, struct RClass**, mrb_sym);
MRB_API mrb_method_t mrb_method_search(mrb_state*, struct RClass*, mrb_sym);
......@@ -95,12 +93,17 @@ void mrb_gc_mark_mt(mrb_state*, struct RClass*);
size_t mrb_gc_mark_mt_size(mrb_state*, struct RClass*);
void mrb_gc_free_mt(mrb_state*, struct RClass*);
#ifdef MRB_METHOD_CACHE
#ifndef MRB_NO_METHOD_CACHE
void mrb_mc_clear_by_class(mrb_state *mrb, struct RClass* c);
#else
#define mrb_mc_clear_by_class(mrb,c)
#endif
/* return non zero to break the loop */
struct mt_elem;
typedef int (mrb_mt_foreach_func)(mrb_state*,mrb_sym,struct mt_elem*,void*);
MRB_API void mrb_mt_foreach(mrb_state*, struct RClass*, mrb_mt_foreach_func*, void*);
MRB_END_DECL
#endif /* MRUBY_CLASS_H */
......@@ -33,7 +33,7 @@ typedef struct mrbc_context {
mrb_bool no_exec:1;
mrb_bool keep_lv:1;
mrb_bool no_optimize:1;
struct RProc *upper;
const struct RProc *upper;
size_t parser_nerr;
} mrbc_context;
......@@ -153,7 +153,7 @@ struct mrb_parser_state {
mrb_bool no_optimize:1;
mrb_bool capture_errors:1;
struct RProc *upper;
const struct RProc *upper;
struct mrb_parser_message error_buffer[10];
struct mrb_parser_message warn_buffer[10];
......
......@@ -46,7 +46,7 @@ typedef struct mrb_irep_debug_info {
* get line from irep's debug info and program counter
* @return returns NULL if not found
*/
MRB_API const char *mrb_debug_get_filename(mrb_state *mrb, mrb_irep *irep, ptrdiff_t pc);
MRB_API const char *mrb_debug_get_filename(mrb_state *mrb, const mrb_irep *irep, ptrdiff_t pc);
/*
* get line from irep's debug info and program counter
......
......@@ -18,10 +18,11 @@ MRB_BEGIN_DECL
#define DUMP_DEBUG_INFO 1
int mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size);
int mrb_dump_irep(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size);
#ifndef MRB_DISABLE_STDIO
int mrb_dump_irep_binary(mrb_state*, mrb_irep*, uint8_t, FILE*);
int mrb_dump_irep_cfunc(mrb_state *mrb, mrb_irep*, uint8_t flags, FILE *f, const char *initname);
int mrb_dump_irep_binary(mrb_state*, const mrb_irep*, uint8_t, FILE*);
int mrb_dump_irep_cfunc(mrb_state *mrb, const mrb_irep*, uint8_t flags, FILE *f, const char *initname);
int mrb_dump_irep_cstruct(mrb_state *mrb, const mrb_irep*, uint8_t flags, FILE *f, const char *initname);
mrb_irep *mrb_read_irep_file(mrb_state*, FILE*);
MRB_API mrb_value mrb_load_irep_file(mrb_state*,FILE*);
MRB_API mrb_value mrb_load_irep_file_cxt(mrb_state*, FILE*, mrbc_context*);
......@@ -48,11 +49,16 @@ MRB_API mrb_irep *mrb_read_irep_buf(mrb_state*, const void*, size_t);
/* Rite Binary File header */
#define RITE_BINARY_IDENT "RITE"
#define RITE_BINARY_FORMAT_VER "0007"
/* Binary Format Version Major:Minor */
/* Major: Incompatible to prior versions */
/* Minor: Upper-compatible to prior versions */
#define RITE_BINARY_MAJOR_VER "01"
#define RITE_BINARY_MINOR_VER "00"
#define RITE_BINARY_FORMAT_VER RITE_BINARY_MAJOR_VER RITE_BINARY_MINOR_VER
#define RITE_COMPILER_NAME "MATZ"
#define RITE_COMPILER_VERSION "0000"
#define RITE_VM_VER "0002"
#define RITE_VM_VER "0300"
#define RITE_BINARY_EOF "END\0"
#define RITE_SECTION_IREP_IDENT "IREP"
......@@ -65,7 +71,8 @@ MRB_API mrb_irep *mrb_read_irep_buf(mrb_state*, const void*, size_t);
/* binary header */
struct rite_binary_header {
uint8_t binary_ident[4]; /* Binary Identifier */
uint8_t binary_version[4]; /* Binary Format Version */
uint8_t major_version[2]; /* Binary Format Major Version */
uint8_t minor_version[2]; /* Binary Format Minor Version */
uint8_t binary_crc[2]; /* Binary CRC */
uint8_t binary_size[4]; /* Binary Size */
uint8_t compiler_name[4]; /* Compiler name */
......@@ -126,16 +133,6 @@ uint32_to_bin(uint32_t l, uint8_t *bin)
return sizeof(uint32_t);
}
static inline size_t
uint32l_to_bin(uint32_t l, uint8_t *bin)
{
bin[3] = (l >> 24) & 0xff;
bin[2] = (l >> 16) & 0xff;
bin[1] = (l >> 8) & 0xff;
bin[0] = l & 0xff;
return sizeof(uint32_t);
}
static inline uint32_t
bin_to_uint32(const uint8_t *bin)
{
......@@ -145,15 +142,6 @@ bin_to_uint32(const uint8_t *bin)
(uint32_t)bin[3];
}
static inline uint32_t
bin_to_uint32l(const uint8_t *bin)
{
return (uint32_t)bin[3] << 24 |
(uint32_t)bin[2] << 16 |
(uint32_t)bin[1] << 8 |
(uint32_t)bin[0];
}
static inline uint16_t
bin_to_uint16(const uint8_t *bin)
{
......
/**
** @file mruby/endian.h - detect endian-ness
**
** See Copyright Notice in mruby.h
*/
#ifndef MRUBY_ENDIAN_H
#define MRUBY_ENDIAN_H
#include <limits.h>
MRB_BEGIN_DECL
#if !defined(BYTE_ORDER) && defined(__BYTE_ORDER__)
# define BYTE_ORDER __BYTE_ORDER__
#endif
#if !defined(BIG_ENDIAN) && defined(__ORDER_BIG_ENDIAN__)
# define BIG_ENDIAN __ORDER_BIG_ENDIAN__
#endif
#if !defined(LITTLE_ENDIAN) && defined(__ORDER_LITTLE_ENDIAN__)
# define LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__
#endif
#ifdef BYTE_ORDER
# if BYTE_ORDER == BIG_ENDIAN
# define littleendian 0
# elif BYTE_ORDER == LITTLE_ENDIAN
# define littleendian 1
# endif
#endif
#ifndef littleendian
/* can't distinguish endian in compile time */
static inline int
check_little_endian(void)
{
unsigned int n = 1;
return (*(unsigned char *)&n == 1);
}
# define littleendian check_little_endian()
#endif
MRB_END_DECL
#endif /* MRUBY_ENDIAN_H */
......@@ -23,7 +23,8 @@ struct RException {
MRB_API void mrb_sys_fail(mrb_state *mrb, const char *mesg);
MRB_API mrb_value mrb_exc_new_str(mrb_state *mrb, struct RClass* c, mrb_value str);
#define mrb_exc_new_str_lit(mrb, c, lit) mrb_exc_new_str(mrb, c, mrb_str_new_lit(mrb, lit))
#define mrb_exc_new_lit(mrb, c, lit) mrb_exc_new_str(mrb, c, mrb_str_new_lit(mrb, lit))
#define mrb_exc_new_str_lit(mrb, c, lit) mrb_exc_new_str_lit(mrb, c, lit)
MRB_API mrb_value mrb_make_exception(mrb_state *mrb, mrb_int argc, const mrb_value *argv);
MRB_API mrb_value mrb_exc_backtrace(mrb_state *mrb, mrb_value exc);
MRB_API mrb_value mrb_get_backtrace(mrb_state *mrb);
......@@ -32,10 +33,10 @@ MRB_API mrb_noreturn void mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_va
/* declaration for `fail` method */
MRB_API mrb_value mrb_f_raise(mrb_state*, mrb_value);
#if defined(MRB_64BIT) || defined(MRB_USE_FLOAT) || defined(MRB_NAN_BOXING) || defined(MRB_WORD_BOXING)
#if defined(MRB_64BIT) || defined(MRB_USE_FLOAT32) || defined(MRB_NAN_BOXING) || defined(MRB_WORD_BOXING)
struct RBreak {
MRB_OBJECT_HEADER;
struct RProc *proc;
const struct RProc *proc;
mrb_value val;
};
#define mrb_break_value_get(brk) ((brk)->val)
......@@ -43,7 +44,7 @@ struct RBreak {
#else
struct RBreak {
MRB_OBJECT_HEADER;
struct RProc *proc;
const struct RProc *proc;
union mrb_value_union value;
};
#define RBREAK_VALUE_TT_MASK ((1 << 8) - 1)
......@@ -62,10 +63,43 @@ mrb_break_value_set(struct RBreak *brk, mrb_value val)
brk->flags &= ~RBREAK_VALUE_TT_MASK;
brk->flags |= val.tt;
}
#endif /* MRB_64BIT || MRB_USE_FLOAT || MRB_NAN_BOXING || MRB_WORD_BOXING */
#endif /* MRB_64BIT || MRB_USE_FLOAT32 || MRB_NAN_BOXING || MRB_WORD_BOXING */
#define mrb_break_proc_get(brk) ((brk)->proc)
#define mrb_break_proc_set(brk, p) ((brk)->proc = p)
#define RBREAK_TAG_FOREACH(f) \
f(RBREAK_TAG_BREAK, 0) \
f(RBREAK_TAG_BREAK_UPPER, 1) \
f(RBREAK_TAG_BREAK_INTARGET, 2) \
f(RBREAK_TAG_RETURN_BLOCK, 3) \
f(RBREAK_TAG_RETURN, 4) \
f(RBREAK_TAG_RETURN_TOPLEVEL, 5) \
f(RBREAK_TAG_JUMP, 6) \
f(RBREAK_TAG_STOP, 7)
#define RBREAK_TAG_DEFINE(tag, i) tag = i,
enum {
RBREAK_TAG_FOREACH(RBREAK_TAG_DEFINE)
};
#undef RBREAK_TAG_DEFINE
#define RBREAK_TAG_BIT 3
#define RBREAK_TAG_BIT_OFF 8
#define RBREAK_TAG_MASK (~(~UINT32_C(0) << RBREAK_TAG_BIT))
static inline uint32_t
mrb_break_tag_get(struct RBreak *brk)
{
return (brk->flags >> RBREAK_TAG_BIT_OFF) & RBREAK_TAG_MASK;
}
static inline void
mrb_break_tag_set(struct RBreak *brk, uint32_t tag)
{
brk->flags &= ~(RBREAK_TAG_MASK << RBREAK_TAG_BIT_OFF);
brk->flags |= (tag & RBREAK_TAG_MASK) << RBREAK_TAG_BIT_OFF;
}
/**
* Protect
*
......
......@@ -201,7 +201,7 @@ MRB_API void mrb_hash_merge(mrb_state *mrb, mrb_value hash1, mrb_value hash2);
/* RHASH_TBL allocates st_table if not available. */
#define RHASH(obj) ((struct RHash*)(mrb_ptr(obj)))
#define RHASH_TBL(h) (RHASH(h)->ht)
#define RHASH_IFNONE(h) mrb_iv_get(mrb, (h), mrb_intern_lit(mrb, "ifnone"))
#define RHASH_IFNONE(h) mrb_iv_get(mrb, (h), MRB_SYM(ifnone))
#define RHASH_PROCDEFAULT(h) RHASH_IFNONE(h)
#define MRB_HASH_DEFAULT 1
......
......@@ -16,28 +16,58 @@
MRB_BEGIN_DECL
enum irep_pool_type {
IREP_TT_STRING,
IREP_TT_FIXNUM,
IREP_TT_FLOAT,
IREP_TT_STR = 0, /* string (need free) */
IREP_TT_SSTR = 2, /* string (static) */
IREP_TT_INT32 = 1, /* 32bit integer */
IREP_TT_INT64 = 3, /* 64bit integer */
IREP_TT_FLOAT = 5, /* float (double/float) */
};
struct mrb_locals {
mrb_sym name;
uint16_t r;
#define IREP_TT_NFLAG 1 /* number (non string) flag */
#define IREP_TT_SFLAG 2 /* static string flag */
typedef struct mrb_pool_value {
uint32_t tt; /* packed type and length (for string) */
union {
const char *str;
int32_t i32;
#ifdef MRB_64BIT
int64_t i64;
#endif
mrb_float f;
} u;
} mrb_pool_value;
enum mrb_catch_type {
MRB_CATCH_RESCUE = 0,
MRB_CATCH_ENSURE = 1,
};
struct mrb_irep_catch_handler {
uint8_t type; /* enum mrb_catch_type */
uint8_t begin[2]; /* The starting address to match the hander. Includes this. */
uint8_t end[2]; /* The endpoint address that matches the hander. Not Includes this. */
uint8_t target[2]; /* The address to jump to if a match is made. */
};
/* Program data array struct */
typedef struct mrb_irep {
uint16_t nlocals; /* Number of local variables */
uint16_t nregs; /* Number of register variables */
uint16_t clen; /* Number of catch handlers */
uint8_t flags;
const mrb_code *iseq;
mrb_value *pool;
mrb_sym *syms;
struct mrb_irep **reps;
struct mrb_locals *lv;
/*
* A catch handler table is placed after the iseq entity.
* The reason it doesn't add fields to the structure is to keep the mrb_irep structure from bloating.
* The catch handler table can be obtained with `mrb_irep_catch_handler_table(irep)`.
*/
const mrb_pool_value *pool;
const mrb_sym *syms;
const struct mrb_irep * const *reps;
const mrb_sym *lv;
/* debug info */
struct mrb_irep_debug_info* debug_info;
......@@ -46,6 +76,8 @@ typedef struct mrb_irep {
} mrb_irep;
#define MRB_ISEQ_NO_FREE 1
#define MRB_IREP_NO_FREE 2
#define MRB_IREP_STATIC (MRB_ISEQ_NO_FREE | MRB_IREP_NO_FREE)
MRB_API mrb_irep *mrb_add_irep(mrb_state *mrb);
......@@ -92,6 +124,17 @@ struct mrb_insn_data {
struct mrb_insn_data mrb_decode_insn(const mrb_code *pc);
static inline const struct mrb_irep_catch_handler *
mrb_irep_catch_handler_table(const struct mrb_irep *irep)
{
if (irep->clen > 0) {
return (const struct mrb_irep_catch_handler*)(irep->iseq + irep->ilen);
}
else {
return (const struct mrb_irep_catch_handler*)NULL;
}
}
MRB_END_DECL
#endif /* MRUBY_IREP_H */
/**
** @file mruby/numeric.h - Numeric, Integer, Float, Fixnum class
** @file mruby/numeric.h - Numeric, Integer, Float class
**
** See Copyright Notice in mruby.h
*/
......@@ -12,17 +12,17 @@
/**
* Numeric class and it's sub-classes.
*
* Integer, Float and Fixnum
* Integer and Float
*/
MRB_BEGIN_DECL
#define TYPED_POSFIXABLE(f,t) ((f) <= (t)MRB_INT_MAX)
#define TYPED_NEGFIXABLE(f,t) ((f) >= (t)MRB_INT_MIN)
#define TYPED_POSFIXABLE(f,t) ((f) <= (t)MRB_FIXNUM_MAX)
#define TYPED_NEGFIXABLE(f,t) ((f) >= (t)MRB_FIXNUM_MIN)
#define TYPED_FIXABLE(f,t) (TYPED_POSFIXABLE(f,t) && TYPED_NEGFIXABLE(f,t))
#define POSFIXABLE(f) TYPED_POSFIXABLE(f,mrb_int)
#define NEGFIXABLE(f) TYPED_NEGFIXABLE(f,mrb_int)
#define FIXABLE(f) TYPED_FIXABLE(f,mrb_int)
#ifndef MRB_WITHOUT_FLOAT
#ifndef MRB_NO_FLOAT
#ifdef MRB_INT64
#define FIXABLE_FLOAT(f) ((f)>=-9223372036854775808.0 && (f)<9223372036854775808.0)
#else
......@@ -30,16 +30,15 @@ MRB_BEGIN_DECL
#endif
#endif
#ifndef MRB_WITHOUT_FLOAT
#ifndef MRB_NO_FLOAT
MRB_API mrb_value mrb_flo_to_fixnum(mrb_state *mrb, mrb_value val);
#endif
MRB_API mrb_value mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, mrb_int base);
/* ArgumentError if format string doesn't match /%(\.[0-9]+)?[aAeEfFgG]/ */
#ifndef MRB_WITHOUT_FLOAT
#ifndef MRB_NO_FLOAT
MRB_API mrb_value mrb_float_to_str(mrb_state *mrb, mrb_value x, const char *fmt);
MRB_API int mrb_float_to_cstr(mrb_state *mrb, char *buf, size_t len, const char *fmt, mrb_float f);
MRB_API mrb_float mrb_to_flo(mrb_state *mrb, mrb_value x);
MRB_API mrb_value mrb_int_value(mrb_state *mrb, mrb_float f);
#endif
MRB_API mrb_value mrb_num_plus(mrb_state *mrb, mrb_value x, mrb_value y);
......@@ -137,15 +136,15 @@ mrb_int_mul_overflow(mrb_int multiplier, mrb_int multiplicand, mrb_int *product)
if (multiplicand > 0) {
if (multiplier > MRB_INT_MAX / multiplicand) return TRUE;
}
else {
else if (multiplicand < 0) {
if (multiplicand < MRB_INT_MAX / multiplier) return TRUE;
}
}
else {
else if (multiplier < 0) {
if (multiplicand > 0) {
if (multiplier < MRB_INT_MAX / multiplicand) return TRUE;
}
else {
else if (multiplicand < 0) {
if (multiplier != 0 && multiplicand < MRB_INT_MAX / multiplier) return TRUE;
}
}
......@@ -161,13 +160,13 @@ mrb_int_mul_overflow(mrb_int multiplier, mrb_int multiplicand, mrb_int *product)
#endif
#ifndef MRB_WITHOUT_FLOAT
#ifndef MRB_NO_FLOAT
# include <stdint.h>
# include <float.h>
# define MRB_FLT_RADIX FLT_RADIX
# ifdef MRB_USE_FLOAT
# ifdef MRB_USE_FLOAT32
# define MRB_FLT_MANT_DIG FLT_MANT_DIG
# define MRB_FLT_EPSILON FLT_EPSILON
# define MRB_FLT_DIG FLT_DIG
......@@ -178,7 +177,7 @@ mrb_int_mul_overflow(mrb_int multiplier, mrb_int multiplicand, mrb_int *product)
# define MRB_FLT_MAX FLT_MAX
# define MRB_FLT_MAX_10_EXP FLT_MAX_10_EXP
# else /* not MRB_USE_FLOAT */
# else /* not MRB_USE_FLOAT32 */
# define MRB_FLT_MANT_DIG DBL_MANT_DIG
# define MRB_FLT_EPSILON DBL_EPSILON
# define MRB_FLT_DIG DBL_DIG
......@@ -188,8 +187,8 @@ mrb_int_mul_overflow(mrb_int multiplier, mrb_int multiplicand, mrb_int *product)
# define MRB_FLT_MAX_EXP DBL_MAX_EXP
# define MRB_FLT_MAX DBL_MAX
# define MRB_FLT_MAX_10_EXP DBL_MAX_10_EXP
# endif /* MRB_USE_FLOAT */
#endif /* MRB_WITHOUT_FLOAT */
# endif /* MRB_USE_FLOAT32 */
#endif /* MRB_NO_FLOAT */
MRB_END_DECL
......
......@@ -39,31 +39,4 @@ enum mrb_insn {
#define FETCH_S() do {a=READ_S();} while (0)
#define FETCH_W() do {a=READ_W();} while (0)
/* with OP_EXT1 (1st 16bit) */
#define FETCH_Z_1() FETCH_Z()
#define FETCH_B_1() FETCH_S()
#define FETCH_BB_1() do {a=READ_S(); b=READ_B();} while (0)
#define FETCH_BBB_1() do {a=READ_S(); b=READ_B(); c=READ_B();} while (0)
#define FETCH_BS_1() do {a=READ_S(); b=READ_S();} while (0)
#define FETCH_S_1() FETCH_S()
#define FETCH_W_1() FETCH_W()
/* with OP_EXT2 (2nd 16bit) */
#define FETCH_Z_2() FETCH_Z()
#define FETCH_B_2() FETCH_B()
#define FETCH_BB_2() do {a=READ_B(); b=READ_S();} while (0)
#define FETCH_BBB_2() do {a=READ_B(); b=READ_S(); c=READ_B();} while (0)
#define FETCH_BS_2() FETCH_BS()
#define FETCH_S_2() FETCH_S()
#define FETCH_W_2() FETCH_W()
/* with OP_EXT3 (1st & 2nd 16bit) */
#define FETCH_Z_3() FETCH_Z()
#define FETCH_B_3() FETCH_B()
#define FETCH_BB_3() do {a=READ_S(); b=READ_S();} while (0)
#define FETCH_BBB_3() do {a=READ_S(); b=READ_S(); c=READ_B();} while (0)
#define FETCH_BS_3() do {a=READ_S(); b=READ_S();} while (0)
#define FETCH_S_3() FETCH_S()
#define FETCH_W_3() FETCH_W()
#endif /* MRUBY_OPCODE_H */
......@@ -25,6 +25,7 @@ OPCODE(LOADI_4, B) /* R(a) = mrb_int(4) */
OPCODE(LOADI_5, B) /* R(a) = mrb_int(5) */
OPCODE(LOADI_6, B) /* R(a) = mrb_int(6) */
OPCODE(LOADI_7, B) /* R(a) = mrb_int(7) */
OPCODE(LOADI16, BS) /* R(a) = mrb_int(b) */
OPCODE(LOADSYM, BB) /* R(a) = Syms(b) */
OPCODE(LOADNIL, B) /* R(a) = nil */
OPCODE(LOADSELF, B) /* R(a) = self */
......@@ -48,13 +49,10 @@ OPCODE(JMP, S) /* pc=a */
OPCODE(JMPIF, BS) /* if R(a) pc=b */
OPCODE(JMPNOT, BS) /* if !R(a) pc=b */
OPCODE(JMPNIL, BS) /* if R(a)==nil pc=b */
OPCODE(ONERR, S) /* rescue_push(a) */
OPCODE(JMPUW, S) /* unwind_and_jump_to(a) */
OPCODE(EXCEPT, B) /* R(a) = exc */
OPCODE(RESCUE, BB) /* R(b) = R(a).isa?(R(b)) */
OPCODE(POPERR, B) /* a.times{rescue_pop()} */
OPCODE(RAISE, B) /* raise(R(a)) */
OPCODE(EPUSH, B) /* ensure_push(SEQ[a]) */
OPCODE(EPOP, B) /* A.times{ensure_pop().call} */
OPCODE(RAISEIF, B) /* raise(R(a)) if R(a) */
OPCODE(SENDV, BB) /* R(a) = call(R(a),Syms(b),*R(a+1)) */
OPCODE(SENDVB, BB) /* R(a) = call(R(a),Syms(b),*R(a+1),&R(a+2)) */
OPCODE(SEND, BBB) /* R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c)) */
......@@ -111,8 +109,4 @@ OPCODE(SCLASS, B) /* R(a) = R(a).singleton_class */
OPCODE(TCLASS, B) /* R(a) = target_class */
OPCODE(DEBUG, BBB) /* print a,b,c */
OPCODE(ERR, B) /* raise(LocalJumpError, Lit(a)) */
OPCODE(EXT1, Z) /* make 1st operand 16bit */
OPCODE(EXT2, Z) /* make 2nd operand 16bit */
OPCODE(EXT3, Z) /* make 1st and 2nd operands 16bit */
OPCODE(STOP, Z) /* stop VM */
OPCODE(LOADI16, BS) /* R(a) = mrb_int(b) */
/**
** @file mruby/presym.h - Preallocated Symbols
**
** See Copyright Notice in mruby.h
*/
#ifndef MRUBY_PRESYM_H
#define MRUBY_PRESYM_H
#undef MRB_PRESYM_MAX
#define MRB_PRESYM_CSYM(sym, num) MRB_PRESYM__##sym = (num<<1),
#define MRB_PRESYM_QSYM(str, sym, num) MRB_PRESYM_q_##sym = (num<<1),
#define MRB_PRESYM_SYM(sym, num)
enum mruby_presym {
#include <../build/presym.inc>
};
#undef MRB_PRESYM_CSYM
#undef MRB_PRESYM_QSYM
#undef MRB_PRESYM_SYM
#define MRB_SYM(sym) MRB_PRESYM__##sym
#define MRB_QSYM(sym) MRB_PRESYM_q_##sym
#endif /* MRUBY_PRESYM_H */
......@@ -41,10 +41,10 @@ void mrb_env_unshare(mrb_state*, struct REnv*);
struct RProc {
MRB_OBJECT_HEADER;
union {
mrb_irep *irep;
const mrb_irep *irep;
mrb_func_t func;
} body;
struct RProc *upper;
const struct RProc *upper;
union {
struct RClass *target_class;
struct REnv *env;
......@@ -57,7 +57,7 @@ struct RProc {
#define MRB_ASPEC_REST(a) (((a) >> 12) & 0x1)
#define MRB_ASPEC_POST(a) (((a) >> 7) & 0x1f)
#define MRB_ASPEC_KEY(a) (((a) >> 2) & 0x1f)
#define MRB_ASPEC_KDICT(a) ((a) & (1<<1))
#define MRB_ASPEC_KDICT(a) (((a) >> 1) & 0x1)
#define MRB_ASPEC_BLOCK(a) ((a) & 1)
#define MRB_PROC_CFUNC_FL 128
......@@ -86,16 +86,13 @@ struct RProc {
#define mrb_proc_ptr(v) ((struct RProc*)(mrb_ptr(v)))
struct RProc *mrb_proc_new(mrb_state*, mrb_irep*);
struct RProc *mrb_closure_new(mrb_state*, mrb_irep*);
struct RProc *mrb_proc_new(mrb_state*, const mrb_irep*);
struct RProc *mrb_closure_new(mrb_state*, const mrb_irep*);
MRB_API struct RProc *mrb_proc_new_cfunc(mrb_state*, mrb_func_t);
MRB_API struct RProc *mrb_closure_new_cfunc(mrb_state *mrb, mrb_func_t func, int nlocals);
void mrb_proc_copy(struct RProc *a, struct RProc *b);
mrb_int mrb_proc_arity(const struct RProc *p);
/* implementation of #send method */
mrb_value mrb_f_send(mrb_state *mrb, mrb_value self);
/* following functions are defined in mruby-proc-ext so please include it when using */
MRB_API struct RProc *mrb_proc_new_cfunc_with_env(mrb_state *mrb, mrb_func_t func, mrb_int argc, const mrb_value *argv);
MRB_API mrb_value mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx);
......@@ -104,7 +101,8 @@ MRB_API mrb_value mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx);
#define MRB_METHOD_FUNC_FL 1
#define MRB_METHOD_NOARG_FL 2
#ifndef MRB_METHOD_T_STRUCT
#ifndef MRB_USE_METHOD_T_STRUCT
#define MRB_METHOD_FUNC_P(m) (((uintptr_t)(m))&MRB_METHOD_FUNC_FL)
#define MRB_METHOD_NOARG_P(m) (((uintptr_t)(m))&MRB_METHOD_NOARG_FL)
......@@ -128,7 +126,7 @@ MRB_API mrb_value mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx);
#define MRB_METHOD_PROC(m) ((m).proc)
#define MRB_METHOD_UNDEF_P(m) ((m).proc==NULL)
#endif /* MRB_METHOD_T_STRUCT */
#endif /* MRB_USE_METHOD_T_STRUCT */
#define MRB_METHOD_CFUNC_P(m) (MRB_METHOD_FUNC_P(m)?TRUE:(MRB_METHOD_PROC(m)?(MRB_PROC_CFUNC_P(MRB_METHOD_PROC(m))):FALSE))
#define MRB_METHOD_CFUNC(m) (MRB_METHOD_FUNC_P(m)?MRB_METHOD_FUNC(m):((MRB_METHOD_PROC(m)&&MRB_PROC_CFUNC_P(MRB_METHOD_PROC(m)))?MRB_PROC_CFUNC(MRB_METHOD_PROC(m)):NULL))
......@@ -137,6 +135,8 @@ MRB_API mrb_value mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx);
#include <mruby/khash.h>
KHASH_DECLARE(mt, mrb_sym, mrb_method_t, TRUE)
MRB_API mrb_value mrb_load_proc(mrb_state *mrb, const struct RProc *proc);
MRB_END_DECL
#endif /* MRUBY_PROC_H */
......@@ -35,7 +35,7 @@ struct RString {
};
struct RStringEmbed {
MRB_OBJECT_HEADER;
char ary[];
char ary[RSTRING_EMBED_LEN_MAX+1];
};
#define RSTR_SET_TYPE_FLAG(s, type) (RSTR_UNSET_TYPE_FLAG(s), (s)->flags |= MRB_STR_##type)
......@@ -92,9 +92,6 @@ struct RStringEmbed {
# define RSTR_COPY_ASCII_FLAG(dst, src) (void)0
#endif
#define RSTR_POOL_P(s) ((s)->flags & MRB_STR_POOL)
#define RSTR_SET_POOL_FLAG(s) ((s)->flags |= MRB_STR_POOL)
/**
* Returns a pointer from a Ruby string
*/
......@@ -112,13 +109,11 @@ MRB_API mrb_int mrb_str_strlen(mrb_state*, struct RString*);
#define MRB_STR_FSHARED 2
#define MRB_STR_NOFREE 4
#define MRB_STR_EMBED 8 /* type flags up to here */
#define MRB_STR_POOL 16 /* status flags from here */
#define MRB_STR_ASCII 32
#define MRB_STR_ASCII 16
#define MRB_STR_EMBED_LEN_SHIFT 6
#define MRB_STR_EMBED_LEN_BIT 5
#define MRB_STR_EMBED_LEN_MASK (((1 << MRB_STR_EMBED_LEN_BIT) - 1) << MRB_STR_EMBED_LEN_SHIFT)
#define MRB_STR_TYPE_MASK (MRB_STR_POOL - 1)
#define MRB_STR_TYPE_MASK 15
void mrb_gc_free_str(mrb_state*, struct RString*);
......@@ -382,8 +377,9 @@ MRB_API double mrb_cstr_to_dbl(mrb_state *mrb, const char *s, mrb_bool badcheck)
/**
* Returns a converted string type.
* For type checking, non converting `mrb_to_str` is recommended.
* obsolete: use `mrb_obj_as_string()` instead.
*/
MRB_API mrb_value mrb_str_to_str(mrb_state *mrb, mrb_value str);
#define mrb_str_to_str(mrb, str) mrb_obj_as_string(mrb, str)
/**
* Returns true if the strings match and false if the strings don't match.
......@@ -447,7 +443,6 @@ MRB_API int mrb_str_cmp(mrb_state *mrb, mrb_value str1, mrb_value str2);
*/
MRB_API char *mrb_str_to_cstr(mrb_state *mrb, mrb_value str);
mrb_value mrb_str_pool(mrb_state *mrb, const char *s, mrb_int len, mrb_bool nofree);
uint32_t mrb_str_hash(mrb_state *mrb, mrb_value str);
mrb_value mrb_str_dump(mrb_state *mrb, mrb_value str);
......
......@@ -13,7 +13,9 @@
# endif
#endif
#if defined(MRB_ENABLE_CXX_EXCEPTION) && defined(__cplusplus)
#if defined(MRB_ENABLE_CXX_EXCEPTION)
# if defined(__cplusplus)
#define MRB_TRY(buf) try {
#define MRB_CATCH(buf) } catch(mrb_jmpbuf_impl e) { if (e != (buf)->impl) { throw e; }
......@@ -22,6 +24,10 @@
#define MRB_THROW(buf) throw((buf)->impl)
typedef mrb_int mrb_jmpbuf_impl;
# else
# error "need to be compiled with C++ compiler"
# endif /* __cplusplus */
#else
#include <setjmp.h>
......@@ -46,9 +52,11 @@ typedef mrb_int mrb_jmpbuf_impl;
struct mrb_jmpbuf {
mrb_jmpbuf_impl impl;
#if defined(MRB_ENABLE_CXX_EXCEPTION) && defined(__cplusplus)
#if defined(MRB_ENABLE_CXX_EXCEPTION)
static mrb_int jmpbuf_id;
# if defined(__cplusplus)
mrb_jmpbuf() : impl(jmpbuf_id++) {}
# endif
#endif
};
......
......@@ -54,16 +54,20 @@ struct mrb_state;
#if defined(MRB_INT64)
typedef int64_t mrb_int;
# define MRB_INT_BIT 64
# define MRB_INT_MIN (INT64_MIN>>MRB_FIXNUM_SHIFT)
# define MRB_INT_MAX (INT64_MAX>>MRB_FIXNUM_SHIFT)
# define MRB_INT_MIN INT64_MIN
# define MRB_INT_MAX INT64_MAX
# define MRB_FIXNUM_MIN (INT64_MIN>>MRB_FIXNUM_SHIFT)
# define MRB_FIXNUM_MAX (INT64_MAX>>MRB_FIXNUM_SHIFT)
# define MRB_PRIo PRIo64
# define MRB_PRId PRId64
# define MRB_PRIx PRIx64
#else
typedef int32_t mrb_int;
# define MRB_INT_BIT 32
# define MRB_INT_MIN (INT32_MIN>>MRB_FIXNUM_SHIFT)
# define MRB_INT_MAX (INT32_MAX>>MRB_FIXNUM_SHIFT)
# define MRB_INT_MIN INT32_MIN
# define MRB_INT_MAX INT32_MAX
# define MRB_FIXNUM_MIN (INT32_MIN>>MRB_FIXNUM_SHIFT)
# define MRB_FIXNUM_MAX (INT32_MAX>>MRB_FIXNUM_SHIFT)
# define MRB_PRIo PRIo32
# define MRB_PRId PRId32
# define MRB_PRIx PRIx32
......@@ -75,9 +79,9 @@ struct mrb_state;
# define MRB_ENDIAN_LOHI(a,b) b a
#endif
#ifndef MRB_WITHOUT_FLOAT
#ifndef MRB_NO_FLOAT
MRB_API double mrb_float_read(const char*, char**);
#ifdef MRB_USE_FLOAT
#ifdef MRB_USE_FLOAT32
typedef float mrb_float;
#else
typedef double mrb_float;
......@@ -90,7 +94,7 @@ MRB_API int mrb_msvc_vsnprintf(char *s, size_t n, const char *format, va_list ar
MRB_API int mrb_msvc_snprintf(char *s, size_t n, const char *format, ...);
# define vsnprintf(s, n, format, arg) mrb_msvc_vsnprintf(s, n, format, arg)
# define snprintf(s, n, format, ...) mrb_msvc_snprintf(s, n, format, __VA_ARGS__)
# if _MSC_VER < 1800 && !defined MRB_WITHOUT_FLOAT
# if _MSC_VER < 1800 && !defined MRB_NO_FLOAT
# include <float.h>
# define isfinite(n) _finite(n)
# define isnan _isnan
......@@ -106,7 +110,7 @@ enum mrb_vtype {
MRB_TT_FALSE = 0,
MRB_TT_TRUE,
MRB_TT_FLOAT,
MRB_TT_FIXNUM,
MRB_TT_INTEGER,
MRB_TT_SYMBOL,
MRB_TT_UNDEF,
MRB_TT_CPTR,
......@@ -130,6 +134,9 @@ enum mrb_vtype {
MRB_TT_MAXDEFINE
};
/* for compatibility */
#define MRB_TT_FIXNUM MRB_TT_INTEGER
#include <mruby/object.h>
#ifdef MRB_DOCUMENTATION_BLOCK
......@@ -177,8 +184,11 @@ struct RCptr {
#ifndef mrb_immediate_p
#define mrb_immediate_p(o) (mrb_type(o) < MRB_TT_FREE)
#endif
#ifndef mrb_integer_p
#define mrb_integer_p(o) (mrb_type(o) == MRB_TT_INTEGER)
#endif
#ifndef mrb_fixnum_p
#define mrb_fixnum_p(o) (mrb_type(o) == MRB_TT_FIXNUM)
#define mrb_fixnum_p(o) mrb_integer_p(o)
#endif
#ifndef mrb_symbol_p
#define mrb_symbol_p(o) (mrb_type(o) == MRB_TT_SYMBOL)
......@@ -195,7 +205,7 @@ struct RCptr {
#ifndef mrb_true_p
#define mrb_true_p(o) (mrb_type(o) == MRB_TT_TRUE)
#endif
#ifndef MRB_WITHOUT_FLOAT
#ifndef MRB_NO_FLOAT
#ifndef mrb_float_p
#define mrb_float_p(o) (mrb_type(o) == MRB_TT_FLOAT)
#endif
......@@ -264,7 +274,7 @@ struct RCptr {
*
* Takes a float and boxes it into an mrb_value
*/
#ifndef MRB_WITHOUT_FLOAT
#ifndef MRB_NO_FLOAT
MRB_INLINE mrb_value mrb_float_value(struct mrb_state *mrb, mrb_float f)
{
mrb_value v;
......@@ -284,14 +294,19 @@ mrb_cptr_value(struct mrb_state *mrb, void *p)
}
/**
* Returns a fixnum in Ruby.
*
* Takes an integer and boxes it into an mrb_value
* Returns an integer in Ruby.
*/
MRB_INLINE mrb_value mrb_int_value(struct mrb_state *mrb, mrb_int i)
{
mrb_value v;
SET_INT_VALUE(mrb, v, i);
return v;
}
MRB_INLINE mrb_value mrb_fixnum_value(mrb_int i)
{
mrb_value v;
SET_INT_VALUE(v, i);
SET_FIXNUM_VALUE(v, i);
return v;
}
......
......@@ -81,7 +81,8 @@ module MRuby
@mrbc = Command::Mrbc.new(self)
@bins = []
@gems, @libmruby_objs = MRuby::Gem::List.new, []
@gems = MRuby::Gem::List.new
@libmruby_objs = []
@build_mrbtest_lib_only = false
@cxx_exception_enabled = false
@cxx_exception_disabled = false
......@@ -95,11 +96,10 @@ module MRuby
MRuby.targets[@name] = self
end
MRuby::Build.current = MRuby.targets[@name]
MRuby.targets[@name].instance_eval(&block)
build_mrbc_exec if name == 'host'
build_mrbtest if test_enabled?
current = MRuby.targets[@name]
MRuby::Build.current = current
current.instance_eval(&block)
current.build_mrbtest if current.test_enabled?
end
def debug_enabled?
......@@ -196,6 +196,7 @@ EOS
end
def enable_bintest
raise "bintest works only on 'host' target" unless name == "host"
@enable_bintest = true
end
......@@ -246,9 +247,11 @@ EOS
def mrbcfile
return @mrbcfile if @mrbcfile
mrbc_build = MRuby.targets['host']
gems.each { |v| mrbc_build = self if v.name == 'mruby-bin-mrbc' }
@mrbcfile = mrbc_build.exefile("#{mrbc_build.build_dir}/bin/mrbc")
unless gems.detect {|v| v.name == 'mruby-bin-mrbc' }
build_mrbc_exec
gems.detect {|v| v.name == 'mruby-bin-mrbc' }.setup
end
@mrbcfile = self.exefile("#{self.build_dir}/bin/mrbc")
end
def compilers
......@@ -369,13 +372,25 @@ EOS
attr_accessor :host_target, :build_target
def initialize(name, build_dir=nil, &block)
unless MRuby.targets['host']
# add minimal 'host'
MRuby::Build.new('host') do |conf|
if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR']
toolchain :visualcpp
else
toolchain :gcc
end
conf.gem :core => 'mruby-bin-mrbc'
end
end
@endian = nil
@test_runner = Command::CrossTestRunner.new(self)
super
end
def mrbcfile
MRuby.targets['host'].exefile("#{MRuby.targets['host'].build_dir}/bin/mrbc")
host = MRuby.targets['host']
host.exefile("#{host.build_dir}/bin/mrbc")
end
def run_test
......
......@@ -313,13 +313,13 @@ module MRuby
@compile_options = "-B%{funcname} -o-"
end
def run(out, infiles, funcname)
def run(out, infiles, funcname, cdump = true)
@command ||= @build.mrbcfile
infiles = [infiles].flatten
infiles.each do |f|
_pp "MRBC", f.relative_path, nil, :indent => 2
end
cmd = %Q["#{filename @command}" #{@compile_options % {:funcname => funcname}} #{filename(infiles).map{|f| %Q["#{f}"]}.join(' ')}]
cmd = %Q["#{filename @command}" #{cdump ? "-S" : ""} #{@compile_options % {:funcname => funcname}} #{filename(infiles).map{|f| %Q["#{f}"]}.join(' ')}]
puts cmd if Rake.verbose
IO.popen(cmd, 'r+') do |io|
out.puts io.read
......
......@@ -28,18 +28,19 @@ module MRuby
Gem.current = nil
load gemrake
return nil unless Gem.current
current = Gem.current
Gem.current.dir = gemdir
Gem.current.build = self.is_a?(MRuby::Build) ? self : MRuby::Build.current
Gem.current.build_config_initializer = block
gems << Gem.current
current.dir = gemdir
current.build = self.is_a?(MRuby::Build) ? self : MRuby::Build.current
current.build_config_initializer = block
gems << current
cxx_srcs = ['src', 'test', 'tools'].map do |subdir|
Dir.glob("#{Gem.current.dir}/#{subdir}/*.{cpp,cxx,cc}")
Dir.glob("#{current.dir}/#{subdir}/*.{cpp,cxx,cc}")
end.flatten
enable_cxx_exception unless cxx_srcs.empty?
Gem.current
current
end
def load_special_path_gem(params)
......
......@@ -47,12 +47,14 @@ module MRuby
@version = "0.0.0"
@mrblib_dir = "mrblib"
@objs_dir = "src"
@dependencies = []
@conflicts = []
MRuby::Gem.current = self
end
def setup
return if defined?(@linker) # return if already set up
MRuby::Gem.current = self
MRuby::Build::COMMANDS.each do |command|
instance_variable_set("@#{command}", @build.send(command).clone)
......@@ -75,7 +77,6 @@ module MRuby
@bins = []
@requirements = []
@dependencies, @conflicts = [], []
@export_include_paths = []
@export_include_paths << "#{dir}/include" if File.directory? "#{dir}/include"
......@@ -174,7 +175,7 @@ module MRuby
def generate_gem_init(fname)
open(fname, 'w') do |f|
print_gem_init_header f
build.mrbc.run f, rbfiles, "gem_mrblib_irep_#{funcname}" unless rbfiles.empty?
build.mrbc.run f, rbfiles, "gem_mrblib_#{funcname}_proc" unless rbfiles.empty?
f.puts %Q[void mrb_#{funcname}_gem_init(mrb_state *mrb);]
f.puts %Q[void mrb_#{funcname}_gem_final(mrb_state *mrb);]
f.puts %Q[]
......@@ -183,7 +184,7 @@ module MRuby
f.puts %Q[ struct REnv *e;] unless rbfiles.empty?
f.puts %Q[ mrb_#{funcname}_gem_init(mrb);] if objs != [objfile("#{build_dir}/gem_init")]
unless rbfiles.empty?
f.puts %Q[ mrb_load_irep(mrb, gem_mrblib_irep_#{funcname});]
f.puts %Q[ mrb_load_proc(mrb, gem_mrblib_#{funcname}_proc);]
f.puts %Q[ if (mrb->exc) {]
f.puts %Q[ mrb_print_error(mrb);]
f.puts %Q[ mrb_close(mrb);]
......@@ -215,10 +216,13 @@ module MRuby
def print_gem_init_header(f)
print_gem_comment(f)
f.puts %Q[#include <stdlib.h>] unless rbfiles.empty?
f.puts %Q[#include <mruby.h>]
f.puts %Q[#include <mruby/irep.h>] unless rbfiles.empty?
f.puts %Q[#include <mruby/proc.h>] unless rbfiles.empty?
unless rbfiles.empty?
f.puts %Q[#include <stdlib.h>]
f.puts %Q[#include <mruby.h>]
f.puts %Q[#include <mruby/proc.h>]
else
f.puts %Q[#include <mruby.h>]
end
end
def print_gem_test_header(f)
......@@ -226,7 +230,7 @@ module MRuby
f.puts %Q[#include <stdio.h>]
f.puts %Q[#include <stdlib.h>]
f.puts %Q[#include <mruby.h>]
f.puts %Q[#include <mruby/irep.h>]
f.puts %Q[#include <mruby/proc.h>]
f.puts %Q[#include <mruby/variable.h>]
f.puts %Q[#include <mruby/hash.h>] unless test_args.empty?
end
......
......@@ -26,7 +26,7 @@ module MRuby
end
def instance
@instance ||= new("#{MRUBY_CONFIG}.lock")
@instance ||= new("#{MRUBY_ROOT}/build/#{MRUBY_TARGET}.lock")
end
end
......@@ -39,7 +39,7 @@ module MRuby
end
def write
locks = {"mruby_version" => mruby}
locks = {"mruby" => mruby}
locks["builds"] = @builds if @builds
File.write(@filename, YAML.dump(locks))
end
......
......@@ -5,6 +5,9 @@ MRuby::GemBox.new do |conf|
# Use standard IO/File class
conf.gem :core => "mruby-io"
# Use standard IO/File class
conf.gem :core => "mruby-socket"
# Use standard Array#pack, String#unpack methods
conf.gem :core => "mruby-pack"
......@@ -84,6 +87,9 @@ MRuby::GemBox.new do |conf|
# Generate mruby-strip command
conf.gem :core => "mruby-bin-strip"
# Generate mruby-config command
conf.gem :core => "mruby-bin-config"
# Use Kernel module extension
conf.gem :core => "mruby-kernel-ext"
......
......@@ -148,11 +148,11 @@ mrb_ary_slice_bang(mrb_state *mrb, mrb_value self)
else {
return mrb_nil_value();
}
case MRB_TT_FIXNUM:
val = mrb_funcall(mrb, self, "delete_at", 1, index);
case MRB_TT_INTEGER:
val = mrb_funcall_id(mrb, self, MRB_SYM(delete_at), 1, index);
return val;
default:
val = mrb_funcall(mrb, self, "delete_at", 1, index);
val = mrb_funcall_id(mrb, self, MRB_SYM(delete_at), 1, index);
return val;
}
}
......
......@@ -516,7 +516,7 @@ SRC
tc << {:cmd=>'p a+1', :exp=>'$1 = 2'}
tc << {:cmd=>'p 2-b', :exp=>'$2 = -3'}
tc << {:cmd=>'p c * 3', :exp=>'$3 = 24'}
tc << {:cmd=>'p a/b', :exp=>'$4 = 0.2'}
tc << {:cmd=>'p a/b', :exp=>'$4 = 0'}
tc << {:cmd=>'p c%b', :exp=>'$5 = 3'}
tc << {:cmd=>'p 2**10', :exp=>'$6 = 1024'}
tc << {:cmd=>'p ~3', :exp=>'$7 = -4'}
......@@ -614,13 +614,13 @@ SRC
tc << {:cmd=>'p a+=9', :exp=>'$1 = 10'}
tc << {:cmd=>'p b-=c', :exp=>'$2 = 15'}
tc << {:cmd=>'p bar*=2', :exp=>'$3 = "barbar"'}
tc << {:cmd=>'p a/=4', :exp=>'$4 = 2.5'}
tc << {:cmd=>'p a/=4', :exp=>'$4 = 2'}
tc << {:cmd=>'p c%=4', :exp=>'$5 = 2'}
tc << {:cmd=>'p b&=0b0101', :exp=>'$6 = 5'}
tc << {:cmd=>'p c|=0x10', :exp=>'$7 = 18'}
tc << {:cmd=>'p "#{a} #{b} #{c}"', :exp=>'$8 = "2.5 5 18"'}
tc << {:cmd=>'p "#{a} #{b} #{c}"', :exp=>'$8 = "2 5 18"'}
tc << {:cmd=>'p "#{foo}#{bar}#{baz}"', :exp=>'$9 = "foobarbarbaz"'}
tc << {:cmd=>'p a,b,c=[10,20,30]',:exp=>'$10 = [10, 20, 30]'}
......@@ -682,13 +682,13 @@ SRC
tc << {:cmd=>'p a+=9', :exp=>'$1 = 10'}
tc << {:cmd=>'p b-=c', :exp=>'$2 = 15'}
tc << {:cmd=>'p bar*=2', :exp=>'$3 = "barbar"'}
tc << {:cmd=>'p a/=4', :exp=>'$4 = 2.5'}
tc << {:cmd=>'p a/=4', :exp=>'$4 = 2'}
tc << {:cmd=>'p c%=4', :exp=>'$5 = 2'}
tc << {:cmd=>'p b&=0b0101', :exp=>'$6 = 5'}
tc << {:cmd=>'p c|=0x10', :exp=>'$7 = 18'}
tc << {:cmd=>'p "#{a} #{b} #{c}"', :exp=>'$8 = "2.5 5 18"'}
tc << {:cmd=>'p "#{a} #{b} #{c}"', :exp=>'$8 = "2 5 18"'}
tc << {:cmd=>'p "#{foo}#{bar}#{baz}"', :exp=>'$9 = "foobarbarbaz"'}
tc << {:cmd=>'p a,b,c=[10,20,30]',:exp=>'$10 = [10, 20, 30]'}
......
......@@ -84,7 +84,7 @@ free_breakpoint(mrb_state *mrb, mrb_debug_breakpoint *bp)
}
static uint16_t
check_file_lineno(mrb_state *mrb, struct mrb_irep *irep, const char *file, uint16_t lineno)
check_file_lineno(mrb_state *mrb, const struct mrb_irep *irep, const char *file, uint16_t lineno)
{
mrb_irep_debug_info_file *info_file;
uint16_t result = 0;
......@@ -151,7 +151,7 @@ compare_break_method(mrb_state *mrb, mrb_debug_breakpoint *bp, struct RClass *cl
}
sc = mrb_class_get(mrb, method_p->class_name);
ssym = mrb_symbol(mrb_check_intern_cstr(mrb, method_p->method_name));
ssym = mrb_intern_check_cstr(mrb, method_p->method_name);
m = mrb_method_search_vm(mrb, &sc, ssym);
if (MRB_METHOD_UNDEF_P(m)) {
return MRB_DEBUG_OK;
......@@ -428,7 +428,7 @@ mrb_debug_disable_break_all(mrb_state *mrb, mrb_debug_context *dbg)
}
static mrb_bool
check_start_pc_for_line(mrb_state *mrb, mrb_irep *irep, const mrb_code *pc, uint16_t line)
check_start_pc_for_line(mrb_state *mrb, const mrb_irep *irep, const mrb_code *pc, uint16_t line)
{
if (pc > irep->iseq) {
if (line == mrb_debug_get_line(mrb, irep, pc - irep->iseq - 1)) {
......
......@@ -33,7 +33,7 @@ mrdb_check_syntax(mrb_state *mrb, mrb_debug_context *dbg, const char *expr, size
mrb_value
mrb_debug_eval(mrb_state *mrb, mrb_debug_context *dbg, const char *expr, size_t len, mrb_bool *exc, int direct_eval)
{
void (*tmp)(struct mrb_state *, struct mrb_irep *, const mrb_code *, mrb_value *);
void (*tmp)(struct mrb_state *, const struct mrb_irep *, const mrb_code *, mrb_value *);
mrb_value ruby_code;
mrb_value s;
mrb_value v;
......@@ -67,7 +67,7 @@ mrb_debug_eval(mrb_state *mrb, mrb_debug_context *dbg, const char *expr, size_t
recv = dbg->regs[0];
v = mrb_funcall(mrb, recv, "instance_eval", 1, ruby_code);
v = mrb_funcall_id(mrb, recv, MRB_SYM(instance_eval), 1, ruby_code);
}
if (exc) {
......
......@@ -504,7 +504,7 @@ get_and_parse_command(mrb_state *mrb, mrdb_state *mrdb)
}
static int32_t
check_method_breakpoint(mrb_state *mrb, mrb_irep *irep, const mrb_code *pc, mrb_value *regs)
check_method_breakpoint(mrb_state *mrb, const mrb_irep *irep, const mrb_code *pc, mrb_value *regs)
{
struct RClass* c;
mrb_sym sym;
......@@ -545,7 +545,7 @@ check_method_breakpoint(mrb_state *mrb, mrb_irep *irep, const mrb_code *pc, mrb_
}
static void
mrb_code_fetch_hook(mrb_state *mrb, mrb_irep *irep, const mrb_code *pc, mrb_value *regs)
mrb_code_fetch_hook(mrb_state *mrb, const mrb_irep *irep, const mrb_code *pc, mrb_value *regs)
{
const char *file;
int32_t line;
......
......@@ -103,8 +103,8 @@ typedef struct mrb_debug_breakpoint {
} mrb_debug_breakpoint;
typedef struct mrb_debug_context {
struct mrb_irep *root_irep;
struct mrb_irep *irep;
const struct mrb_irep *root_irep;
const struct mrb_irep *irep;
const mrb_code *pc;
mrb_value *regs;
......
......@@ -104,13 +104,13 @@ p(mrb_state *mrb, mrb_value obj, int prompt)
mrb_value val;
char* msg;
val = mrb_funcall(mrb, obj, "inspect", 0);
val = mrb_funcall_id(mrb, obj, MRB_SYM(inspect), 0);
if (prompt) {
if (!mrb->exc) {
fputs(" => ", stdout);
}
else {
val = mrb_funcall(mrb, mrb_obj_value(mrb->exc), "inspect", 0);
val = mrb_funcall_id(mrb, mrb_obj_value(mrb->exc), MRB_SYM(inspect), 0);
}
}
if (!mrb_string_p(val)) {
......@@ -525,10 +525,7 @@ main(int argc, char **argv)
while (TRUE) {
char *utf8;
struct mrb_jmpbuf c_jmp;
MRB_TRY(&c_jmp);
mrb->jmp = &c_jmp;
if (args.rfp) {
if (fgets(last_code_line, sizeof(last_code_line)-1, args.rfp) != NULL)
goto done;
......@@ -672,7 +669,7 @@ main(int argc, char **argv)
}
else {
/* no */
if (!mrb_respond_to(mrb, result, mrb_intern_lit(mrb, "inspect"))){
if (!mrb_respond_to(mrb, result, MRB_SYM(inspect))){
result = mrb_any_to_s(mrb, result);
}
p(mrb, result, 1);
......@@ -687,11 +684,6 @@ main(int argc, char **argv)
}
mrb_parser_free(parser);
cxt->lineno++;
MRB_CATCH(&c_jmp) {
p(mrb, mrb_obj_value(mrb->exc), 0);
mrb->exc = 0;
}
MRB_END_EXC(&c_jmp);
}
#ifdef ENABLE_READLINE
......
......@@ -20,6 +20,7 @@ struct mrbc_args {
const char *prog;
const char *outfile;
const char *initname;
mrb_bool dump_struct : 1;
mrb_bool check_syntax : 1;
mrb_bool verbose : 1;
mrb_bool remove_lv : 1;
......@@ -32,10 +33,11 @@ usage(const char *name)
static const char *const usage_msg[] = {
"switches:",
"-c check syntax only",
"-o<outfile> place the output into <outfile>",
"-o<outfile> place the output into <outfile>; required for multi-files",
"-v print version number, then turn on verbose mode",
"-g produce debugging information",
"-B<symbol> binary <symbol> output in C language format",
"-S dump C struct (requires -B)",
"--remove-lv remove local variables",
"--verbose run at verbose mode",
"--version print the version",
......@@ -44,7 +46,7 @@ usage(const char *name)
};
const char *const *p = usage_msg;
printf("Usage: %s [switches] programfile\n", name);
printf("Usage: %s [switches] programfile...\n", name);
while (*p)
printf(" %s\n", *p++);
}
......@@ -105,6 +107,9 @@ parse_args(mrb_state *mrb, int argc, char **argv, struct mrbc_args *args)
args->outfile = get_outfilename(mrb, argv[i] + 2, "");
}
break;
case 'S':
args->dump_struct = TRUE;
break;
case 'B':
if (argv[i][2] == '\0' && argv[i+1]) {
i++;
......@@ -238,13 +243,18 @@ static int
dump_file(mrb_state *mrb, FILE *wfp, const char *outfile, struct RProc *proc, struct mrbc_args *args)
{
int n = MRB_DUMP_OK;
mrb_irep *irep = proc->body.irep;
const mrb_irep *irep = proc->body.irep;
if (args->remove_lv) {
mrb_irep_remove_lv(mrb, irep);
mrb_irep_remove_lv(mrb, (mrb_irep*)irep);
}
if (args->initname) {
n = mrb_dump_irep_cfunc(mrb, irep, args->flags, wfp, args->initname);
if (args->dump_struct) {
n = mrb_dump_irep_cstruct(mrb, irep, args->flags, wfp, args->initname);
}
else {
n = mrb_dump_irep_cfunc(mrb, irep, args->flags, wfp, args->initname);
}
if (n == MRB_DUMP_INVALID_ARGUMENT) {
fprintf(stderr, "%s: invalid C language symbol name\n", args->initname);
}
......
MRuby::Gem::Specification.new('mruby-catch') do |spec|
spec.license = 'MIT'
spec.author = 'mruby developers'
spec.summary = 'Catch / Throw non-local Jump'
end
class ThrowCatchJump < Exception
def initialize(tag, val)
@tag = tag
@val = val
super("uncaught throw :#{tag}")
end
def _tag
@tag
end
def _val
@val
end
end
module Kernel
def catch(tag, &block)
block.call(tag)
rescue ThrowCatchJump => e
unless e._tag == tag
raise e
end
return e._val
end
def throw(tag, val=nil)
raise ThrowCatchJump.new(tag, val)
end
end
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -104,7 +104,7 @@ class Complex < Numeric
alias_method :imag, :imaginary
[Fixnum, Float].each do |cls|
[Integer, Float].each do |cls|
[:+, :-, :*, :/, :==].each do |op|
cls.instance_eval do
original_operator_name = :"__original_operator_#{op}_complex"
......
......@@ -3,8 +3,8 @@
#include <mruby/numeric.h>
#include <math.h>
#ifdef MRB_WITHOUT_FLOAT
# error Complex conflicts 'MRB_WITHOUT_FLOAT' configuration in your 'build_config.rb'
#ifdef MRB_NO_FLOAT
# error Complex conflicts with 'MRB_NO_FLOAT' configuration
#endif
struct mrb_complex {
......@@ -12,13 +12,13 @@ struct mrb_complex {
mrb_float imaginary;
};
#ifdef MRB_USE_FLOAT
#ifdef MRB_USE_FLOAT32
#define F(x) x##f
#else
#define F(x) x
#endif
#if defined(MRB_64BIT) || defined(MRB_USE_FLOAT)
#if defined(MRB_64BIT) || defined(MRB_USE_FLOAT32)
#define COMPLEX_USE_ISTRUCT
/* use TT_ISTRUCT */
......@@ -69,7 +69,7 @@ complex_ptr(mrb_state *mrb, mrb_value v)
static mrb_value
complex_new(mrb_state *mrb, mrb_float real, mrb_float imaginary)
{
struct RClass *c = mrb_class_get(mrb, "Complex");
struct RClass *c = mrb_class_get_id(mrb, MRB_SYM(Complex));
struct mrb_complex *p;
struct RBasic *comp = complex_alloc(mrb, c, &p);
p->real = real;
......@@ -122,7 +122,7 @@ complex_to_i(mrb_state *mrb, mrb_value self)
if (p->imaginary != 0) {
mrb_raisef(mrb, E_RANGE_ERROR, "can't convert %v into Float", self);
}
return mrb_int_value(mrb, p->real);
return mrb_int_value(mrb, (mrb_int)p->real);
}
static mrb_value
......@@ -224,7 +224,7 @@ void mrb_mruby_complex_gem_init(mrb_state *mrb)
#ifdef COMPLEX_USE_ISTRUCT
mrb_assert(sizeof(struct mrb_complex) < ISTRUCT_DATA_SIZE);
#endif
comp = mrb_define_class(mrb, "Complex", mrb_class_get(mrb, "Numeric"));
comp = mrb_define_class(mrb, "Complex", mrb_class_get_id(mrb, MRB_SYM(Numeric)));
#ifdef COMPLEX_USE_ISTRUCT
MRB_SET_INSTANCE_TT(comp, MRB_TT_ISTRUCT);
#else
......
......@@ -56,11 +56,11 @@ end
assert 'Complex#/' do
assert_complex Complex(2, 3) / Complex(2, 3) , (1 + 0i)
assert_complex Complex(900) / Complex(1) , (900 + 0i)
assert_complex Complex(-2, 9) / Complex(-9, 2), ((36 / 85) - (77i / 85))
assert_complex Complex(9, 8) / 4 , ((9 / 4) + 2i)
assert_complex Complex(-2, 9) / Complex(-9, 2), ((36.0 / 85) - (77i / 85))
assert_complex Complex(9, 8) / 4 , ((9.0 / 4) + 2i)
assert_complex Complex(20, 9) / 9.8 , (2.0408163265306123 + 0.9183673469387754i)
if 1e39.infinite? then
# MRB_USE_FLOAT in effect
# MRB_USE_FLOAT32 in effect
ten = 1e21
one = 1e20
else
......@@ -80,7 +80,7 @@ assert 'Complex#abs' do
assert_float Complex(-1).abs, 1
assert_float Complex(3.0, -4.0).abs, 5.0
if 1e39.infinite? then
# MRB_USE_FLOAT in effect
# MRB_USE_FLOAT32 in effect
exp = 125
else
exp = 1021
......
......@@ -130,6 +130,7 @@ class Enumerator
@feedvalue = nil
@stop_exc = false
end
attr_accessor :obj, :meth, :args
attr_reader :fib
......
......@@ -445,7 +445,7 @@ assert 'modifying existing methods' do
}
end
assert 'Integral#times' do
assert 'Integer#times' do
a = 3
b = a.times
c = []
......
......@@ -20,7 +20,7 @@ create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value bi
struct REnv *e;
mrb_callinfo *ci; /* callinfo of eval caller */
struct RClass *target_class = NULL;
int bidx;
mrb_int bidx;
if (!mrb_nil_p(binding)) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "Binding of eval must be nil.");
......@@ -179,7 +179,7 @@ void
mrb_mruby_eval_gem_init(mrb_state* mrb)
{
mrb_define_module_function(mrb, mrb->kernel_module, "eval", f_eval, MRB_ARGS_ARG(1, 3));
mrb_define_method(mrb, mrb_class_get(mrb, "BasicObject"), "instance_eval", f_instance_eval, MRB_ARGS_OPT(3)|MRB_ARGS_BLOCK());
mrb_define_method(mrb, mrb_class_get_id(mrb, MRB_SYM(BasicObject)), "instance_eval", f_instance_eval, MRB_ARGS_OPT(3)|MRB_ARGS_BLOCK());
}
void
......
......@@ -10,10 +10,10 @@ istruct_test_initialize(mrb_state *mrb, mrb_value self)
mrb_int size = mrb_istruct_size();
mrb_value object = mrb_get_arg1(mrb);
if (mrb_fixnum_p(object)) {
if (mrb_integer_p(object)) {
strncpy(string, "fixnum", size-1);
}
#ifndef MRB_WITHOUT_FLOAT
#ifndef MRB_NO_FLOAT
else if (mrb_float_p(object)) {
strncpy(string, "float", size-1);
}
......
......@@ -2,7 +2,7 @@ class File < IO
attr_accessor :path
def initialize(fd_or_path, mode = "r", perm = 0666)
if fd_or_path.kind_of? Fixnum
if fd_or_path.kind_of? Integer
super(fd_or_path, mode)
else
@path = fd_or_path
......
......@@ -186,7 +186,7 @@ class IO
def read(length = nil, outbuf = "")
unless length.nil?
unless length.is_a? Fixnum
unless length.is_a? Integer
raise TypeError.new "can't convert #{length.class} into Integer"
end
if length < 0
......@@ -229,7 +229,7 @@ class IO
case arg
when String
rs = arg
when Fixnum
when Integer
rs = "\n"
limit = arg
else
......
......@@ -399,7 +399,7 @@ mrb_file_mtime(mrb_state *mrb, mrb_value self)
if (mrb_fstat(fd, &st) == -1)
return mrb_false_value();
return mrb_fixnum_value((mrb_int)st.st_mtime);
return mrb_int_value(mrb, (mrb_int)st.st_mtime);
}
static mrb_value
......@@ -448,8 +448,8 @@ mrb_file_size(mrb_state *mrb, mrb_value self)
}
if (st.st_size > MRB_INT_MAX) {
#ifdef MRB_WITHOUT_FLOAT
mrb_raise(mrb, E_RUNTIME_ERROR, "File#size too large for MRB_WITHOUT_FLOAT");
#ifdef MRB_NO_FLOAT
mrb_raise(mrb, E_RUNTIME_ERROR, "File#size too large for MRB_NO_FLOAT");
#else
return mrb_float_value(mrb, (mrb_float)st.st_size);
#endif
......@@ -614,36 +614,36 @@ mrb_init_file(mrb_state *mrb)
mrb_define_method(mrb, file, "size", mrb_file_size, MRB_ARGS_NONE());
mrb_define_method(mrb, file, "truncate", mrb_file_truncate, MRB_ARGS_REQ(1));
cnst = mrb_define_module_under(mrb, file, "Constants");
mrb_define_const(mrb, cnst, "LOCK_SH", mrb_fixnum_value(LOCK_SH));
mrb_define_const(mrb, cnst, "LOCK_EX", mrb_fixnum_value(LOCK_EX));
mrb_define_const(mrb, cnst, "LOCK_UN", mrb_fixnum_value(LOCK_UN));
mrb_define_const(mrb, cnst, "LOCK_NB", mrb_fixnum_value(LOCK_NB));
mrb_define_const(mrb, cnst, "SEPARATOR", mrb_str_new_cstr(mrb, FILE_SEPARATOR));
mrb_define_const(mrb, cnst, "PATH_SEPARATOR", mrb_str_new_cstr(mrb, PATH_SEPARATOR));
cnst = mrb_define_module_under_id(mrb, file, MRB_SYM(Constants));
mrb_define_const_id(mrb, cnst, MRB_SYM(LOCK_SH), mrb_fixnum_value(LOCK_SH));
mrb_define_const_id(mrb, cnst, MRB_SYM(LOCK_EX), mrb_fixnum_value(LOCK_EX));
mrb_define_const_id(mrb, cnst, MRB_SYM(LOCK_UN), mrb_fixnum_value(LOCK_UN));
mrb_define_const_id(mrb, cnst, MRB_SYM(LOCK_NB), mrb_fixnum_value(LOCK_NB));
mrb_define_const_id(mrb, cnst, MRB_SYM(SEPARATOR), mrb_str_new_cstr(mrb, FILE_SEPARATOR));
mrb_define_const_id(mrb, cnst, MRB_SYM(PATH_SEPARATOR), mrb_str_new_cstr(mrb, PATH_SEPARATOR));
#if defined(_WIN32) || defined(_WIN64)
mrb_define_const(mrb, cnst, "ALT_SEPARATOR", mrb_str_new_cstr(mrb, FILE_ALT_SEPARATOR));
mrb_define_const_id(mrb, cnst, MRB_SYM(ALT_SEPARATOR), mrb_str_new_cstr(mrb, FILE_ALT_SEPARATOR));
#else
mrb_define_const(mrb, cnst, "ALT_SEPARATOR", mrb_nil_value());
mrb_define_const_id(mrb, cnst, MRB_SYM(ALT_SEPARATOR), mrb_nil_value());
#endif
mrb_define_const(mrb, cnst, "NULL", mrb_str_new_cstr(mrb, NULL_FILE));
mrb_define_const(mrb, cnst, "RDONLY", mrb_fixnum_value(MRB_O_RDONLY));
mrb_define_const(mrb, cnst, "WRONLY", mrb_fixnum_value(MRB_O_WRONLY));
mrb_define_const(mrb, cnst, "RDWR", mrb_fixnum_value(MRB_O_RDWR));
mrb_define_const(mrb, cnst, "APPEND", mrb_fixnum_value(MRB_O_APPEND));
mrb_define_const(mrb, cnst, "CREAT", mrb_fixnum_value(MRB_O_CREAT));
mrb_define_const(mrb, cnst, "EXCL", mrb_fixnum_value(MRB_O_EXCL));
mrb_define_const(mrb, cnst, "TRUNC", mrb_fixnum_value(MRB_O_TRUNC));
mrb_define_const(mrb, cnst, "NONBLOCK", mrb_fixnum_value(MRB_O_NONBLOCK));
mrb_define_const(mrb, cnst, "NOCTTY", mrb_fixnum_value(MRB_O_NOCTTY));
mrb_define_const(mrb, cnst, "BINARY", mrb_fixnum_value(MRB_O_BINARY));
mrb_define_const(mrb, cnst, "SHARE_DELETE", mrb_fixnum_value(MRB_O_SHARE_DELETE));
mrb_define_const(mrb, cnst, "SYNC", mrb_fixnum_value(MRB_O_SYNC));
mrb_define_const(mrb, cnst, "DSYNC", mrb_fixnum_value(MRB_O_DSYNC));
mrb_define_const(mrb, cnst, "RSYNC", mrb_fixnum_value(MRB_O_RSYNC));
mrb_define_const(mrb, cnst, "NOFOLLOW", mrb_fixnum_value(MRB_O_NOFOLLOW));
mrb_define_const(mrb, cnst, "NOATIME", mrb_fixnum_value(MRB_O_NOATIME));
mrb_define_const(mrb, cnst, "DIRECT", mrb_fixnum_value(MRB_O_DIRECT));
mrb_define_const(mrb, cnst, "TMPFILE", mrb_fixnum_value(MRB_O_TMPFILE));
mrb_define_const_id(mrb, cnst, MRB_SYM(NULL), mrb_str_new_cstr(mrb, NULL_FILE));
mrb_define_const_id(mrb, cnst, MRB_SYM(RDONLY), mrb_fixnum_value(MRB_O_RDONLY));
mrb_define_const_id(mrb, cnst, MRB_SYM(WRONLY), mrb_fixnum_value(MRB_O_WRONLY));
mrb_define_const_id(mrb, cnst, MRB_SYM(RDWR), mrb_fixnum_value(MRB_O_RDWR));
mrb_define_const_id(mrb, cnst, MRB_SYM(APPEND), mrb_fixnum_value(MRB_O_APPEND));
mrb_define_const_id(mrb, cnst, MRB_SYM(CREAT), mrb_fixnum_value(MRB_O_CREAT));
mrb_define_const_id(mrb, cnst, MRB_SYM(EXCL), mrb_fixnum_value(MRB_O_EXCL));
mrb_define_const_id(mrb, cnst, MRB_SYM(TRUNC), mrb_fixnum_value(MRB_O_TRUNC));
mrb_define_const_id(mrb, cnst, MRB_SYM(NONBLOCK), mrb_fixnum_value(MRB_O_NONBLOCK));
mrb_define_const_id(mrb, cnst, MRB_SYM(NOCTTY), mrb_fixnum_value(MRB_O_NOCTTY));
mrb_define_const_id(mrb, cnst, MRB_SYM(BINARY), mrb_fixnum_value(MRB_O_BINARY));
mrb_define_const_id(mrb, cnst, MRB_SYM(SHARE_DELETE), mrb_fixnum_value(MRB_O_SHARE_DELETE));
mrb_define_const_id(mrb, cnst, MRB_SYM(SYNC), mrb_fixnum_value(MRB_O_SYNC));
mrb_define_const_id(mrb, cnst, MRB_SYM(DSYNC), mrb_fixnum_value(MRB_O_DSYNC));
mrb_define_const_id(mrb, cnst, MRB_SYM(RSYNC), mrb_fixnum_value(MRB_O_RSYNC));
mrb_define_const_id(mrb, cnst, MRB_SYM(NOFOLLOW), mrb_fixnum_value(MRB_O_NOFOLLOW));
mrb_define_const_id(mrb, cnst, MRB_SYM(NOATIME), mrb_fixnum_value(MRB_O_NOATIME));
mrb_define_const_id(mrb, cnst, MRB_SYM(DIRECT), mrb_fixnum_value(MRB_O_DIRECT));
mrb_define_const_id(mrb, cnst, MRB_SYM(TMPFILE), mrb_fixnum_value(MRB_O_TMPFILE));
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment