summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDaniel Bovensiepen <[email protected]>2013-06-15 03:53:50 +0800
committerDaniel Bovensiepen <[email protected]>2013-06-15 03:53:50 +0800
commit373122a299ebec890cfaa95ee41fde221ac6a543 (patch)
tree346e79bb8a30a4e0b4102babf7dd9407beb36979
parentad07d41bd1b42fe7d23e04361839f511c5f9cd7f (diff)
parent961cd408a86580c4d428f56153da00fd46738e35 (diff)
downloadmruby-373122a299ebec890cfaa95ee41fde221ac6a543.tar.gz
mruby-373122a299ebec890cfaa95ee41fde221ac6a543.zip
Merge upstream
-rw-r--r--AUTHORS5
-rw-r--r--README.md4
-rw-r--r--doc/compile/README.md4
-rw-r--r--doc/mrbgems/README.md7
-rw-r--r--examples/mrbgems/c_and_ruby_extension_example/mrbgem.rake2
-rw-r--r--examples/mrbgems/c_extension_example/mrbgem.rake2
-rw-r--r--examples/mrbgems/ruby_extension_example/mrbgem.rake2
-rw-r--r--examples/targets/ArduinoDue.rb30
-rw-r--r--examples/targets/chipKitMax32.rb24
-rw-r--r--include/mruby.h65
-rw-r--r--include/mruby/irep.h5
-rw-r--r--include/mruby/khash.h55
-rw-r--r--include/mruby/string.h2
-rw-r--r--include/mruby/value.h38
-rwxr-xr-xminirake5
-rw-r--r--mrbgems/default.gembox6
-rw-r--r--mrbgems/mruby-array-ext/mrbgem.rake2
-rw-r--r--mrbgems/mruby-bin-mirb/mrbgem.rake5
-rw-r--r--mrbgems/mruby-bin-mirb/tools/mirb/mirb.c35
-rw-r--r--mrbgems/mruby-bin-mruby/mrbgem.rake2
-rw-r--r--mrbgems/mruby-enum-ext/mrbgem.rake2
-rw-r--r--mrbgems/mruby-eval/mrbgem.rake2
-rw-r--r--mrbgems/mruby-fiber/mrbgem.rake2
-rw-r--r--mrbgems/mruby-hash-ext/mrbgem.rake2
-rw-r--r--mrbgems/mruby-math/mrbgem.rake2
-rw-r--r--mrbgems/mruby-math/src/math.c22
-rw-r--r--mrbgems/mruby-numeric-ext/mrbgem.rake2
-rw-r--r--mrbgems/mruby-object-ext/mrbgem.rake4
-rw-r--r--mrbgems/mruby-object-ext/src/object.c108
-rw-r--r--mrbgems/mruby-object-ext/test/nil.rb11
-rw-r--r--mrbgems/mruby-object-ext/test/object.rb9
-rw-r--r--mrbgems/mruby-objectspace/mrbgem.rake2
-rw-r--r--mrbgems/mruby-print/mrbgem.rake2
-rw-r--r--mrbgems/mruby-proc-ext/mrbgem.rake2
-rw-r--r--mrbgems/mruby-random/mrbgem.rake2
-rw-r--r--mrbgems/mruby-random/src/random.c31
-rw-r--r--mrbgems/mruby-range-ext/mrbgem.rake2
-rw-r--r--mrbgems/mruby-range-ext/src/range.c4
-rw-r--r--mrbgems/mruby-sprintf/mrbgem.rake2
-rw-r--r--mrbgems/mruby-sprintf/src/sprintf.c4
-rw-r--r--mrbgems/mruby-string-ext/mrbgem.rake2
-rw-r--r--mrbgems/mruby-struct/mrbgem.rake2
-rw-r--r--mrbgems/mruby-struct/src/struct.c5
-rw-r--r--mrbgems/mruby-symbol-ext/mrbgem.rake2
-rw-r--r--mrbgems/mruby-time/mrbgem.rake2
-rw-r--r--mrbgems/mruby-time/src/time.c2
-rw-r--r--mrbgems/mruby-toplevel-ext/mrbgem.rake4
-rw-r--r--mrbgems/mruby-toplevel-ext/mrblib/toplevel.rb11
-rw-r--r--mrbgems/mruby-toplevel-ext/test/toplevel.rb24
-rw-r--r--mrblib/class.rb24
-rw-r--r--mrblib/string.rb12
-rw-r--r--src/array.c70
-rw-r--r--src/backtrace.c4
-rw-r--r--src/class.c119
-rw-r--r--src/codegen.c32
-rw-r--r--src/crc.c2
-rw-r--r--src/dump.c9
-rw-r--r--src/error.c12
-rw-r--r--src/error.h1
-rw-r--r--src/gc.c321
-rw-r--r--src/hash.c24
-rw-r--r--src/kernel.c66
-rw-r--r--src/load.c23
-rw-r--r--src/numeric.c16
-rw-r--r--src/object.c79
-rw-r--r--src/opcode.h223
-rw-r--r--src/parse.y36
-rw-r--r--src/pool.c14
-rw-r--r--src/proc.c6
-rw-r--r--src/range.c80
-rw-r--r--src/re.h3
-rw-r--r--src/state.c8
-rw-r--r--src/string.c31
-rw-r--r--src/symbol.c8
-rw-r--r--src/variable.c47
-rw-r--r--src/vm.c26
-rw-r--r--tasks/mrbgem_spec.rake7
-rw-r--r--tasks/mrbgems.rake3
-rw-r--r--tasks/mrbgems_test.rake2
-rw-r--r--tasks/mruby_build.rake7
-rw-r--r--tasks/mruby_build_commands.rake18
-rw-r--r--tasks/mruby_build_gem.rake20
-rw-r--r--tasks/toolchains/androideabi.rake15
-rw-r--r--test/t/integer.rb19
-rw-r--r--test/t/module.rb139
-rw-r--r--test/t/nil.rb1
-rw-r--r--test/t/range.rb8
-rw-r--r--test/t/string.rb4
-rw-r--r--travis_config.rb1
89 files changed, 1343 insertions, 768 deletions
diff --git a/AUTHORS b/AUTHORS
index 17fe246de..7f00f91f1 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -11,3 +11,8 @@ Original Authors "mruby developers" are:
Masaki Muranaka
Internet Initiative Japan Inc.
Tadashi FUKUZAWA
+ MATSUMOTO Ryosuke
+ Yasuhiro Matsumoto
+ Koji Yoshioka
+ Jun Hiroe
+ Narihiro Nakamura
diff --git a/README.md b/README.md
index 28e2ffc71..9bcffacf7 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
This is a preliminary release for internal team review.
The URLs and addresses described below are not available yet.
The official release will be announced later.
- Any suggestion for modification is welcome.
+ Any suggestions for modification are welcome.
Delays in replies are to be expected. Sorry in advance.
## What's mruby
@@ -113,4 +113,4 @@ Please ask us if you want to distribute your code under another license.
See the [contribution guidelines](https://github.com/mruby/mruby/blob/master/CONTRIBUTING.md)
then send a pull request to <http://github.com/mruby/mruby>. We consider you have granted
non-exclusive right to your contributed code under MIT license. If you want to be named
-as one of mruby developers, include update to the AUTHORS file in your pull request.
+as one of mruby developers, please include an update to the AUTHORS file in your pull request.
diff --git a/doc/compile/README.md b/doc/compile/README.md
index a244d06b2..e7f382f15 100644
--- a/doc/compile/README.md
+++ b/doc/compile/README.md
@@ -33,7 +33,8 @@ customized path using the *$MRUBY_CONFIG* environment variable.
To compile just call ```./minirake``` inside of the mruby source root. To
generate and execute the test tools call ```./minirake test```. To clean
-all build files call ```./minirake clean```.
+all build files call ```./minirake clean```. To see full command line on
+build, call ```./minirake -v```.
## Build Configuration
@@ -177,6 +178,7 @@ Integrate GEMs in the build process.
conf.gem 'path/to/another/gem'
+See doc/mrbgems/README.md for more option about mrbgems.
### Mrbtest
Configuration Mrbtest build process.
diff --git a/doc/mrbgems/README.md b/doc/mrbgems/README.md
index e89fd1a56..881fbb228 100644
--- a/doc/mrbgems/README.md
+++ b/doc/mrbgems/README.md
@@ -25,6 +25,9 @@ A remote GIT repository location for a GEM is also supported:
conf.gem :bitbucket => 'mruby/mrbgems-example', :branch => 'master'
+To pull all gems from remote GIT repository on build, call ```./minirake -p```,
+or ```./minirake --pull-gems```.
+
NOTE: `:bitbucket` option supports only git. Hg is unsupported in this version.
## GemBox
@@ -96,7 +99,7 @@ GEM directory. A typical GEM specification could look like this for example:
MRuby::Gem::Specification.new('c_and_ruby_extension_example') do |spec|
spec.license = 'MIT'
- spec.authors = 'mruby developers'
+ spec.author = 'mruby developers'
end
The mrbgems build process will use this specification to compile Object and Ruby
@@ -121,7 +124,7 @@ In case your GEM is depending on other GEMs please use
MRuby::Gem::Specification.new('c_and_ruby_extension_example') do |spec|
spec.license = 'MIT'
- spec.authors = 'mruby developers'
+ spec.author = 'mruby developers'
# add GEM dependency mruby-parser.
# Version has to be between 1.0.0 and 1.5.2
diff --git a/examples/mrbgems/c_and_ruby_extension_example/mrbgem.rake b/examples/mrbgems/c_and_ruby_extension_example/mrbgem.rake
index 35dbe5e18..a1f964b36 100644
--- a/examples/mrbgems/c_and_ruby_extension_example/mrbgem.rake
+++ b/examples/mrbgems/c_and_ruby_extension_example/mrbgem.rake
@@ -1,6 +1,6 @@
MRuby::Gem::Specification.new('c_and_ruby_extension_example') do |spec|
spec.license = 'MIT'
- spec.authors = 'mruby developers'
+ spec.author = 'mruby developers'
# Add compile flags
# spec.cc.flags << ''
diff --git a/examples/mrbgems/c_extension_example/mrbgem.rake b/examples/mrbgems/c_extension_example/mrbgem.rake
index 8c132b233..3524e22f4 100644
--- a/examples/mrbgems/c_extension_example/mrbgem.rake
+++ b/examples/mrbgems/c_extension_example/mrbgem.rake
@@ -1,6 +1,6 @@
MRuby::Gem::Specification.new('c_extension_example') do |spec|
spec.license = 'MIT'
- spec.authors = 'mruby developers'
+ spec.author = 'mruby developers'
# Add compile flags
# spec.cc.flags << '-g'
diff --git a/examples/mrbgems/ruby_extension_example/mrbgem.rake b/examples/mrbgems/ruby_extension_example/mrbgem.rake
index 3a80b5cd7..5624c33e9 100644
--- a/examples/mrbgems/ruby_extension_example/mrbgem.rake
+++ b/examples/mrbgems/ruby_extension_example/mrbgem.rake
@@ -1,6 +1,6 @@
MRuby::Gem::Specification.new('ruby_extension_example') do |spec|
spec.license = 'MIT'
- spec.authors = 'mruby developers'
+ spec.author = 'mruby developers'
# Add compile flags
# spec.cc.flags << ''
diff --git a/examples/targets/ArduinoDue.rb b/examples/targets/ArduinoDue.rb
index c45efb57c..a4af4a926 100644
--- a/examples/targets/ArduinoDue.rb
+++ b/examples/targets/ArduinoDue.rb
@@ -5,6 +5,8 @@
MRuby::CrossBuild.new("Arduino Due") do |conf|
toolchain :gcc
+ # Mac OS X
+ # ARDUINO_PATH = '/Applications/Arduino.app/Contents/Resources/Java'
# GNU Linux
ARDUINO_PATH = '/opt/arduino'
BIN_PATH = "#{ARDUINO_PATH}/hardware/tools/g++_arm_none_eabi/bin"
@@ -13,18 +15,28 @@ MRuby::CrossBuild.new("Arduino Due") do |conf|
conf.cc do |cc|
cc.command = "#{BIN_PATH}/arm-none-eabi-gcc"
- cc.include_paths << ["#{SAM_PATH}/system/libsam -I#{SAM_PATH}/system/CMSIS/CMSIS/Include/",
+ cc.include_paths << ["#{SAM_PATH}/system/libsam", "#{SAM_PATH}/system/CMSIS/CMSIS/Include/",
"#{SAM_PATH}/system/CMSIS/Device/ATMEL/",
- "#{SAM_PATH}/cores/arduino -I#{TARGET_PATH}"]
+ "#{SAM_PATH}/cores/arduino", "#{SAM_PATH}/libraries","#{TARGET_PATH}"]
cc.flags = %w(-g -Os -w -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500
-Dprintf=iprintf -mcpu=cortex-m3 -DF_CPU=84000000L -DARDUINO=152 -D__SAM3X8E__ -mthumb -DUSB_PID=0x003e -DUSB_VID=0x2341 -DUSBCON)
cc.compile_options = "%{flags} -o %{outfile} -c %{infile}"
+
+ #configuration for low memory environment
+ cc.defines << %w(MRB_HEAP_PAGE_SIZE=64)
+ cc.defines << %w(MRB_USE_IV_SEGLIST)
+ cc.defines << %w(KHASH_DEFAULT_SIZE=8)
+ cc.defines << %w(MRB_STR_BUF_MIN_SIZE=20)
+ cc.defines << %w(MRB_GC_STRESS)
+ #cc.defines << %w(DISABLE_STDIO) #if you dont need stdio.
+ #cc.defines << %w(POOL_PAGE_SIZE=1000) #effective only for use with mruby-eval
end
conf.cxx do |cxx|
cxx.command = conf.cc.command.dup
cxx.include_paths = conf.cc.include_paths.dup
cxx.flags = conf.cc.flags.dup
+ cxx.defines = conf.cc.defines.dup
cxx.compile_options = conf.cc.compile_options.dup
end
@@ -36,4 +48,18 @@ MRuby::CrossBuild.new("Arduino Due") do |conf|
#no executables
conf.bins = []
+ #do not build executable test
+ conf.build_mrbtest_lib_only
+
+ #gems from core
+ conf.gem :core => "mruby-print"
+ conf.gem :core => "mruby-math"
+ conf.gem :core => "mruby-enum-ext"
+
+ #light-weight regular expression
+ conf.gem :github => "masamitsu-murase/mruby-hs-regexp", :branch => "master"
+
+ #Arduino API
+ #conf.gem :github =>"kyab/mruby-arduino", :branch => "master"
+
end
diff --git a/examples/targets/chipKitMax32.rb b/examples/targets/chipKitMax32.rb
index 380a34094..5c3a30a2b 100644
--- a/examples/targets/chipKitMax32.rb
+++ b/examples/targets/chipKitMax32.rb
@@ -24,12 +24,22 @@ MRuby::CrossBuild.new("chipKitMax32") do |conf|
-fno-short-double -mprocessor=32MX795F512L -DF_CPU=80000000L -DARDUINO=23 -D_BOARD_MEGA_
-DMPIDEVER=0x01000202 -DMPIDE=23)
cc.compile_options = "%{flags} -o %{outfile} -c %{infile}"
+
+ #configuration for low memory environment
+ cc.defines << %w(MRB_HEAP_PAGE_SIZE=64)
+ cc.defines << %w(MRB_USE_IV_SEGLIST)
+ cc.defines << %w(KHASH_DEFAULT_SIZE=8)
+ cc.defines << %w(MRB_STR_BUF_MIN_SIZE=20)
+ cc.defines << %w(MRB_GC_STRESS)
+ #cc.defines << %w(DISABLE_STDIO) #if you dont need stdio.
+ #cc.defines << %w(POOL_PAGE_SIZE=1000) #effective only for use with mruby-eval
end
conf.cxx do |cxx|
cxx.command = conf.cc.command.dup
cxx.include_paths = conf.cc.include_paths.dup
cxx.flags = conf.cc.flags.dup
+ cxx.defines = conf.cc.defines.dup
cxx.compile_options = conf.cc.compile_options.dup
end
@@ -41,4 +51,18 @@ MRuby::CrossBuild.new("chipKitMax32") do |conf|
#no executables
conf.bins = []
+ #do not build test executable
+ conf.build_mrbtest_lib_only
+
+ #gems from core
+ conf.gem :core => "mruby-print"
+ conf.gem :core => "mruby-math"
+ conf.gem :core => "mruby-enum-ext"
+
+ #light-weight regular expression
+ conf.gem :github => "masamitsu-murase/mruby-hs-regexp", :branch => "master"
+
+ #Arduino API
+ #conf.gem :github =>"kyab/mruby-arduino", :branch => "master"
+
end
diff --git a/include/mruby.h b/include/mruby.h
index 33a15de0e..dcd2aa5fc 100644
--- a/include/mruby.h
+++ b/include/mruby.h
@@ -73,15 +73,15 @@ enum mrb_fiber_state {
struct mrb_context {
struct mrb_context *prev;
- mrb_value *stack;
+ mrb_value *stack; /* stack of virtual machine */
mrb_value *stbase, *stend;
mrb_callinfo *ci;
mrb_callinfo *cibase, *ciend;
- mrb_code **rescue;
+ mrb_code **rescue; /* exception handler stack */
int rsize;
- struct RProc **ensure;
+ struct RProc **ensure; /* ensure handler stack */
int esize;
uint8_t status;
@@ -97,19 +97,19 @@ enum gc_state {
typedef struct mrb_state {
void *jmp;
- mrb_allocf allocf;
+ mrb_allocf allocf; /* memory allocation function */
struct mrb_context *c;
struct mrb_context *root_c;
- struct RObject *exc;
- struct iv_tbl *globals;
- struct mrb_irep **irep;
+ struct RObject *exc; /* exception */
+ struct iv_tbl *globals; /* global variable table */
+ struct mrb_irep **irep; /* program data array */
size_t irep_len, irep_capa;
mrb_sym init_sym;
struct RObject *top_self;
- struct RClass *object_class;
+ struct RClass *object_class; /* Object class */
struct RClass *class_class;
struct RClass *module_class;
struct RClass *proc_class;
@@ -125,17 +125,17 @@ typedef struct mrb_state {
struct RClass *symbol_class;
struct RClass *kernel_module;
- struct heap_page *heaps;
+ struct heap_page *heaps; /* heaps for GC */
struct heap_page *sweeps;
struct heap_page *free_heaps;
size_t live; /* count of live objects */
- struct RBasic *arena[MRB_ARENA_SIZE];
+ struct RBasic *arena[MRB_ARENA_SIZE]; /* GC protection array */
int arena_idx;
enum gc_state gc_state; /* state of gc */
int current_white_part; /* make white object by white_part */
- struct RBasic *gray_list; /* list of gray objects */
- struct RBasic *variable_gray_list; /* list of objects to be traversed atomically */
+ struct RBasic *gray_list; /* list of gray objects to be traversed incrementally */
+ struct RBasic *atomic_gray_list; /* list of objects to be traversed atomically */
size_t gc_live_after_mark;
size_t gc_threshold;
int gc_interval_ratio;
@@ -176,12 +176,13 @@ void mrb_undef_class_method(mrb_state*, struct RClass*, const char*);
mrb_value mrb_instance_new(mrb_state *mrb, mrb_value cv);
struct RClass * mrb_class_new(mrb_state *mrb, struct RClass *super);
struct RClass * mrb_module_new(mrb_state *mrb);
-int mrb_class_defined(mrb_state *mrb, const char *name);
+mrb_bool mrb_class_defined(mrb_state *mrb, const char *name);
struct RClass * mrb_class_get(mrb_state *mrb, const char *name);
+struct RClass * mrb_class_get_under(mrb_state *mrb, struct RClass *outer, const char *name);
mrb_value mrb_obj_dup(mrb_state *mrb, mrb_value obj);
mrb_value mrb_check_to_integer(mrb_state *mrb, mrb_value val, const char *method);
-int mrb_obj_respond_to(struct RClass* c, mrb_sym mid);
+mrb_bool mrb_obj_respond_to(struct RClass* c, mrb_sym mid);
struct RClass * mrb_define_class_under(mrb_state *mrb, struct RClass *outer, const char *name, struct RClass *super);
struct RClass * mrb_define_module_under(mrb_state *mrb, struct RClass *outer, const char *name);
@@ -239,9 +240,11 @@ mrb_sym mrb_intern(mrb_state *mrb,const char *cstr)
return mrb_intern_cstr(mrb, cstr);
}
-void *mrb_malloc(mrb_state*, size_t);
-void *mrb_calloc(mrb_state*, size_t, size_t);
-void *mrb_realloc(mrb_state*, void*, size_t);
+void *mrb_malloc(mrb_state*, size_t); /* raise RuntimeError if no mem */
+void *mrb_calloc(mrb_state*, size_t, size_t); /* ditto */
+void *mrb_realloc(mrb_state*, void*, size_t); /* ditto */
+void *mrb_realloc_simple(mrb_state*, void*, size_t); /* return NULL if no memory available */
+void *mrb_malloc_simple(mrb_state*, size_t); /* return NULL if no memory available */
struct RBasic *mrb_obj_alloc(mrb_state*, enum mrb_vtype, struct RClass*);
void mrb_free(mrb_state*, void*);
@@ -261,15 +264,16 @@ void mrb_p(mrb_state*, mrb_value);
mrb_int mrb_obj_id(mrb_value obj);
mrb_sym mrb_obj_to_sym(mrb_state *mrb, mrb_value name);
-int mrb_obj_eq(mrb_state*, mrb_value, mrb_value);
-int mrb_obj_equal(mrb_state*, mrb_value, mrb_value);
-int mrb_equal(mrb_state *mrb, mrb_value obj1, mrb_value obj2);
+mrb_bool mrb_obj_eq(mrb_state*, mrb_value, mrb_value);
+mrb_bool mrb_obj_equal(mrb_state*, mrb_value, mrb_value);
+mrb_bool mrb_equal(mrb_state *mrb, mrb_value obj1, mrb_value obj2);
mrb_value mrb_Integer(mrb_state *mrb, mrb_value val);
mrb_value mrb_Float(mrb_state *mrb, mrb_value val);
mrb_value mrb_inspect(mrb_state *mrb, mrb_value obj);
-int mrb_eql(mrb_state *mrb, mrb_value obj1, mrb_value obj2);
+mrb_bool mrb_eql(mrb_state *mrb, mrb_value obj1, mrb_value obj2);
void mrb_garbage_collect(mrb_state*);
+void mrb_full_gc(mrb_state*);
void mrb_incremental_gc(mrb_state *);
int mrb_gc_arena_save(mrb_state*);
void mrb_gc_arena_restore(mrb_state*,int);
@@ -283,13 +287,13 @@ void mrb_field_write_barrier(mrb_state *, struct RBasic*, struct RBasic*);
} while (0)
void mrb_write_barrier(mrb_state *, struct RBasic*);
-mrb_value mrb_check_convert_type(mrb_state *mrb, mrb_value val, mrb_int type, const char *tname, const char *method);
+mrb_value mrb_check_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const char *tname, const char *method);
mrb_value mrb_any_to_s(mrb_state *mrb, mrb_value obj);
const char * mrb_obj_classname(mrb_state *mrb, mrb_value obj);
struct RClass* mrb_obj_class(mrb_state *mrb, mrb_value obj);
mrb_value mrb_class_path(mrb_state *mrb, struct RClass *c);
-mrb_value mrb_convert_type(mrb_state *mrb, mrb_value val, mrb_int type, const char *tname, const char *method);
-int mrb_obj_is_kind_of(mrb_state *mrb, mrb_value obj, struct RClass *c);
+mrb_value mrb_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const char *tname, const char *method);
+mrb_bool mrb_obj_is_kind_of(mrb_state *mrb, mrb_value obj, struct RClass *c);
mrb_value mrb_obj_inspect(mrb_state *mrb, mrb_value self);
mrb_value mrb_obj_clone(mrb_state *mrb, mrb_value self);
@@ -366,8 +370,8 @@ void mrb_define_global_const(mrb_state *mrb, const char *name, mrb_value val);
mrb_value mrb_block_proc(void);
mrb_value mrb_attr_get(mrb_state *mrb, mrb_value obj, mrb_sym id);
-int mrb_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym mid);
-int mrb_obj_is_instance_of(mrb_state *mrb, mrb_value obj, struct RClass* c);
+mrb_bool mrb_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym mid);
+mrb_bool mrb_obj_is_instance_of(mrb_state *mrb, mrb_value obj, struct RClass* c);
/* memory pool implementation */
typedef struct mrb_pool mrb_pool;
@@ -375,9 +379,16 @@ struct mrb_pool* mrb_pool_open(mrb_state*);
void mrb_pool_close(struct mrb_pool*);
void* mrb_pool_alloc(struct mrb_pool*, size_t);
void* mrb_pool_realloc(struct mrb_pool*, void*, size_t oldlen, size_t newlen);
-int mrb_pool_can_realloc(struct mrb_pool*, void*, size_t);
+mrb_bool mrb_pool_can_realloc(struct mrb_pool*, void*, size_t);
void* mrb_alloca(mrb_state *mrb, size_t);
+#ifdef MRB_DEBUG
+#include <assert.h>
+#define mrb_assert(p) assert(p)
+#else
+#define mrb_assert(p) ((void)0)
+#endif
+
#if defined(__cplusplus)
} /* extern "C" { */
#endif
diff --git a/include/mruby/irep.h b/include/mruby/irep.h
index 856b12099..498b58ca3 100644
--- a/include/mruby/irep.h
+++ b/include/mruby/irep.h
@@ -11,10 +11,11 @@
extern "C" {
#endif
+/* Program data array struct */
typedef struct mrb_irep {
uint32_t idx;
- uint16_t nlocals;
- uint16_t nregs;
+ uint16_t nlocals; /* Number of local variables */
+ uint16_t nregs; /* Number of register variables */
uint8_t flags;
mrb_code *iseq;
diff --git a/include/mruby/khash.h b/include/mruby/khash.h
index db8048f5a..fb11586d2 100644
--- a/include/mruby/khash.h
+++ b/include/mruby/khash.h
@@ -27,12 +27,14 @@ typedef khint_t khiter_t;
//extern uint8_t __m[];
/* mask for flags */
-static const uint8_t __m[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
+static const uint8_t __m_empty[8] = {0x02, 0x08, 0x20, 0x80};
+static const uint8_t __m_del[8] = {0x01, 0x04, 0x10, 0x40};
+static const uint8_t __m_either[8] = {0x03, 0x0c, 0x30, 0xc0};
-#define __ac_isempty(e_flag, d_flag, i) (e_flag[(i)/8]&__m[(i)%8])
-#define __ac_isdel(e_flag, d_flag, i) (d_flag[(i)/8]&__m[(i)%8])
-#define __ac_iseither(e_flag, d_flag, i) (__ac_isempty(e_flag,d_flag,i)||__ac_isdel(e_flag,d_flag,i))
+#define __ac_isempty(ed_flag, i) (ed_flag[(i)/4]&__m_empty[(i)%4])
+#define __ac_isdel(ed_flag, i) (ed_flag[(i)/4]&__m_del[(i)%4])
+#define __ac_iseither(ed_flag, i) (ed_flag[(i)/4]&__m_either[(i)%4])
#define khash_power2(v) do { \
v--;\
v |= v >> 1;\
@@ -56,8 +58,7 @@ static const uint8_t __m[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
khint_t size; \
khint_t n_occupied; \
khint_t upper_bound; \
- uint8_t *e_flags; \
- uint8_t *d_flags; \
+ uint8_t *ed_flags; \
khkey_t *keys; \
khval_t *vals; \
khint_t mask; \
@@ -96,14 +97,13 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
void kh_alloc_##name(kh_##name##_t *h) \
{ \
khint_t sz = h->n_buckets; \
+ uint8_t *p = mrb_malloc(h->mrb, sizeof(uint8_t)*sz/4+(sizeof(khkey_t)+sizeof(khval_t))*sz); \
h->size = h->n_occupied = 0; \
h->upper_bound = UPPER_BOUND(sz); \
- h->e_flags = (uint8_t *)mrb_malloc(h->mrb, sizeof(uint8_t)*sz/4); \
- h->d_flags = h->e_flags + sz/8; \
- kh_fill_flags(h->e_flags, 0xff, sz/8); \
- kh_fill_flags(h->d_flags, 0x00, sz/8); \
- h->keys = (khkey_t *)mrb_malloc(h->mrb, sizeof(khkey_t)*sz); \
- h->vals = (khval_t *)mrb_malloc(h->mrb, sizeof(khval_t)*sz); \
+ h->keys = (khkey_t *)p; \
+ h->vals = (khval_t *)(p+sizeof(khkey_t)*sz); \
+ h->ed_flags = (p+sizeof(khkey_t)*sz+sizeof(khval_t)*sz); \
+ kh_fill_flags(h->ed_flags, 0xaa, sz/4); \
h->mask = sz-1; \
h->inc = sz/2-1; \
} \
@@ -124,24 +124,21 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
{ \
if (h) { \
mrb_free(h->mrb, h->keys); \
- mrb_free(h->mrb, h->vals); \
- mrb_free(h->mrb, h->e_flags); \
mrb_free(h->mrb, h); \
} \
} \
void kh_clear_##name(kh_##name##_t *h) \
{ \
- if (h && h->e_flags) { \
- kh_fill_flags(h->e_flags, 0xff, h->n_buckets/8); \
- kh_fill_flags(h->d_flags, 0x00, h->n_buckets/8); \
+ if (h && h->ed_flags) { \
+ kh_fill_flags(h->ed_flags, 0xaa, h->n_buckets/4); \
h->size = h->n_occupied = 0; \
} \
} \
khint_t kh_get_##name(kh_##name##_t *h, khkey_t key) \
{ \
khint_t k = __hash_func(h->mrb,key) & (h->mask); \
- while (!__ac_isempty(h->e_flags, h->d_flags, k)) { \
- if (!__ac_isdel(h->e_flags, h->d_flags, k)) { \
+ while (!__ac_isempty(h->ed_flags, k)) { \
+ if (!__ac_isdel(h->ed_flags, k)) { \
if (__hash_equal(h->mrb,h->keys[k], key)) return k; \
} \
k = (k+h->inc) & (h->mask); \
@@ -154,7 +151,7 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
new_n_buckets = KHASH_MIN_SIZE; \
khash_power2(new_n_buckets); \
{ \
- uint8_t *old_e_flags = h->e_flags; \
+ uint8_t *old_ed_flags = h->ed_flags; \
khkey_t *old_keys = h->keys; \
khval_t *old_vals = h->vals; \
khint_t old_n_buckets = h->n_buckets; \
@@ -163,14 +160,12 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
kh_alloc_##name(h); \
/* relocate */ \
for (i=0 ; i<old_n_buckets ; i++) { \
- if (!__ac_isempty(old_e_flags, old_d_flags, i)) { \
+ if (!__ac_iseither(old_ed_flags, i)) { \
khint_t k = kh_put_##name(h, old_keys[i]); \
kh_value(h,k) = old_vals[i]; \
} \
} \
- mrb_free(h->mrb, old_e_flags); \
mrb_free(h->mrb, old_keys); \
- mrb_free(h->mrb, old_vals); \
} \
} \
khint_t kh_put_##name(kh_##name##_t *h, khkey_t key) \
@@ -180,27 +175,27 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
kh_resize_##name(h, h->n_buckets*2); \
} \
k = __hash_func(h->mrb,key) & (h->mask); \
- while (!__ac_iseither(h->e_flags, h->d_flags, k)) { \
+ while (!__ac_iseither(h->ed_flags, k)) { \
if (__hash_equal(h->mrb,h->keys[k], key)) break; \
k = (k+h->inc) & (h->mask); \
} \
- if (__ac_isempty(h->e_flags, h->d_flags, k)) { \
+ if (__ac_isempty(h->ed_flags, k)) { \
/* put at empty */ \
h->keys[k] = key; \
- h->e_flags[k/8] &= ~__m[k%8]; \
+ h->ed_flags[k/4] &= ~__m_empty[k%4]; \
h->size++; \
h->n_occupied++; \
- } else if (__ac_isdel(h->e_flags, h->d_flags, k)) { \
+ } else if (__ac_isdel(h->ed_flags, k)) { \
/* put at del */ \
h->keys[k] = key; \
- h->d_flags[k/8] &= ~__m[k%8]; \
+ h->ed_flags[k/4] &= ~__m_del[k%4]; \
h->size++; \
} \
return k; \
} \
void kh_del_##name(kh_##name##_t *h, khint_t x) \
{ \
- h->d_flags[x/8] |= __m[x%8]; \
+ h->ed_flags[x/4] |= __m_del[x%4]; \
h->size--; \
} \
kh_##name##_t *kh_copy_##name(mrb_state *mrb, kh_##name##_t *h) \
@@ -231,7 +226,7 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
#define kh_del(name, h, k) kh_del_##name(h, k)
#define kh_copy(name, mrb, h) kh_copy_##name(mrb, h)
-#define kh_exist(h, x) (!__ac_iseither((h)->e_flags, (h)->d_flags, (x)))
+#define kh_exist(h, x) (!__ac_iseither((h)->ed_flags, (x)))
#define kh_key(h, x) ((h)->keys[x])
#define kh_val(h, x) ((h)->vals[x])
#define kh_value(h, x) ((h)->vals[x])
diff --git a/include/mruby/string.h b/include/mruby/string.h
index 26d1344d8..000c80b09 100644
--- a/include/mruby/string.h
+++ b/include/mruby/string.h
@@ -57,7 +57,7 @@ mrb_value mrb_str_to_str(mrb_state *mrb, mrb_value str);
mrb_int mrb_str_hash(mrb_state *mrb, mrb_value str);
mrb_value mrb_str_buf_append(mrb_state *mrb, mrb_value str, mrb_value str2);
mrb_value mrb_str_inspect(mrb_state *mrb, mrb_value str);
-int mrb_str_equal(mrb_state *mrb, mrb_value str1, mrb_value str2);
+mrb_bool mrb_str_equal(mrb_state *mrb, mrb_value str1, mrb_value str2);
mrb_value mrb_str_dump(mrb_state *mrb, mrb_value str);
mrb_value mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len);
mrb_value mrb_str_append(mrb_state *mrb, mrb_value str, mrb_value str2);
diff --git a/include/mruby/value.h b/include/mruby/value.h
index 06241ec76..e78035b5f 100644
--- a/include/mruby/value.h
+++ b/include/mruby/value.h
@@ -51,23 +51,29 @@
typedef short mrb_sym;
#ifdef _MSC_VER
-# define _ALLOW_KEYWORD_MACROS
-# include <float.h>
-# define inline __inline
+# ifndef __cplusplus
+# define inline __inline
+# endif
# define snprintf _snprintf
-# define isnan _isnan
-# define isinf(n) (!_finite(n) && !_isnan(n))
-# define strtoll _strtoi64
-# define PRId32 "I32d"
-# define PRIi32 "I32i"
-# define PRIo32 "I32o"
-# define PRIx32 "I32x"
-# define PRIX32 "I32X"
-# define PRId64 "I64d"
-# define PRIi64 "I64i"
-# define PRIo64 "I64o"
-# define PRIx64 "I64x"
-# define PRIX64 "I64X"
+# if _MSC_VER < 1800
+# include <float.h>
+# define isnan _isnan
+# define isinf(n) (!_finite(n) && !_isnan(n))
+# define strtoll _strtoi64
+# define strtof (float)strtod
+# define PRId32 "I32d"
+# define PRIi32 "I32i"
+# define PRIo32 "I32o"
+# define PRIx32 "I32x"
+# define PRIX32 "I32X"
+# define PRId64 "I64d"
+# define PRIi64 "I64i"
+# define PRIo64 "I64o"
+# define PRIx64 "I64x"
+# define PRIX64 "I64X"
+# else
+# include <inttypes.h>
+# endif
#else
# include <inttypes.h>
#endif
diff --git a/minirake b/minirake
index f41b9b587..e48ca1306 100755
--- a/minirake
+++ b/minirake
@@ -317,6 +317,8 @@ class RakeApp
"Require MODULE before executing rakefile."],
['--tasks', '-T', GetoptLong::NO_ARGUMENT,
"Display the tasks and dependencies, then exit."],
+ ['--pull-gems','-p', GetoptLong::NO_ARGUMENT,
+ "Pull all git mrbgems."],
['--trace', '-t', GetoptLong::NO_ARGUMENT,
"Turn on invoke/execute tracing."],
['--usage', '-h', GetoptLong::NO_ARGUMENT,
@@ -401,6 +403,8 @@ class RakeApp
require value
when '--tasks'
$show_tasks = true
+ when '--pull-gems'
+ $pull_gems = true
when '--trace'
$trace = true
when '--usage'
@@ -419,6 +423,7 @@ class RakeApp
# Read and handle the command line options.
def handle_options
$verbose = false
+ $pull_gems = false
opts = GetoptLong.new(*command_line_options)
opts.each { |opt, value| do_option(opt, value) }
end
diff --git a/mrbgems/default.gembox b/mrbgems/default.gembox
index 1c6732d48..33ee99be0 100644
--- a/mrbgems/default.gembox
+++ b/mrbgems/default.gembox
@@ -41,12 +41,18 @@ MRuby::GemBox.new do |conf|
# Use Random class
conf.gem :core => "mruby-random"
+ # Use extensional Object class
+ conf.gem :core => "mruby-object-ext"
+
# Use ObjectSpace class
conf.gem :core => "mruby-objectspace"
# Use Fiber class
conf.gem :core => "mruby-fiber"
+ # Use extended toplevel object (main) methods
+ conf.gem :core => "mruby-toplevel-ext"
+
# Generate mirb command
conf.gem :core => "mruby-bin-mirb"
diff --git a/mrbgems/mruby-array-ext/mrbgem.rake b/mrbgems/mruby-array-ext/mrbgem.rake
index 38e0ad267..18f92ad65 100644
--- a/mrbgems/mruby-array-ext/mrbgem.rake
+++ b/mrbgems/mruby-array-ext/mrbgem.rake
@@ -1,4 +1,4 @@
MRuby::Gem::Specification.new('mruby-array-ext') do |spec|
spec.license = 'MIT'
- spec.authors = 'mruby developers'
+ spec.author = 'mruby developers'
end
diff --git a/mrbgems/mruby-bin-mirb/mrbgem.rake b/mrbgems/mruby-bin-mirb/mrbgem.rake
index fd0b20254..846a3b077 100644
--- a/mrbgems/mruby-bin-mirb/mrbgem.rake
+++ b/mrbgems/mruby-bin-mirb/mrbgem.rake
@@ -1,5 +1,8 @@
MRuby::Gem::Specification.new('mruby-bin-mirb') do |spec|
spec.license = 'MIT'
- spec.authors = 'mruby developers'
+ spec.author = 'mruby developers'
+
+ spec.linker.libraries << 'readline' if spec.cc.defines.include? "ENABLE_READLINE"
+
spec.bins = %w(mirb)
end
diff --git a/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c b/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c
index 5e3e123c6..50556e092 100644
--- a/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c
+++ b/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c
@@ -15,11 +15,19 @@
#include <mruby/data.h>
#include <mruby/compile.h>
#ifdef ENABLE_READLINE
+#include <limits.h>
#include <readline/readline.h>
#include <readline/history.h>
#endif
#include <mruby/string.h>
+
+#ifdef ENABLE_READLINE
+static const char *history_file_name = ".mirb_history";
+char history_path[PATH_MAX];
+#endif
+
+
static void
p(mrb_state *mrb, mrb_value obj, int prompt)
{
@@ -38,7 +46,7 @@ p(mrb_state *mrb, mrb_value obj, int prompt)
/* Guess if the user might want to enter more
* or if he wants an evaluation of his code now */
-int
+mrb_bool
is_code_block_open(struct mrb_parser_state *parser)
{
int code_block_open = FALSE;
@@ -236,6 +244,8 @@ main(int argc, char **argv)
#ifndef ENABLE_READLINE
int last_char;
int char_index;
+#else
+ char *home = NULL;
#endif
mrbc_context *cxt;
struct mrb_parser_state *parser;
@@ -268,6 +278,23 @@ main(int argc, char **argv)
if (args.verbose) cxt->dump_result = 1;
ai = mrb_gc_arena_save(mrb);
+
+#ifdef ENABLE_READLINE
+ using_history();
+ home = getenv("HOME");
+#ifdef _WIN32
+ if (!home)
+ home = getenv("USERPROFILE");
+#endif
+ if (home) {
+ strcpy(history_path, home);
+ strcat(history_path, "/");
+ strcat(history_path, history_file_name);
+ read_history(history_path);
+ }
+#endif
+
+
while (TRUE) {
#ifndef ENABLE_READLINE
print_cmdline(code_block_open);
@@ -346,7 +373,7 @@ main(int argc, char **argv)
}
else {
/* no */
- if (!mrb_respond_to(mrb,result,mrb_intern(mrb,"inspect"))){
+ if (!mrb_respond_to(mrb, result, mrb_intern2(mrb, "inspect", 7))){
result = mrb_any_to_s(mrb,result);
}
p(mrb, result, 1);
@@ -361,5 +388,9 @@ main(int argc, char **argv)
mrbc_context_free(mrb, cxt);
mrb_close(mrb);
+#ifdef ENABLE_READLINE
+ write_history(history_path);
+#endif
+
return 0;
}
diff --git a/mrbgems/mruby-bin-mruby/mrbgem.rake b/mrbgems/mruby-bin-mruby/mrbgem.rake
index 2e173a291..08ba89855 100644
--- a/mrbgems/mruby-bin-mruby/mrbgem.rake
+++ b/mrbgems/mruby-bin-mruby/mrbgem.rake
@@ -1,5 +1,5 @@
MRuby::Gem::Specification.new('mruby-bin-mruby') do |spec|
spec.license = 'MIT'
- spec.authors = 'mruby developers'
+ spec.author = 'mruby developers'
spec.bins = %w(mruby)
end
diff --git a/mrbgems/mruby-enum-ext/mrbgem.rake b/mrbgems/mruby-enum-ext/mrbgem.rake
index 758d298dc..e054f4318 100644
--- a/mrbgems/mruby-enum-ext/mrbgem.rake
+++ b/mrbgems/mruby-enum-ext/mrbgem.rake
@@ -1,4 +1,4 @@
MRuby::Gem::Specification.new('mruby-enum-ext') do |spec|
spec.license = 'MIT'
- spec.authors = 'mruby developers'
+ spec.author = 'mruby developers'
end
diff --git a/mrbgems/mruby-eval/mrbgem.rake b/mrbgems/mruby-eval/mrbgem.rake
index f80cf1b9e..217a9e604 100644
--- a/mrbgems/mruby-eval/mrbgem.rake
+++ b/mrbgems/mruby-eval/mrbgem.rake
@@ -1,4 +1,4 @@
MRuby::Gem::Specification.new('mruby-eval') do |spec|
spec.license = 'MIT'
- spec.authors = 'mruby developers'
+ spec.author = 'mruby developers'
end
diff --git a/mrbgems/mruby-fiber/mrbgem.rake b/mrbgems/mruby-fiber/mrbgem.rake
index cb258adcb..25009c47f 100644
--- a/mrbgems/mruby-fiber/mrbgem.rake
+++ b/mrbgems/mruby-fiber/mrbgem.rake
@@ -1,4 +1,4 @@
MRuby::Gem::Specification.new('mruby-fiber') do |spec|
spec.license = 'MIT'
- spec.authors = 'mruby developers'
+ spec.author = 'mruby developers'
end
diff --git a/mrbgems/mruby-hash-ext/mrbgem.rake b/mrbgems/mruby-hash-ext/mrbgem.rake
index 3163c8c88..25d4f8e61 100644
--- a/mrbgems/mruby-hash-ext/mrbgem.rake
+++ b/mrbgems/mruby-hash-ext/mrbgem.rake
@@ -1,4 +1,4 @@
MRuby::Gem::Specification.new('mruby-hash-ext') do |spec|
spec.license = 'MIT'
- spec.authors = 'mruby developers'
+ spec.author = 'mruby developers'
end
diff --git a/mrbgems/mruby-math/mrbgem.rake b/mrbgems/mruby-math/mrbgem.rake
index 4b0fa40fd..75d3d1fff 100644
--- a/mrbgems/mruby-math/mrbgem.rake
+++ b/mrbgems/mruby-math/mrbgem.rake
@@ -1,4 +1,4 @@
MRuby::Gem::Specification.new('mruby-math') do |spec|
spec.license = 'MIT'
- spec.authors = 'mruby developers'
+ spec.author = 'mruby developers'
end
diff --git a/mrbgems/mruby-math/src/math.c b/mrbgems/mruby-math/src/math.c
index bf3c007b4..bdc7767f7 100644
--- a/mrbgems/mruby-math/src/math.c
+++ b/mrbgems/mruby-math/src/math.c
@@ -12,8 +12,8 @@
#define domain_error(msg) \
mrb_raise(mrb, E_RANGE_ERROR, "Numerical argument is out of domain - " #msg)
-/* math functions not provided under Microsoft Visual C++ */
-#ifdef _MSC_VER
+/* math functions not provided by Microsoft Visual C++ 2012 or older */
+#if defined _MSC_VER && _MSC_VER < 1800
#define MATH_TOLERANCE 1E-12
@@ -87,6 +87,12 @@ erfc(double x)
return one_sqrtpi*exp(-x*x)*q2;
}
+double
+log2(double x)
+{
+ return log10(x)/log10(2.0);
+}
+
#endif
/*
@@ -358,18 +364,6 @@ math_atanh(mrb_state *mrb, mrb_value obj)
# define log10(x) ((x) < 0.0 ? nan("") : log10(x))
#endif
-#ifndef log2
-#ifndef HAVE_LOG2
-double
-log2(double x)
-{
- return log10(x)/log10(2.0);
-}
-#else
-extern double log2(double);
-#endif
-#endif
-
/*
* call-seq:
* Math.exp(x) -> float
diff --git a/mrbgems/mruby-numeric-ext/mrbgem.rake b/mrbgems/mruby-numeric-ext/mrbgem.rake
index 69c4fde4c..010804058 100644
--- a/mrbgems/mruby-numeric-ext/mrbgem.rake
+++ b/mrbgems/mruby-numeric-ext/mrbgem.rake
@@ -1,4 +1,4 @@
MRuby::Gem::Specification.new('mruby-numeric-ext') do |spec|
spec.license = 'MIT'
- spec.authors = 'mruby developers'
+ spec.author = 'mruby developers'
end
diff --git a/mrbgems/mruby-object-ext/mrbgem.rake b/mrbgems/mruby-object-ext/mrbgem.rake
new file mode 100644
index 000000000..980f1667a
--- /dev/null
+++ b/mrbgems/mruby-object-ext/mrbgem.rake
@@ -0,0 +1,4 @@
+MRuby::Gem::Specification.new('mruby-object-ext') do |spec|
+ spec.license = 'MIT'
+ spec.author = 'mruby developers'
+end
diff --git a/mrbgems/mruby-object-ext/src/object.c b/mrbgems/mruby-object-ext/src/object.c
new file mode 100644
index 000000000..598ebe91d
--- /dev/null
+++ b/mrbgems/mruby-object-ext/src/object.c
@@ -0,0 +1,108 @@
+#include "mruby.h"
+#include "mruby/array.h"
+#include "mruby/class.h"
+
+/*
+ * call-seq:
+ * nil.to_a -> []
+ *
+ * Always returns an empty array.
+ */
+
+static mrb_value
+nil_to_a(mrb_state *mrb, mrb_value obj)
+{
+ return mrb_ary_new(mrb);
+}
+
+/*
+ * call-seq:
+ * nil.to_f -> 0.0
+ *
+ * Always returns zero.
+ */
+
+static mrb_value
+nil_to_f(mrb_state *mrb, mrb_value obj)
+{
+ return mrb_float_value(mrb, 0.0);
+}
+
+/*
+ * call-seq:
+ * nil.to_i -> 0
+ *
+ * Always returns zero.
+ */
+
+static mrb_value
+nil_to_i(mrb_state *mrb, mrb_value obj)
+{
+ return mrb_fixnum_value(0);
+}
+
+/*
+ * call-seq:
+ * obj.instance_exec(arg...) {|var...| block } -> obj
+ *
+ * Executes the given block within the context of the receiver
+ * (_obj_). In order to set the context, the variable +self+ is set
+ * to _obj_ while the code is executing, giving the code access to
+ * _obj_'s instance variables. Arguments are passed as block parameters.
+ *
+ * class KlassWithSecret
+ * def initialize
+ * @secret = 99
+ * end
+ * end
+ * k = KlassWithSecret.new
+ * k.instance_exec(5) {|x| @secret+x } #=> 104
+ */
+
+mrb_value
+mrb_yield_internal(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv, mrb_value self, struct RClass *c);
+
+static mrb_value
+mrb_obj_instance_exec(mrb_state *mrb, mrb_value self)
+{
+ mrb_value *argv;
+ int argc;
+ mrb_value blk;
+ struct RClass *c;
+
+ mrb_get_args(mrb, "*&", &argv, &argc, &blk);
+
+ if (mrb_nil_p(blk)) {
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
+ }
+
+ switch (mrb_type(self)) {
+ case MRB_TT_SYMBOL:
+ case MRB_TT_FIXNUM:
+ case MRB_TT_FLOAT:
+ c = 0;
+ break;
+ default:
+ c = mrb_class_ptr(mrb_singleton_class(mrb, self));
+ break;
+ }
+
+ return mrb_yield_internal(mrb, blk, argc, argv, self, c);
+}
+
+void
+mrb_mruby_object_ext_gem_init(mrb_state* mrb)
+{
+ struct RClass * n = mrb->nil_class;
+
+ mrb_define_method(mrb, n, "to_a", nil_to_a, MRB_ARGS_NONE());
+ mrb_define_method(mrb, n, "to_f", nil_to_f, MRB_ARGS_NONE());
+ mrb_define_method(mrb, n, "to_i", nil_to_i, MRB_ARGS_NONE());
+
+ mrb_define_method(mrb, mrb->object_class, "instance_exec", mrb_obj_instance_exec, MRB_ARGS_ANY() | MRB_ARGS_BLOCK());
+}
+
+void
+mrb_mruby_object_ext_gem_final(mrb_state* mrb)
+{
+}
diff --git a/mrbgems/mruby-object-ext/test/nil.rb b/mrbgems/mruby-object-ext/test/nil.rb
new file mode 100644
index 000000000..e385dec6a
--- /dev/null
+++ b/mrbgems/mruby-object-ext/test/nil.rb
@@ -0,0 +1,11 @@
+assert('NilClass#to_a') do
+ assert_equal nil.to_a, []
+end
+
+assert('NilClass#to_f') do
+ assert_equal nil.to_f, 0.0
+end
+
+assert('NilClass#to_i') do
+ assert_equal nil.to_i, 0
+end
diff --git a/mrbgems/mruby-object-ext/test/object.rb b/mrbgems/mruby-object-ext/test/object.rb
new file mode 100644
index 000000000..1a75622f6
--- /dev/null
+++ b/mrbgems/mruby-object-ext/test/object.rb
@@ -0,0 +1,9 @@
+assert('Object#instance_exec') do
+ class KlassWithSecret
+ def initialize
+ @secret = 99
+ end
+ end
+ k = KlassWithSecret.new
+ assert_equal k.instance_exec(5) {|x| @secret+x }, 104
+end
diff --git a/mrbgems/mruby-objectspace/mrbgem.rake b/mrbgems/mruby-objectspace/mrbgem.rake
index 100df4cdc..6a6a3e778 100644
--- a/mrbgems/mruby-objectspace/mrbgem.rake
+++ b/mrbgems/mruby-objectspace/mrbgem.rake
@@ -1,4 +1,4 @@
MRuby::Gem::Specification.new('mruby-objectspace') do |spec|
spec.license = 'MIT'
- spec.authors = 'mruby developers'
+ spec.author = 'mruby developers'
end
diff --git a/mrbgems/mruby-print/mrbgem.rake b/mrbgems/mruby-print/mrbgem.rake
index dc7831280..768fc2e18 100644
--- a/mrbgems/mruby-print/mrbgem.rake
+++ b/mrbgems/mruby-print/mrbgem.rake
@@ -1,4 +1,4 @@
MRuby::Gem::Specification.new('mruby-print') do |spec|
spec.license = 'MIT'
- spec.authors = 'mruby developers'
+ spec.author = 'mruby developers'
end
diff --git a/mrbgems/mruby-proc-ext/mrbgem.rake b/mrbgems/mruby-proc-ext/mrbgem.rake
index 7f979431d..b75fceda3 100644
--- a/mrbgems/mruby-proc-ext/mrbgem.rake
+++ b/mrbgems/mruby-proc-ext/mrbgem.rake
@@ -1,4 +1,4 @@
MRuby::Gem::Specification.new('mruby-proc-ext') do |spec|
spec.license = 'MIT'
- spec.authors = 'mruby developers'
+ spec.author = 'mruby developers'
end
diff --git a/mrbgems/mruby-random/mrbgem.rake b/mrbgems/mruby-random/mrbgem.rake
index 38e93e4b1..7ad3c855c 100644
--- a/mrbgems/mruby-random/mrbgem.rake
+++ b/mrbgems/mruby-random/mrbgem.rake
@@ -1,4 +1,4 @@
MRuby::Gem::Specification.new('mruby-random') do |spec|
spec.license = 'MIT'
- spec.authors = 'mruby developers'
+ spec.author = 'mruby developers'
end
diff --git a/mrbgems/mruby-random/src/random.c b/mrbgems/mruby-random/src/random.c
index 13b4fa7a3..1c89ca21d 100644
--- a/mrbgems/mruby-random/src/random.c
+++ b/mrbgems/mruby-random/src/random.c
@@ -11,12 +11,17 @@
#include <time.h>
-#define GLOBAL_RAND_SEED_KEY "$mrb_g_rand_seed"
-#define INSTANCE_RAND_SEED_KEY "$mrb_i_rand_seed"
-#define MT_STATE_KEY "$mrb_i_mt_state"
+#define GLOBAL_RAND_SEED_KEY "$mrb_g_rand_seed"
+#define GLOBAL_RAND_SEED_KEY_CSTR_LEN 16
+
+#define INSTANCE_RAND_SEED_KEY "$mrb_i_rand_seed"
+#define INSTANCE_RAND_SEED_KEY_CSTR_LEN 16
+
+#define MT_STATE_KEY "$mrb_i_mt_state"
+#define MT_STATE_KEY_CSTR_LEN 15
static const struct mrb_data_type mt_state_type = {
- MT_STATE_KEY, mrb_free,
+ MT_STATE_KEY, mrb_free,
};
static mt_state *mrb_mt_get_context(mrb_state *mrb, mrb_value self)
@@ -24,7 +29,7 @@ static mt_state *mrb_mt_get_context(mrb_state *mrb, mrb_value self)
mt_state *t;
mrb_value context;
- context = mrb_iv_get(mrb, self, mrb_intern(mrb, MT_STATE_KEY));
+ context = mrb_iv_get(mrb, self, mrb_intern2(mrb, MT_STATE_KEY, MT_STATE_KEY_CSTR_LEN));
t = (mt_state*)mrb_data_get_ptr(mrb, context, &mt_state_type);
if (!t)
mrb_raise(mrb, E_RUNTIME_ERROR, "mt_state get from mrb_iv_get failed");
@@ -141,7 +146,7 @@ static mrb_value mrb_random_g_rand(mrb_state *mrb, mrb_value self)
mrb_value seed;
max = get_opt(mrb);
- seed = mrb_gv_get(mrb, mrb_intern(mrb, GLOBAL_RAND_SEED_KEY));
+ seed = mrb_gv_get(mrb, mrb_intern2(mrb, GLOBAL_RAND_SEED_KEY, GLOBAL_RAND_SEED_KEY_CSTR_LEN));
if (mrb_nil_p(seed)) {
mrb_random_mt_g_srand(mrb, mrb_nil_value());
}
@@ -155,8 +160,8 @@ static mrb_value mrb_random_g_srand(mrb_state *mrb, mrb_value self)
seed = get_opt(mrb);
seed = mrb_random_mt_g_srand(mrb, seed);
- old_seed = mrb_gv_get(mrb, mrb_intern(mrb, GLOBAL_RAND_SEED_KEY));
- mrb_gv_set(mrb, mrb_intern(mrb, GLOBAL_RAND_SEED_KEY), seed);
+ old_seed = mrb_gv_get(mrb, mrb_intern2(mrb, GLOBAL_RAND_SEED_KEY, GLOBAL_RAND_SEED_KEY_CSTR_LEN));
+ mrb_gv_set(mrb, mrb_intern2(mrb, GLOBAL_RAND_SEED_KEY, GLOBAL_RAND_SEED_KEY_CSTR_LEN), seed);
return old_seed;
}
@@ -170,8 +175,8 @@ static mrb_value mrb_random_init(mrb_state *mrb, mrb_value self)
seed = get_opt(mrb);
seed = mrb_random_mt_srand(mrb, t, seed);
- mrb_iv_set(mrb, self, mrb_intern(mrb, INSTANCE_RAND_SEED_KEY), seed);
- mrb_iv_set(mrb, self, mrb_intern(mrb, MT_STATE_KEY),
+ mrb_iv_set(mrb, self, mrb_intern2(mrb, INSTANCE_RAND_SEED_KEY, INSTANCE_RAND_SEED_KEY_CSTR_LEN), seed);
+ mrb_iv_set(mrb, self, mrb_intern2(mrb, MT_STATE_KEY, MT_STATE_KEY_CSTR_LEN),
mrb_obj_value(Data_Wrap_Struct(mrb, mrb->object_class, &mt_state_type, (void*) t)));
return self;
}
@@ -183,7 +188,7 @@ static mrb_value mrb_random_rand(mrb_state *mrb, mrb_value self)
mt_state *t = mrb_mt_get_context(mrb, self);
max = get_opt(mrb);
- seed = mrb_iv_get(mrb, self, mrb_intern(mrb, INSTANCE_RAND_SEED_KEY));
+ seed = mrb_iv_get(mrb, self, mrb_intern2(mrb, INSTANCE_RAND_SEED_KEY, INSTANCE_RAND_SEED_KEY_CSTR_LEN));
if (mrb_nil_p(seed)) {
mrb_random_mt_srand(mrb, t, mrb_nil_value());
}
@@ -198,8 +203,8 @@ static mrb_value mrb_random_srand(mrb_state *mrb, mrb_value self)
seed = get_opt(mrb);
seed = mrb_random_mt_srand(mrb, t, seed);
- old_seed = mrb_iv_get(mrb, self, mrb_intern(mrb, INSTANCE_RAND_SEED_KEY));
- mrb_iv_set(mrb, self, mrb_intern(mrb, INSTANCE_RAND_SEED_KEY), seed);
+ old_seed = mrb_iv_get(mrb, self, mrb_intern2(mrb, INSTANCE_RAND_SEED_KEY, INSTANCE_RAND_SEED_KEY_CSTR_LEN));
+ mrb_iv_set(mrb, self, mrb_intern2(mrb, INSTANCE_RAND_SEED_KEY, INSTANCE_RAND_SEED_KEY_CSTR_LEN), seed);
return old_seed;
}
diff --git a/mrbgems/mruby-range-ext/mrbgem.rake b/mrbgems/mruby-range-ext/mrbgem.rake
index 5ed521a44..a7970aa51 100644
--- a/mrbgems/mruby-range-ext/mrbgem.rake
+++ b/mrbgems/mruby-range-ext/mrbgem.rake
@@ -1,4 +1,4 @@
MRuby::Gem::Specification.new('mruby-range-ext') do |spec|
spec.license = 'MIT'
- spec.authors = 'mruby developers'
+ spec.author = 'mruby developers'
end
diff --git a/mrbgems/mruby-range-ext/src/range.c b/mrbgems/mruby-range-ext/src/range.c
index 377677ffb..4e17dac8c 100644
--- a/mrbgems/mruby-range-ext/src/range.c
+++ b/mrbgems/mruby-range-ext/src/range.c
@@ -1,7 +1,7 @@
#include "mruby.h"
#include "mruby/range.h"
-static int
+static mrb_bool
r_le(mrb_state *mrb, mrb_value a, mrb_value b)
{
mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */
@@ -15,7 +15,7 @@ r_le(mrb_state *mrb, mrb_value a, mrb_value b)
return FALSE;
}
-static int
+static mrb_bool
r_lt(mrb_state *mrb, mrb_value a, mrb_value b)
{
mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b);
diff --git a/mrbgems/mruby-sprintf/mrbgem.rake b/mrbgems/mruby-sprintf/mrbgem.rake
index 8772a5174..3e15ee7a9 100644
--- a/mrbgems/mruby-sprintf/mrbgem.rake
+++ b/mrbgems/mruby-sprintf/mrbgem.rake
@@ -1,4 +1,4 @@
MRuby::Gem::Specification.new('mruby-sprintf') do |spec|
spec.license = 'MIT'
- spec.authors = 'mruby developers'
+ spec.author = 'mruby developers'
end
diff --git a/mrbgems/mruby-sprintf/src/sprintf.c b/mrbgems/mruby-sprintf/src/sprintf.c
index 55698d09f..6479b19bc 100644
--- a/mrbgems/mruby-sprintf/src/sprintf.c
+++ b/mrbgems/mruby-sprintf/src/sprintf.c
@@ -15,10 +15,6 @@
#include <math.h>
#include <ctype.h>
-#ifdef _MSC_VER
-#include <float.h>
-#endif
-
#ifdef HAVE_IEEEFP_H
#include <ieeefp.h>
#endif
diff --git a/mrbgems/mruby-string-ext/mrbgem.rake b/mrbgems/mruby-string-ext/mrbgem.rake
index 83db97eb4..4a3369998 100644
--- a/mrbgems/mruby-string-ext/mrbgem.rake
+++ b/mrbgems/mruby-string-ext/mrbgem.rake
@@ -1,4 +1,4 @@
MRuby::Gem::Specification.new('mruby-string-ext') do |spec|
spec.license = 'MIT'
- spec.authors = 'mruby developers'
+ spec.author = 'mruby developers'
end
diff --git a/mrbgems/mruby-struct/mrbgem.rake b/mrbgems/mruby-struct/mrbgem.rake
index 476e990da..3e9eab8d7 100644
--- a/mrbgems/mruby-struct/mrbgem.rake
+++ b/mrbgems/mruby-struct/mrbgem.rake
@@ -1,4 +1,4 @@
MRuby::Gem::Specification.new('mruby-struct') do |spec|
spec.license = 'MIT'
- spec.authors = 'mruby developers'
+ spec.author = 'mruby developers'
end
diff --git a/mrbgems/mruby-struct/src/struct.c b/mrbgems/mruby-struct/src/struct.c
index a2731ca54..a8511fc3c 100644
--- a/mrbgems/mruby-struct/src/struct.c
+++ b/mrbgems/mruby-struct/src/struct.c
@@ -43,7 +43,7 @@ struct_ivar_get(mrb_state *mrb, mrb_value c, mrb_sym id)
mrb_value
mrb_struct_iv_get(mrb_state *mrb, mrb_value c, const char *name)
{
- return struct_ivar_get(mrb, c, mrb_intern(mrb, name));
+ return struct_ivar_get(mrb, c, mrb_intern_cstr(mrb, name));
}
mrb_value
@@ -185,8 +185,7 @@ static mrb_value
mrb_struct_set(mrb_state *mrb, mrb_value obj, mrb_value val)
{
const char *name;
- int i;
- size_t len;
+ size_t i, len;
mrb_sym mid;
mrb_value members, slot, *ptr, *ptr_members;
diff --git a/mrbgems/mruby-symbol-ext/mrbgem.rake b/mrbgems/mruby-symbol-ext/mrbgem.rake
index 8e40c743b..6294e7a46 100644
--- a/mrbgems/mruby-symbol-ext/mrbgem.rake
+++ b/mrbgems/mruby-symbol-ext/mrbgem.rake
@@ -1,4 +1,4 @@
MRuby::Gem::Specification.new('mruby-symbol-ext') do |spec|
spec.license = 'MIT'
- spec.authors = 'mruby developers'
+ spec.author = 'mruby developers'
end
diff --git a/mrbgems/mruby-time/mrbgem.rake b/mrbgems/mruby-time/mrbgem.rake
index 0f0b4899d..edf2aa3fc 100644
--- a/mrbgems/mruby-time/mrbgem.rake
+++ b/mrbgems/mruby-time/mrbgem.rake
@@ -1,4 +1,4 @@
MRuby::Gem::Specification.new('mruby-time') do |spec|
spec.license = 'MIT'
- spec.authors = 'mruby developers'
+ spec.author = 'mruby developers'
end
diff --git a/mrbgems/mruby-time/src/time.c b/mrbgems/mruby-time/src/time.c
index 2a2aabe72..8b797f047 100644
--- a/mrbgems/mruby-time/src/time.c
+++ b/mrbgems/mruby-time/src/time.c
@@ -105,7 +105,7 @@ static const char *mon_names[] = {
};
static const char *wday_names[] = {
- "Sun", "Mon", "Tus", "Wed", "Thu", "Fri", "Sat",
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
};
struct mrb_time {
diff --git a/mrbgems/mruby-toplevel-ext/mrbgem.rake b/mrbgems/mruby-toplevel-ext/mrbgem.rake
new file mode 100644
index 000000000..78eb73a26
--- /dev/null
+++ b/mrbgems/mruby-toplevel-ext/mrbgem.rake
@@ -0,0 +1,4 @@
+MRuby::Gem::Specification.new('mruby-toplevel-ext') do |spec|
+ spec.license = 'MIT'
+ spec.author = 'mruby developers'
+end
diff --git a/mrbgems/mruby-toplevel-ext/mrblib/toplevel.rb b/mrbgems/mruby-toplevel-ext/mrblib/toplevel.rb
new file mode 100644
index 000000000..774562398
--- /dev/null
+++ b/mrbgems/mruby-toplevel-ext/mrblib/toplevel.rb
@@ -0,0 +1,11 @@
+
+def self.include (*modules)
+ self.class.include(*modules)
+end
+
+def self.private(*methods)
+end
+def self.protected(*methods)
+end
+def self.public(*methods)
+end
diff --git a/mrbgems/mruby-toplevel-ext/test/toplevel.rb b/mrbgems/mruby-toplevel-ext/test/toplevel.rb
new file mode 100644
index 000000000..4401beba1
--- /dev/null
+++ b/mrbgems/mruby-toplevel-ext/test/toplevel.rb
@@ -0,0 +1,24 @@
+##
+# Toplevel Self(Ext) Test
+
+module ToplevelTestModule1
+ def method_foo
+ :foo
+ end
+
+ CONST_BAR = :bar
+end
+
+module ToplevelTestModule2
+ CONST_BAR = :bar2
+end
+
+assert('Toplevel#include') do
+ self.include ToplevelTestModule2, ToplevelTestModule1
+
+ assert_true self.class.included_modules.include?( ToplevelTestModule1 )
+ assert_true self.class.included_modules.include?( ToplevelTestModule2 )
+ assert_equal :foo, method_foo
+ assert_equal :bar2, CONST_BAR
+end
+
diff --git a/mrblib/class.rb b/mrblib/class.rb
index 4f268b6c8..6d624ee83 100644
--- a/mrblib/class.rb
+++ b/mrblib/class.rb
@@ -1,18 +1,24 @@
class Module
# 15.2.2.4.13
def attr_reader(*names)
- names.each{|name|
- name2 = ('@'+name.to_s).intern
- define_method(name){self.instance_variable_get(name2)}
- }
+ names.each do |name|
+ name = name.to_s
+ raise(NameError, "#{name.inspect} is not allowed as an instance variable name") if name.include?('@') || name.include?('?') || name.include?('$')
+
+ attr_name = '@'+name
+ define_method(name){self.instance_variable_get(attr_name)}
+ end
end
# 15.2.2.4.14
def attr_writer(*names)
- names.each{|name|
- name2 = ('@'+name.to_s).intern
- name = (name.to_s+"=").intern
- define_method(name){|v|self.instance_variable_set(name2,v)}
- }
+ names.each do |name|
+ name = name.to_s
+ raise(NameError, "#{name.inspect} is not allowed as an instance variable name") if name.include?('@') || name.include?('?') || name.include?('$')
+
+ attr_name = '@'+name
+ name = (name+"=").intern
+ define_method(name){|v|self.instance_variable_set(attr_name,v)}
+ end
end
# 15.2.2.4.12
def attr_accessor(*names)
diff --git a/mrblib/string.rb b/mrblib/string.rb
index 131d30446..49f87be8b 100644
--- a/mrblib/string.rb
+++ b/mrblib/string.rb
@@ -133,6 +133,18 @@ class String
a = self[pos+1..-1]
self.replace([b, value, a].join(''))
end
+
+ ##
+ # ISO 15.2.10.5.5
+ def =~(re)
+ re =~ self
+ end
+
+ ##
+ # ISO 15.2.10.5.27
+ def match(re, &block)
+ re.match(self, &block)
+ end
end
##
diff --git a/src/array.c b/src/array.c
index a4a09ec0a..ceda884c0 100644
--- a/src/array.c
+++ b/src/array.c
@@ -19,7 +19,7 @@
#define ARY_DEFAULT_LEN 4
#define ARY_SHRINK_RATIO 5 /* must be larger than 2 */
#define ARY_C_MAX_SIZE (SIZE_MAX / sizeof(mrb_value))
-#define ARY_MAX_SIZE ((ARY_C_MAX_SIZE < (size_t)MRB_INT_MAX) ? (mrb_int)ARY_C_MAX_SIZE : MRB_INT_MAX)
+#define ARY_MAX_SIZE ((ARY_C_MAX_SIZE < (size_t)MRB_INT_MAX) ? (mrb_int)ARY_C_MAX_SIZE : MRB_INT_MAX-1)
static inline mrb_value
ary_elt(mrb_value ary, mrb_int offset)
@@ -40,7 +40,7 @@ ary_new_capa(mrb_state *mrb, mrb_int capa)
if (capa > ARY_MAX_SIZE) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");
}
- blen = capa * sizeof(mrb_value) ;
+ blen = capa * sizeof(mrb_value);
if (blen < capa) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");
}
@@ -926,7 +926,8 @@ inspect_ary(mrb_state *mrb, mrb_value ary, mrb_value list)
}
if (mrb_array_p(RARRAY_PTR(ary)[i])) {
s = inspect_ary(mrb, RARRAY_PTR(ary)[i], list);
- } else {
+ }
+ else {
s = mrb_inspect(mrb, RARRAY_PTR(ary)[i]);
}
mrb_str_buf_cat(mrb, arystr, RSTRING_PTR(s), RSTRING_LEN(s));
@@ -1056,39 +1057,26 @@ static mrb_value
mrb_ary_equal(mrb_state *mrb, mrb_value ary1)
{
mrb_value ary2;
- mrb_bool equal_p;
+ mrb_int i;
mrb_get_args(mrb, "o", &ary2);
- if (mrb_obj_equal(mrb, ary1, ary2)) {
- equal_p = 1;
- }
- else if (mrb_special_const_p(ary2)) {
- equal_p = 0;
- }
- else if (!mrb_array_p(ary2)) {
+ if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_true_value();
+ if (mrb_special_const_p(ary2)) return mrb_false_value();
+ if (!mrb_array_p(ary2)) {
if (!mrb_respond_to(mrb, ary2, mrb_intern2(mrb, "to_ary", 6))) {
- equal_p = 0;
+ return mrb_false_value();
}
else {
- equal_p = mrb_equal(mrb, ary2, ary1);
+ return mrb_bool_value(mrb_equal(mrb, ary2, ary1));
}
}
- else if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) {
- equal_p = 0;
- }
- else {
- mrb_int i;
-
- equal_p = 1;
- for (i=0; i<RARRAY_LEN(ary1); i++) {
- if (!mrb_equal(mrb, ary_elt(ary1, i), ary_elt(ary2, i))) {
- equal_p = 0;
- break;
- }
+ if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return mrb_false_value();
+ for (i=0; i<RARRAY_LEN(ary1); i++) {
+ if (!mrb_equal(mrb, ary_elt(ary1, i), ary_elt(ary2, i))) {
+ return mrb_false_value();
}
}
-
- return mrb_bool_value(equal_p);
+ return mrb_true_value();
}
/* 15.2.12.5.34 (x) */
@@ -1104,30 +1092,18 @@ static mrb_value
mrb_ary_eql(mrb_state *mrb, mrb_value ary1)
{
mrb_value ary2;
- mrb_bool eql_p;
+ mrb_int i;
mrb_get_args(mrb, "o", &ary2);
- if (mrb_obj_equal(mrb, ary1, ary2)) {
- eql_p = 1;
- }
- else if (!mrb_array_p(ary2)) {
- eql_p = 0;
- }
- else if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) {
- eql_p = 0;
- }
- else {
- mrb_int i;
- eql_p = 1;
- for (i=0; i<RARRAY_LEN(ary1); i++) {
- if (!mrb_eql(mrb, ary_elt(ary1, i), ary_elt(ary2, i))) {
- eql_p = 0;
- break;
- }
+ if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_true_value();
+ if (!mrb_array_p(ary2)) return mrb_false_value();
+ if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return mrb_false_value();
+ for (i=0; i<RARRAY_LEN(ary1); i++) {
+ if (!mrb_eql(mrb, ary_elt(ary1, i), ary_elt(ary2, i))) {
+ return mrb_false_value();
}
}
-
- return mrb_bool_value(eql_p);
+ return mrb_true_value();
}
void
diff --git a/src/backtrace.c b/src/backtrace.c
index d5d0818ae..e05ad4326 100644
--- a/src/backtrace.c
+++ b/src/backtrace.c
@@ -18,7 +18,7 @@ mrb_print_backtrace(mrb_state *mrb)
int i, line;
fputs("trace:\n", stderr);
- ciidx = mrb_fixnum(mrb_obj_iv_get(mrb, mrb->exc, mrb_intern(mrb, "ciidx")));
+ ciidx = mrb_fixnum(mrb_obj_iv_get(mrb, mrb->exc, mrb_intern2(mrb, "ciidx", 5)));
if (ciidx >= mrb->c->ciend - mrb->c->cibase)
ciidx = 10; /* ciidx is broken... */
@@ -41,7 +41,7 @@ mrb_print_backtrace(mrb_state *mrb)
pc = mrb->c->cibase[i+1].pc;
}
else {
- pc = (mrb_code*)mrb_voidp(mrb_obj_iv_get(mrb, mrb->exc, mrb_intern(mrb, "lastpc")));
+ pc = (mrb_code*)mrb_voidp(mrb_obj_iv_get(mrb, mrb->exc, mrb_intern2(mrb, "lastpc", 6)));
}
if (irep->iseq <= pc && pc < irep->iseq + irep->ilen) {
line = irep->lines[pc - irep->iseq - 1];
diff --git a/src/class.c b/src/class.c
index 5fd3a4006..d67a4af3e 100644
--- a/src/class.c
+++ b/src/class.c
@@ -55,7 +55,7 @@ mrb_name_class(mrb_state *mrb, struct RClass *c, mrb_sym name)
mrb_obj_iv_set(mrb, (struct RObject*)c,
mrb_intern2(mrb, "__classid__", 11), mrb_symbol_value(name));
}
-
+
#define make_metaclass(mrb, c) prepare_singleton_class((mrb), (struct RBasic*)(c))
static void
@@ -78,6 +78,8 @@ prepare_singleton_class(mrb_state *mrb, struct RBasic *o)
}
else if (o->tt == MRB_TT_SCLASS) {
c = (struct RClass*)o;
+ while (c->super->tt == MRB_TT_ICLASS)
+ c = c->super;
make_metaclass(mrb, c->super);
sc->super = c->super->c;
}
@@ -105,7 +107,7 @@ mrb_define_module_id(mrb_state *mrb, mrb_sym name)
struct RClass*
mrb_define_module(mrb_state *mrb, const char *name)
{
- return mrb_define_module_id(mrb, mrb_intern(mrb, name));
+ return mrb_define_module_id(mrb, mrb_intern_cstr(mrb, name));
}
static void
@@ -159,9 +161,7 @@ mrb_define_class_id(mrb_state *mrb, mrb_sym name, struct RClass *super)
struct RClass*
mrb_define_class(mrb_state *mrb, const char *name, struct RClass *super)
{
- struct RClass *c;
- c = mrb_define_class_id(mrb, mrb_intern(mrb, name), super);
- return c;
+ return mrb_define_class_id(mrb, mrb_intern_cstr(mrb, name), super);
}
struct RClass*
@@ -203,7 +203,7 @@ mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id
return c;
}
-int
+mrb_bool
mrb_class_defined(mrb_state *mrb, const char *name)
{
mrb_value sym = mrb_check_intern_cstr(mrb, name);
@@ -227,7 +227,13 @@ class_from_sym(mrb_state *mrb, struct RClass *klass, mrb_sym id)
struct RClass *
mrb_class_get(mrb_state *mrb, const char *name)
{
- return class_from_sym(mrb, mrb->object_class, mrb_intern(mrb, name));
+ return mrb_class_get_under(mrb, mrb->object_class, name);
+}
+
+struct RClass *
+mrb_class_get_under(mrb_state *mrb, struct RClass *outer, const char *name)
+{
+ return class_from_sym(mrb, outer, mrb_intern_cstr(mrb, name));
}
/*!
@@ -250,7 +256,7 @@ struct RClass *
mrb_define_class_under(mrb_state *mrb, struct RClass *outer, const char *name, struct RClass *super)
{
struct RClass * c;
- mrb_sym id = mrb_intern(mrb, name);
+ mrb_sym id = mrb_intern_cstr(mrb, name);
if (mrb_const_defined_at(mrb, outer, id)) {
c = class_from_sym(mrb, outer, id);
@@ -272,7 +278,7 @@ struct RClass *
mrb_define_module_under(mrb_state *mrb, struct RClass *outer, const char *name)
{
struct RClass * c;
- mrb_sym id = mrb_intern(mrb, name);
+ mrb_sym id = mrb_intern_cstr(mrb, name);
if (mrb_const_defined_at(mrb, outer, id)) {
c = class_from_sym(mrb, outer, id);
@@ -313,7 +319,7 @@ mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t f
void
mrb_define_method(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec)
{
- mrb_define_method_id(mrb, c, mrb_intern(mrb, name), func, aspec);
+ mrb_define_method_id(mrb, c, mrb_intern_cstr(mrb, name), func, aspec);
}
void
@@ -371,20 +377,22 @@ to_hash(mrb_state *mrb, mrb_value val)
format specifiers:
- o: Object [mrb_value]
- S: String [mrb_value]
- A: Array [mrb_value]
- H: Hash [mrb_value]
- s: String [char*,int]
- z: String [char*]
- a: Array [mrb_value*,mrb_int]
- f: Float [mrb_float]
- i: Integer [mrb_int]
- b: Boolean [mrb_bool]
- n: Symbol [mrb_sym]
- &: Block [mrb_value]
- *: rest argument [mrb_value*,int]
- |: optional
+ string mruby type C type note
+ ----------------------------------------------------------------------------------------------
+ o: Object [mrb_value]
+ S: String [mrb_value]
+ A: Array [mrb_value]
+ H: Hash [mrb_value]
+ s: String [char*,int] Receive two arguments.
+ z: String [char*] NUL terminated string.
+ a: Array [mrb_value*,mrb_int] Receive two arguments.
+ f: Float [mrb_float]
+ i: Integer [mrb_int]
+ b: Boolean [mrb_bool]
+ n: Symbol [mrb_sym]
+ &: Block [mrb_value]
+ *: rest argument [mrb_value*,int] Receive the rest of the arguments as an array.
+ |: optional Next argument of '|' and later are optional.
*/
int
mrb_get_args(mrb_state *mrb, const char *format, ...)
@@ -487,7 +495,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
if (i < argc) {
ss = to_str(mrb, *sp++);
s = mrb_str_ptr(ss);
- if (strlen(s->ptr) != s->len) {
+ if (strlen(s->ptr) < s->len) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "String contains NUL");
}
*ps = s->ptr;
@@ -903,6 +911,12 @@ mrb_mod_module_eval(mrb_state *mrb, mrb_value mod)
}
mrb_value
+mrb_mod_dummy_visibility(mrb_state *mrb, mrb_value mod)
+{
+ return mod;
+}
+
+mrb_value
mrb_singleton_class(mrb_state *mrb, mrb_value v)
{
struct RBasic *obj;
@@ -933,7 +947,7 @@ void
mrb_define_singleton_method(mrb_state *mrb, struct RObject *o, const char *name, mrb_func_t func, mrb_aspec aspec)
{
prepare_singleton_class(mrb, (struct RBasic*)o);
- mrb_define_method_id(mrb, o->c, mrb_intern(mrb, name), func, aspec);
+ mrb_define_method_id(mrb, o->c, mrb_intern_cstr(mrb, name), func, aspec);
}
void
@@ -1069,6 +1083,7 @@ mrb_class_new_class(mrb_state *mrb, mrb_value cv)
super = mrb_obj_value(mrb->object_class);
}
new_class = mrb_class_new(mrb, mrb_class_ptr(super));
+ mrb_funcall(mrb, super, "inherited", 1, mrb_obj_value(new_class));
return mrb_obj_value(new_class);
}
@@ -1134,16 +1149,14 @@ mrb_bob_not(mrb_state *mrb, mrb_value cv)
static mrb_value
mrb_bob_missing(mrb_state *mrb, mrb_value mod)
{
- mrb_value name, *a;
+ mrb_sym name;
+ mrb_value *a;
int alen;
mrb_value inspect;
- mrb_get_args(mrb, "o*", &name, &a, &alen);
- if (!mrb_symbol_p(name)) {
- mrb_raise(mrb, E_TYPE_ERROR, "name should be a symbol");
- }
+ mrb_get_args(mrb, "n*", &name, &a, &alen);
- if (mrb_respond_to(mrb,mod,mrb_intern2(mrb,"inspect",7))){
+ if (mrb_respond_to(mrb,mod,mrb_intern2(mrb, "inspect",7))){
inspect = mrb_funcall(mrb, mod, "inspect", 0);
if (RSTRING_LEN(inspect) > 64) {
inspect = mrb_any_to_s(mrb, mod);
@@ -1154,12 +1167,12 @@ mrb_bob_missing(mrb_state *mrb, mrb_value mod)
}
mrb_raisef(mrb, E_NOMETHOD_ERROR, "undefined method '%S' for %S",
- mrb_sym2str(mrb, mrb_symbol(name)), inspect);
+ mrb_sym2str(mrb, name), inspect);
/* not reached */
return mrb_nil_value();
}
-int
+mrb_bool
mrb_obj_respond_to(struct RClass* c, mrb_sym mid)
{
khiter_t k;
@@ -1183,7 +1196,7 @@ mrb_obj_respond_to(struct RClass* c, mrb_sym mid)
return FALSE; /* no method */
}
-int
+mrb_bool
mrb_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym mid)
{
return mrb_obj_respond_to(mrb_class(mrb, obj), mid);
@@ -1338,7 +1351,7 @@ mrb_alias_method(mrb_state *mrb, struct RClass *c, mrb_sym a, mrb_sym b)
void
mrb_define_alias(mrb_state *mrb, struct RClass *klass, const char *name1, const char *name2)
{
- mrb_alias_method(mrb, klass, mrb_intern(mrb, name1), mrb_intern(mrb, name2));
+ mrb_alias_method(mrb, klass, mrb_intern_cstr(mrb, name1), mrb_intern_cstr(mrb, name2));
}
/*
@@ -1410,10 +1423,10 @@ mrb_value
mrb_mod_alias(mrb_state *mrb, mrb_value mod)
{
struct RClass *c = mrb_class_ptr(mod);
- mrb_value new_value, old_value;
+ mrb_sym new_name, old_name;
- mrb_get_args(mrb, "oo", &new_value, &old_value);
- mrb_alias_method(mrb, c, mrb_symbol(new_value), mrb_symbol(old_value));
+ mrb_get_args(mrb, "nn", &new_name, &old_name);
+ mrb_alias_method(mrb, c, new_name, old_name);
return mrb_nil_value();
}
@@ -1424,7 +1437,8 @@ undef_method(mrb_state *mrb, struct RClass *c, mrb_sym a)
if (!mrb_obj_respond_to(c, a)) {
mrb_name_error(mrb, a, "undefined method '%S' for class '%S'", mrb_sym2str(mrb, a), mrb_obj_value(c));
- } else {
+ }
+ else {
MRB_SET_VALUE(m, MRB_TT_PROC, value.p, 0);
mrb_define_method_vm(mrb, c, a, m);
}
@@ -1433,7 +1447,7 @@ undef_method(mrb_state *mrb, struct RClass *c, mrb_sym a)
void
mrb_undef_method(mrb_state *mrb, struct RClass *c, const char *name)
{
- undef_method(mrb, c, mrb_intern(mrb, name));
+ undef_method(mrb, c, mrb_intern_cstr(mrb, name));
}
void
@@ -1506,7 +1520,8 @@ get_sym_or_str_arg(mrb_state *mrb)
if (mrb_symbol_p(sym_or_str) || mrb_string_p(sym_or_str)) {
return sym_or_str;
- } else {
+ }
+ else {
mrb_value obj = mrb_funcall(mrb, sym_or_str, "inspect", 0);
mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", obj);
return mrb_nil_value();
@@ -1538,7 +1553,8 @@ mrb_mod_cvar_defined(mrb_state *mrb, mrb_value mod)
if (mrb_symbol_p(id)) {
check_cv_name_sym(mrb, mrb_symbol(id));
defined_p = mrb_cv_defined(mrb, mod, mrb_symbol(id));
- } else {
+ }
+ else {
mrb_value sym;
check_cv_name_str(mrb, id);
sym = mrb_check_intern_str(mrb, id);
@@ -1690,7 +1706,8 @@ mrb_mod_method_defined(mrb_state *mrb, mrb_value mod)
id = get_sym_or_str_arg(mrb);
if (mrb_symbol_p(id)) {
method_defined_p = mrb_obj_respond_to(mrb_class_ptr(mod), mrb_symbol(id));
- } else {
+ }
+ else {
mrb_value sym = mrb_check_intern_str(mrb, id);
if (mrb_nil_p(sym)) {
method_defined_p = FALSE;
@@ -1774,7 +1791,8 @@ mrb_mod_const_defined(mrb_state *mrb, mrb_value mod)
if (mrb_type(id) == MRB_TT_SYMBOL) {
check_const_name_sym(mrb, mrb_symbol(id));
const_defined_p = mrb_const_defined(mrb, mod, mrb_symbol(id));
- } else {
+ }
+ else {
mrb_value sym;
check_const_name_str(mrb, id);
sym = mrb_check_intern_str(mrb, id);
@@ -1874,10 +1892,10 @@ mrb_init_class(mrb_state *mrb)
mrb_define_const(mrb, obj, "Class", mrb_obj_value(cls));
/* name each classes */
- mrb_name_class(mrb, bob, mrb_intern(mrb, "BasicObject"));
- mrb_name_class(mrb, obj, mrb_intern(mrb, "Object")); /* 15.2.1 */
- mrb_name_class(mrb, mod, mrb_intern(mrb, "Module")); /* 15.2.2 */
- mrb_name_class(mrb, cls, mrb_intern(mrb, "Class")); /* 15.2.3 */
+ mrb_name_class(mrb, bob, mrb_intern2(mrb, "BasicObject", 11)); /* 15.2.1 */
+ mrb_name_class(mrb, obj, mrb_intern2(mrb, "Object", 6)); /* 15.2.1 */
+ mrb_name_class(mrb, mod, mrb_intern2(mrb, "Module", 6)); /* 15.2.2 */
+ mrb_name_class(mrb, cls, mrb_intern2(mrb, "Class", 5)); /* 15.2.3 */
MRB_SET_INSTANCE_TT(cls, MRB_TT_CLASS);
mrb_define_method(mrb, bob, "initialize", mrb_bob_init, MRB_ARGS_NONE());
@@ -1904,6 +1922,9 @@ mrb_init_class(mrb_state *mrb)
mrb_define_method(mrb, mod, "instance_methods", mrb_mod_instance_methods, MRB_ARGS_ANY()); /* 15.2.2.4.33 */
mrb_define_method(mrb, mod, "method_defined?", mrb_mod_method_defined, MRB_ARGS_REQ(1)); /* 15.2.2.4.34 */
mrb_define_method(mrb, mod, "module_eval", mrb_mod_module_eval, MRB_ARGS_ANY()); /* 15.2.2.4.35 */
+ mrb_define_method(mrb, mod, "private", mrb_mod_dummy_visibility, MRB_ARGS_ANY()); /* 15.2.2.4.36 */
+ mrb_define_method(mrb, mod, "protected", mrb_mod_dummy_visibility, MRB_ARGS_ANY()); /* 15.2.2.4.37 */
+ mrb_define_method(mrb, mod, "public", mrb_mod_dummy_visibility, MRB_ARGS_ANY()); /* 15.2.2.4.38 */
mrb_define_method(mrb, mod, "remove_class_variable", mrb_mod_remove_cvar, MRB_ARGS_REQ(1)); /* 15.2.2.4.39 */
mrb_define_method(mrb, mod, "remove_method", mrb_mod_remove_method, MRB_ARGS_ANY()); /* 15.2.2.4.41 */
mrb_define_method(mrb, mod, "to_s", mrb_mod_to_s, MRB_ARGS_NONE());
diff --git a/src/codegen.c b/src/codegen.c
index cfbbe7286..5681ce03a 100644
--- a/src/codegen.c
+++ b/src/codegen.c
@@ -59,7 +59,7 @@ typedef struct scope {
int icapa;
mrb_irep *irep;
- int pcapa;
+ size_t pcapa;
int scapa;
int nlocals;
@@ -426,9 +426,8 @@ push_(codegen_scope *s)
static inline int
new_lit(codegen_scope *s, mrb_value val)
{
- int i;
+ size_t i;
-
switch (mrb_type(val)) {
case MRB_TT_STRING:
for (i=0; i<s->irep->plen; i++) {
@@ -448,7 +447,7 @@ new_lit(codegen_scope *s, mrb_value val)
}
break;
}
-
+
if (s->irep->plen == s->pcapa) {
s->pcapa *= 2;
s->irep->pool = (mrb_value *)codegen_realloc(s, s->irep->pool, sizeof(mrb_value)*s->pcapa);
@@ -462,7 +461,7 @@ new_lit(codegen_scope *s, mrb_value val)
static inline int
new_msym(codegen_scope *s, mrb_sym sym)
{
- int i, len;
+ size_t i, len;
len = s->irep->slen;
if (len > 256) len = 256;
@@ -481,7 +480,7 @@ new_msym(codegen_scope *s, mrb_sym sym)
static inline int
new_sym(codegen_scope *s, mrb_sym sym)
{
- int i;
+ size_t i;
for (i=0; i<s->irep->slen; i++) {
if (s->irep->syms[i] == sym) return i;
@@ -684,7 +683,7 @@ scope_body(codegen_scope *s, node *tree)
return idx - s->idx;
}
-static int
+static mrb_bool
nosplat(node *t)
{
while (t) {
@@ -2065,7 +2064,7 @@ codegen(codegen_scope *s, node *tree, int val)
char *p1 = (char*)tree->car;
char *p2 = (char*)tree->cdr;
int ai = mrb_gc_arena_save(s->mrb);
- int sym = new_sym(s, mrb_intern(s->mrb, REGEXP_CLASS));
+ int sym = new_sym(s, mrb_intern2(s->mrb, REGEXP_CLASS, REGEXP_CLASS_CSTR_LEN));
int off = new_lit(s, mrb_str_new(s->mrb, p1, strlen(p1)));
int argc = 1;
@@ -2092,7 +2091,7 @@ codegen(codegen_scope *s, node *tree, int val)
if (val) {
node *n = tree->car;
int ai = mrb_gc_arena_save(s->mrb);
- int sym = new_sym(s, mrb_intern(s->mrb, REGEXP_CLASS));
+ int sym = new_sym(s, mrb_intern2(s->mrb, REGEXP_CLASS, REGEXP_CLASS_CSTR_LEN));
int argc = 1;
int off;
char *p;
@@ -2506,7 +2505,8 @@ codedump(mrb_state *mrb, int n)
{
#ifdef ENABLE_STDIO
mrb_irep *irep = mrb->irep[n];
- int i, ai;
+ uint32_t i;
+ int ai;
mrb_code c;
if (!irep) return;
@@ -2842,13 +2842,15 @@ codegen_start(mrb_state *mrb, parser_state *p)
if (p->filename) {
scope->filename = p->filename;
}
- if (setjmp(scope->jmp) != 0) {
+ if (setjmp(scope->jmp) == 0) {
+ // prepare irep
+ codegen(scope, p->tree, NOVAL);
+ mrb_pool_close(scope->mpool);
+ return 0;
+ }
+ else {
return -1;
}
- // prepare irep
- codegen(scope, p->tree, NOVAL);
- mrb_pool_close(scope->mpool);
- return 0;
}
int
diff --git a/src/crc.c b/src/crc.c
index 463c7abe6..3bda7bc26 100644
--- a/src/crc.c
+++ b/src/crc.c
@@ -6,7 +6,7 @@
#include <limits.h>
#include <stdint.h>
-#include <sys/types.h>
+#include <stddef.h>
// Calculate CRC (CRC-16-CCITT)
//
diff --git a/src/dump.c b/src/dump.c
index c2b987bc8..72ca9e0c3 100644
--- a/src/dump.c
+++ b/src/dump.c
@@ -334,8 +334,7 @@ static int
write_lineno_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin)
{
uint8_t *cur = bin;
- size_t filename_len = 0;
- int iseq_no;
+ size_t filename_len = 0, iseq_no;
cur += sizeof(uint32_t); /* record size */
@@ -365,13 +364,13 @@ write_lineno_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin)
}
static int
-mrb_write_section_lineno(mrb_state *mrb, int start_index, uint8_t *bin)
+mrb_write_section_lineno(mrb_state *mrb, size_t start_index, uint8_t *bin)
{
- int irep_no;
+ size_t irep_no;
uint32_t section_size = 0, rlen = 0; /* size of irep record */
uint8_t *cur = bin;
- if (mrb == NULL || start_index < 0 || start_index >= mrb->irep_len || bin == NULL) {
+ if (mrb == NULL || start_index >= mrb->irep_len || bin == NULL) {
return MRB_DUMP_INVALID_ARGUMENT;
}
diff --git a/src/error.c b/src/error.c
index bd3afd2e1..df4bbc866 100644
--- a/src/error.c
+++ b/src/error.c
@@ -5,7 +5,6 @@
*/
#include <errno.h>
-#include <setjmp.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
@@ -147,7 +146,8 @@ exc_inspect(mrb_state *mrb, mrb_value exc)
if (!mrb_nil_p(mesg) && RSTRING_LEN(mesg) > 0) {
mrb_str_cat(mrb, str, ": ", 2);
mrb_str_append(mrb, str, mesg);
- } else {
+ }
+ else {
mrb_str_cat(mrb, str, ": ", 2);
mrb_str_cat_cstr(mrb, str, mrb_obj_classname(mrb, exc));
}
@@ -218,7 +218,7 @@ mrb_exc_raise(mrb_state *mrb, mrb_value exc)
mrb_p(mrb, exc);
abort();
}
- longjmp(*(jmp_buf*)mrb->jmp, 1);
+ mrb_longjmp(mrb);
}
void
@@ -425,10 +425,12 @@ mrb_sys_fail(mrb_state *mrb, const char *mesg)
sce = mrb_class_get(mrb, "SystemCallError");
if (mesg != NULL) {
mrb_funcall(mrb, mrb_obj_value(sce), "_sys_fail", 2, mrb_fixnum_value(no), mrb_str_new_cstr(mrb, mesg));
- } else {
+ }
+ else {
mrb_funcall(mrb, mrb_obj_value(sce), "_sys_fail", 1, mrb_fixnum_value(no));
}
- } else {
+ }
+ else {
mrb_raise(mrb, E_RUNTIME_ERROR, mesg);
}
}
diff --git a/src/error.h b/src/error.h
index 3726cb4c4..5aa4ca374 100644
--- a/src/error.h
+++ b/src/error.h
@@ -14,5 +14,6 @@ mrb_value make_exception(mrb_state *mrb, int argc, mrb_value *argv, int isstr);
mrb_value mrb_make_exception(mrb_state *mrb, int argc, mrb_value *argv);
mrb_value mrb_format(mrb_state *mrb, const char *format, ...);
void mrb_exc_print(mrb_state *mrb, struct RObject *exc);
+void mrb_longjmp(mrb_state *mrb);
#endif /* MRUBY_ERROR_H */
diff --git a/src/gc.c b/src/gc.c
index 293fbf948..8569cc085 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -11,6 +11,7 @@
# include <limits.h>
#endif
#include <string.h>
+#include <stdlib.h>
#include "mruby.h"
#include "mruby/array.h"
#include "mruby/class.h"
@@ -37,18 +38,23 @@
* Gray - Marked, But the child objects are unmarked.
* Black - Marked, the child objects are also marked.
- == Two white part
+ == Two White Types
- The white has a different part of A and B.
- In sweep phase, the sweep target white is either A or B.
- The sweep target white is switched just before sweep phase.
- e.g. A -> B -> A -> B ...
+ There're two white color types in a flip-flop fassion: White-A and White-B,
+ which respectively represent the Current White color (the newly allocated
+ objects in the current GC cycle) and the Sweep Target White color (the
+ dead objects to be swept).
- All objects are painted white when allocated.
- This white is another the sweep target white.
- For example, if the sweep target white is A, it's B.
- So objects when allocated in sweep phase will be next sweep phase target.
- Therefore, these objects will not be released accidentally in sweep phase.
+ A and B will be switched just at the beginning of the next GC cycle. At
+ that time, all the dead objects have been swept, while the newly created
+ objects in the current GC cycle which finally remains White are now
+ regarded as dead objects. Instead of traversing all the White-A objects and
+ paint them as White-B, just switch the meaning of White-A and White-B would
+ be much cheaper.
+
+ As a result, the objects we sweep in the current GC cycle are always
+ left from the previous GC cycle. This allows us to sweep objects
+ incrementally, without the disturbance of the newly created objects.
== Execution Timing
@@ -60,7 +66,7 @@
For details, see the comments for each function.
- = Write Barrier
+ == Write Barrier
mruby implementer, C extension library writer must write a write
barrier when writing a pointer to an object on object's field.
@@ -69,6 +75,20 @@
* mrb_field_write_barrier
* mrb_write_barrier
+ == Generational Mode
+
+ mruby's GC offers an Generational Mode while re-using the tri-color GC
+ infrastructure. It will treat the Black objects as Old objects after each
+ sweep phase, instead of paint them to White. The key idea are still same as
+ the traditional generational GC:
+
+ * Minor GC - just traverse the Young objects (Gray objects) in the mark
+ phase, then only sweep the newly created objects, and leave
+ the Old objects live.
+
+ * Major GC - same as a full regular GC cycle.
+
+
For details, see the comments for each function.
*/
@@ -137,39 +157,46 @@ gettimeofday_time(void)
#endif
#ifdef GC_DEBUG
-#include <assert.h>
-#define gc_assert(expect) assert(expect)
#define DEBUG(x) (x)
#else
-#define gc_assert(expect) ((void)0)
#define DEBUG(x)
#endif
#define GC_STEP_SIZE 1024
+
void*
-mrb_realloc(mrb_state *mrb, void *p, size_t len)
+mrb_realloc_simple(mrb_state *mrb, void *p, size_t len)
{
void *p2;
p2 = (mrb->allocf)(mrb, p, len, mrb->ud);
-
if (!p2 && len > 0 && mrb->heaps) {
- mrb_garbage_collect(mrb);
+ mrb_full_gc(mrb);
p2 = (mrb->allocf)(mrb, p, len, mrb->ud);
}
+ return p2;
+}
+
+
+void*
+mrb_realloc(mrb_state *mrb, void *p, size_t len)
+{
+ void *p2;
+
+ p2 = mrb_realloc_simple(mrb, p, len);
if (!p2 && len) {
if (mrb->out_of_memory) {
/* mrb_panic(mrb); */
}
else {
- mrb->out_of_memory = 1;
+ mrb->out_of_memory = TRUE;
mrb_raise(mrb, E_RUNTIME_ERROR, "Out of memory");
}
}
else {
- mrb->out_of_memory = 0;
+ mrb->out_of_memory = FALSE;
}
return p2;
@@ -182,6 +209,12 @@ mrb_malloc(mrb_state *mrb, size_t len)
}
void*
+mrb_malloc_simple(mrb_state *mrb, size_t len)
+{
+ return mrb_realloc_simple(mrb, 0, len);
+}
+
+void*
mrb_calloc(mrb_state *mrb, size_t nelem, size_t len)
{
void *p;
@@ -195,7 +228,8 @@ mrb_calloc(mrb_state *mrb, size_t nelem, size_t len)
if (p) {
memset(p, 0, size);
}
- } else {
+ }
+ else {
p = NULL;
}
@@ -295,8 +329,8 @@ add_heap(mrb_state *mrb)
void
mrb_init_heap(mrb_state *mrb)
{
- mrb->heaps = 0;
- mrb->free_heaps = 0;
+ mrb->heaps = NULL;
+ mrb->free_heaps = NULL;
add_heap(mrb);
mrb->gc_interval_ratio = DEFAULT_GC_INTERVAL_RATIO;
mrb->gc_step_ratio = DEFAULT_GC_STEP_RATIO;
@@ -353,7 +387,7 @@ mrb_obj_alloc(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls)
static const RVALUE RVALUE_zero = { { { MRB_TT_FALSE } } };
#ifdef MRB_GC_STRESS
- mrb_garbage_collect(mrb);
+ mrb_full_gc(mrb);
#endif
if (mrb->gc_threshold < mrb->live) {
mrb_incremental_gc(mrb);
@@ -391,19 +425,29 @@ add_gray_list(mrb_state *mrb, struct RBasic *obj)
}
static void
-mark_context(mrb_state *mrb, struct mrb_context *c)
+mark_context_stack(mrb_state *mrb, struct mrb_context *c)
{
size_t i;
size_t e;
- mrb_callinfo *ci;
- /* mark stack */
e = c->stack - c->stbase;
if (c->ci) e += c->ci->nregs;
if (c->stbase + e > c->stend) e = c->stend - c->stbase;
for (i=0; i<e; i++) {
mrb_gc_mark_value(mrb, c->stbase[i]);
}
+}
+
+static void
+mark_context(mrb_state *mrb, struct mrb_context *c)
+{
+ size_t i;
+ size_t e;
+ mrb_callinfo *ci;
+
+ /* mark stack */
+ mark_context_stack(mrb, c);
+
/* mark ensure stack */
e = (c->ci) ? c->ci->eidx : 0;
for (i=0; i<e; i++) {
@@ -424,7 +468,7 @@ mark_context(mrb_state *mrb, struct mrb_context *c)
static void
gc_mark_children(mrb_state *mrb, struct RBasic *obj)
{
- gc_assert(is_gray(obj));
+ mrb_assert(is_gray(obj));
paint_black(obj);
mrb->gray_list = obj->gcnext;
mrb_gc_mark(mrb, (struct RBasic*)obj->c);
@@ -521,7 +565,7 @@ mrb_gc_mark(mrb_state *mrb, struct RBasic *obj)
{
if (obj == 0) return;
if (!is_white(obj)) return;
- gc_assert((obj)->tt != MRB_TT_FREE);
+ mrb_assert((obj)->tt != MRB_TT_FREE);
add_gray_list(mrb, obj);
}
@@ -561,7 +605,7 @@ obj_free(mrb_state *mrb, struct RBasic *obj)
if (e->cioff < 0) {
mrb_free(mrb, e->stack);
- e->stack = 0;
+ e->stack = NULL;
}
}
break;
@@ -613,12 +657,11 @@ obj_free(mrb_state *mrb, struct RBasic *obj)
static void
root_scan_phase(mrb_state *mrb)
{
- int j;
- size_t i, e;
+ size_t i, e, j;
if (!is_minor_gc(mrb)) {
- mrb->gray_list = 0;
- mrb->variable_gray_list = 0;
+ mrb->gray_list = NULL;
+ mrb->atomic_gray_list = NULL;
}
mrb_gc_mark_gv(mrb);
@@ -728,6 +771,18 @@ gc_gray_mark(mrb_state *mrb, struct RBasic *obj)
return children;
}
+
+static void
+gc_mark_gray_list(mrb_state *mrb) {
+ while (mrb->gray_list) {
+ if (is_gray(mrb->gray_list))
+ gc_mark_children(mrb, mrb->gray_list);
+ else
+ mrb->gray_list = mrb->gray_list->gcnext;
+ }
+}
+
+
static size_t
incremental_marking_phase(mrb_state *mrb, size_t limit)
{
@@ -743,22 +798,13 @@ incremental_marking_phase(mrb_state *mrb, size_t limit)
static void
final_marking_phase(mrb_state *mrb)
{
- while (mrb->gray_list) {
- if (is_gray(mrb->gray_list))
- gc_mark_children(mrb, mrb->gray_list);
- else
- mrb->gray_list = mrb->gray_list->gcnext;
- }
- gc_assert(mrb->gray_list == NULL);
- mrb->gray_list = mrb->variable_gray_list;
- mrb->variable_gray_list = 0;
- while (mrb->gray_list) {
- if (is_gray(mrb->gray_list))
- gc_mark_children(mrb, mrb->gray_list);
- else
- mrb->gray_list = mrb->gray_list->gcnext;
- }
- gc_assert(mrb->gray_list == NULL);
+ mark_context_stack(mrb, mrb->root_c);
+ gc_mark_gray_list(mrb);
+ mrb_assert(mrb->gray_list == NULL);
+ mrb->gray_list = mrb->atomic_gray_list;
+ mrb->atomic_gray_list = NULL;
+ gc_mark_gray_list(mrb);
+ mrb_assert(mrb->gray_list == NULL);
}
static void
@@ -858,17 +904,31 @@ incremental_gc(mrb_state *mrb, size_t limit)
}
default:
/* unknown state */
- gc_assert(0);
+ mrb_assert(0);
return 0;
}
}
static void
-advance_phase(mrb_state *mrb, enum gc_state to_state)
+incremental_gc_until(mrb_state *mrb, enum gc_state to_state)
{
- while (mrb->gc_state != to_state) {
+ do {
incremental_gc(mrb, ~0);
+ } while (mrb->gc_state != to_state);
+}
+
+static void
+incremental_gc_step(mrb_state *mrb)
+{
+ size_t limit = 0, result = 0;
+ limit = (GC_STEP_SIZE/100) * mrb->gc_step_ratio;
+ while (result < limit) {
+ result += incremental_gc(mrb, limit);
+ if (mrb->gc_state == GC_STATE_NONE)
+ break;
}
+
+ mrb->gc_threshold = mrb->live + GC_STEP_SIZE;
}
static void
@@ -876,15 +936,15 @@ clear_all_old(mrb_state *mrb)
{
size_t origin_mode = mrb->is_generational_gc_mode;
- gc_assert(is_generational(mrb));
+ mrb_assert(is_generational(mrb));
if (is_major_gc(mrb)) {
- advance_phase(mrb, GC_STATE_NONE);
+ incremental_gc_until(mrb, GC_STATE_NONE);
}
mrb->is_generational_gc_mode = FALSE;
prepare_incremental_sweep(mrb);
- advance_phase(mrb, GC_STATE_NONE);
- mrb->variable_gray_list = mrb->gray_list = NULL;
+ incremental_gc_until(mrb, GC_STATE_NONE);
+ mrb->atomic_gray_list = mrb->gray_list = NULL;
mrb->is_generational_gc_mode = origin_mode;
}
@@ -897,26 +957,19 @@ mrb_incremental_gc(mrb_state *mrb)
GC_TIME_START;
if (is_minor_gc(mrb)) {
- do {
- incremental_gc(mrb, ~0);
- } while (mrb->gc_state != GC_STATE_NONE);
+ incremental_gc_until(mrb, GC_STATE_NONE);
}
else {
- size_t limit = 0, result = 0;
- limit = (GC_STEP_SIZE/100) * mrb->gc_step_ratio;
- while (result < limit) {
- result += incremental_gc(mrb, limit);
- if (mrb->gc_state == GC_STATE_NONE)
- break;
- }
+ incremental_gc_step(mrb);
}
if (mrb->gc_state == GC_STATE_NONE) {
- gc_assert(mrb->live >= mrb->gc_live_after_mark);
+ mrb_assert(mrb->live >= mrb->gc_live_after_mark);
mrb->gc_threshold = (mrb->gc_live_after_mark/100) * mrb->gc_interval_ratio;
if (mrb->gc_threshold < GC_STEP_SIZE) {
mrb->gc_threshold = GC_STEP_SIZE;
}
+
if (is_major_gc(mrb)) {
mrb->majorgc_old_threshold = mrb->gc_live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO;
mrb->gc_full = FALSE;
@@ -928,28 +981,21 @@ mrb_incremental_gc(mrb_state *mrb)
}
}
}
- else {
- mrb->gc_threshold = mrb->live + GC_STEP_SIZE;
- }
-
GC_TIME_STOP_AND_REPORT;
}
+/* Perform a full gc cycle */
void
-mrb_garbage_collect(mrb_state *mrb)
+mrb_full_gc(mrb_state *mrb)
{
- size_t max_limit = ~0;
-
if (mrb->gc_disabled) return;
- GC_INVOKE_TIME_REPORT("mrb_garbage_collect()");
+ GC_INVOKE_TIME_REPORT("mrb_full_gc()");
GC_TIME_START;
if (mrb->gc_state == GC_STATE_SWEEP) {
/* finish sweep phase */
- while (mrb->gc_state != GC_STATE_NONE) {
- incremental_gc(mrb, max_limit);
- }
+ incremental_gc_until(mrb, GC_STATE_NONE);
}
/* clean all black object as old */
@@ -958,10 +1004,7 @@ mrb_garbage_collect(mrb_state *mrb)
mrb->gc_full = TRUE;
}
- do {
- incremental_gc(mrb, max_limit);
- } while (mrb->gc_state != GC_STATE_NONE);
-
+ incremental_gc_until(mrb, GC_STATE_NONE);
mrb->gc_threshold = (mrb->gc_live_after_mark/100) * mrb->gc_interval_ratio;
if (is_generational(mrb)) {
@@ -972,6 +1015,12 @@ mrb_garbage_collect(mrb_state *mrb)
GC_TIME_STOP_AND_REPORT;
}
+void
+mrb_garbage_collect(mrb_state *mrb)
+{
+ mrb_full_gc(mrb);
+}
+
int
mrb_gc_arena_save(mrb_state *mrb)
{
@@ -995,14 +1044,14 @@ mrb_field_write_barrier(mrb_state *mrb, struct RBasic *obj, struct RBasic *value
if (!is_black(obj)) return;
if (!is_white(value)) return;
- gc_assert(!is_dead(mrb, value) && !is_dead(mrb, obj));
- gc_assert(is_generational(mrb) || mrb->gc_state != GC_STATE_NONE);
+ mrb_assert(!is_dead(mrb, value) && !is_dead(mrb, obj));
+ mrb_assert(is_generational(mrb) || mrb->gc_state != GC_STATE_NONE);
if (is_generational(mrb) || mrb->gc_state == GC_STATE_MARK) {
add_gray_list(mrb, value);
}
else {
- gc_assert(mrb->gc_state == GC_STATE_SWEEP);
+ mrb_assert(mrb->gc_state == GC_STATE_SWEEP);
paint_partial_white(mrb, obj); /* for never write barriers */
}
}
@@ -1021,11 +1070,11 @@ mrb_write_barrier(mrb_state *mrb, struct RBasic *obj)
{
if (!is_black(obj)) return;
- gc_assert(!is_dead(mrb, obj));
- gc_assert(is_generational(mrb) || mrb->gc_state != GC_STATE_NONE);
+ mrb_assert(!is_dead(mrb, obj));
+ mrb_assert(is_generational(mrb) || mrb->gc_state != GC_STATE_NONE);
paint_gray(obj);
- obj->gcnext = mrb->variable_gray_list;
- mrb->variable_gray_list = obj;
+ obj->gcnext = mrb->atomic_gray_list;
+ mrb->atomic_gray_list = obj;
}
/*
@@ -1039,7 +1088,7 @@ mrb_write_barrier(mrb_state *mrb, struct RBasic *obj)
static mrb_value
gc_start(mrb_state *mrb, mrb_value obj)
{
- mrb_garbage_collect(mrb);
+ mrb_full_gc(mrb);
return mrb_nil_value();
}
@@ -1159,11 +1208,11 @@ change_gen_gc_mode(mrb_state *mrb, mrb_int enable)
{
if (is_generational(mrb) && !enable) {
clear_all_old(mrb);
- gc_assert(mrb->gc_state == GC_STATE_NONE);
+ mrb_assert(mrb->gc_state == GC_STATE_NONE);
mrb->gc_full = FALSE;
}
else if (!is_generational(mrb) && enable) {
- advance_phase(mrb, GC_STATE_NONE);
+ incremental_gc_until(mrb, GC_STATE_NONE);
mrb->majorgc_old_threshold = mrb->gc_live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO;
mrb->gc_full = FALSE;
}
@@ -1271,7 +1320,7 @@ test_mrb_field_write_barrier(void)
mrb->gc_state = GC_STATE_MARK;
mrb_field_write_barrier(mrb, obj, value);
- gc_assert(is_gray(value));
+ mrb_assert(is_gray(value));
puts(" in GC_STATE_SWEEP");
@@ -1279,8 +1328,8 @@ test_mrb_field_write_barrier(void)
mrb->gc_state = GC_STATE_SWEEP;
mrb_field_write_barrier(mrb, obj, value);
- gc_assert(obj->color & mrb->current_white_part);
- gc_assert(value->color & mrb->current_white_part);
+ mrb_assert(obj->color & mrb->current_white_part);
+ mrb_assert(value->color & mrb->current_white_part);
puts(" fail with black");
@@ -1289,7 +1338,7 @@ test_mrb_field_write_barrier(void)
paint_partial_white(mrb,value);
mrb_field_write_barrier(mrb, obj, value);
- gc_assert(obj->color & mrb->current_white_part);
+ mrb_assert(obj->color & mrb->current_white_part);
puts(" fail with gray");
@@ -1298,7 +1347,7 @@ test_mrb_field_write_barrier(void)
paint_gray(value);
mrb_field_write_barrier(mrb, obj, value);
- gc_assert(is_gray(value));
+ mrb_assert(is_gray(value));
{
@@ -1311,7 +1360,7 @@ test_mrb_field_write_barrier(void)
mrb->gc_state = GC_STATE_MARK;
mrb_field_write_barrier_value(mrb, obj, value);
- gc_assert(is_gray(mrb_basic_ptr(value)));
+ mrb_assert(is_gray(mrb_basic_ptr(value)));
}
mrb_close(mrb);
@@ -1331,15 +1380,15 @@ test_mrb_write_barrier(void)
mrb->gc_state = GC_STATE_MARK;
mrb_write_barrier(mrb, obj);
- gc_assert(is_gray(obj));
- gc_assert(mrb->variable_gray_list == obj);
+ mrb_assert(is_gray(obj));
+ mrb_assert(mrb->atomic_gray_list == obj);
puts(" fail with gray");
paint_gray(obj);
mrb_write_barrier(mrb, obj);
- gc_assert(is_gray(obj));
+ mrb_assert(is_gray(obj));
mrb_close(mrb);
}
@@ -1352,17 +1401,17 @@ test_add_gray_list(void)
puts("test_add_gray_list");
change_gen_gc_mode(mrb, FALSE);
- gc_assert(mrb->gray_list == NULL);
+ mrb_assert(mrb->gray_list == NULL);
obj1 = mrb_basic_ptr(mrb_str_new_cstr(mrb, "test"));
add_gray_list(mrb, obj1);
- gc_assert(mrb->gray_list == obj1);
- gc_assert(is_gray(obj1));
+ mrb_assert(mrb->gray_list == obj1);
+ mrb_assert(is_gray(obj1));
obj2 = mrb_basic_ptr(mrb_str_new_cstr(mrb, "test"));
add_gray_list(mrb, obj2);
- gc_assert(mrb->gray_list == obj2);
- gc_assert(mrb->gray_list->gcnext == obj1);
- gc_assert(is_gray(obj2));
+ mrb_assert(mrb->gray_list == obj2);
+ mrb_assert(mrb->gray_list->gcnext == obj1);
+ mrb_assert(is_gray(obj2));
mrb_close(mrb);
}
@@ -1381,8 +1430,8 @@ test_gc_gray_mark(void)
obj = (struct RBasic*)mrb->object_class;
paint_gray(obj);
gray_num = gc_gray_mark(mrb, obj);
- gc_assert(is_black(obj));
- gc_assert(gray_num > 1);
+ mrb_assert(is_black(obj));
+ mrb_assert(gray_num > 1);
puts(" in MRB_TT_ARRAY");
obj_v = mrb_ary_new(mrb);
@@ -1391,9 +1440,9 @@ test_gc_gray_mark(void)
paint_partial_white(mrb, mrb_basic_ptr(value_v));
mrb_ary_push(mrb, obj_v, value_v);
gray_num = gc_gray_mark(mrb, mrb_basic_ptr(obj_v));
- gc_assert(is_black(mrb_basic_ptr(obj_v)));
- gc_assert(is_gray(mrb_basic_ptr(value_v)));
- gc_assert(gray_num == 1);
+ mrb_assert(is_black(mrb_basic_ptr(obj_v)));
+ mrb_assert(is_gray(mrb_basic_ptr(value_v)));
+ mrb_assert(gray_num == 1);
mrb_close(mrb);
}
@@ -1409,16 +1458,16 @@ test_incremental_gc(void)
puts("test_incremental_gc");
change_gen_gc_mode(mrb, FALSE);
- puts(" in mrb_garbage_collect");
- mrb_garbage_collect(mrb);
+ puts(" in mrb_full_gc");
+ mrb_full_gc(mrb);
- gc_assert(mrb->gc_state == GC_STATE_NONE);
+ mrb_assert(mrb->gc_state == GC_STATE_NONE);
puts(" in GC_STATE_NONE");
incremental_gc(mrb, max);
- gc_assert(mrb->gc_state == GC_STATE_MARK);
+ mrb_assert(mrb->gc_state == GC_STATE_MARK);
puts(" in GC_STATE_MARK");
- advance_phase(mrb, GC_STATE_SWEEP);
- gc_assert(mrb->gc_state == GC_STATE_SWEEP);
+ incremental_gc_until(mrb, GC_STATE_SWEEP);
+ mrb_assert(mrb->gc_state == GC_STATE_SWEEP);
puts(" in GC_STATE_SWEEP");
page = mrb->heaps;
@@ -1438,13 +1487,13 @@ test_incremental_gc(void)
total += MRB_HEAP_PAGE_SIZE;
}
- gc_assert(mrb->gray_list == NULL);
+ mrb_assert(mrb->gray_list == NULL);
incremental_gc(mrb, max);
- gc_assert(mrb->gc_state == GC_STATE_SWEEP);
+ mrb_assert(mrb->gc_state == GC_STATE_SWEEP);
incremental_gc(mrb, max);
- gc_assert(mrb->gc_state == GC_STATE_NONE);
+ mrb_assert(mrb->gc_state == GC_STATE_NONE);
free = (RVALUE*)mrb->heaps->freelist;
while (free) {
@@ -1452,30 +1501,30 @@ test_incremental_gc(void)
free = (RVALUE*)free->as.free.next;
}
- gc_assert(mrb->live == live);
- gc_assert(mrb->live == total-freed);
+ mrb_assert(mrb->live == live);
+ mrb_assert(mrb->live == total-freed);
puts("test_incremental_gc(gen)");
- advance_phase(mrb, GC_STATE_SWEEP);
+ incremental_gc_until(mrb, GC_STATE_SWEEP);
change_gen_gc_mode(mrb, TRUE);
- gc_assert(mrb->gc_full == FALSE);
- gc_assert(mrb->gc_state == GC_STATE_NONE);
+ mrb_assert(mrb->gc_full == FALSE);
+ mrb_assert(mrb->gc_state == GC_STATE_NONE);
puts(" in minor");
- gc_assert(is_minor_gc(mrb));
- gc_assert(mrb->majorgc_old_threshold > 0);
+ mrb_assert(is_minor_gc(mrb));
+ mrb_assert(mrb->majorgc_old_threshold > 0);
mrb->majorgc_old_threshold = 0;
mrb_incremental_gc(mrb);
- gc_assert(mrb->gc_full == TRUE);
- gc_assert(mrb->gc_state == GC_STATE_NONE);
+ mrb_assert(mrb->gc_full == TRUE);
+ mrb_assert(mrb->gc_state == GC_STATE_NONE);
puts(" in major");
- gc_assert(is_major_gc(mrb));
+ mrb_assert(is_major_gc(mrb));
do {
mrb_incremental_gc(mrb);
} while (mrb->gc_state != GC_STATE_NONE);
- gc_assert(mrb->gc_full == FALSE);
+ mrb_assert(mrb->gc_full == FALSE);
mrb_close(mrb);
}
@@ -1490,12 +1539,12 @@ test_incremental_sweep_phase(void)
add_heap(mrb);
mrb->sweeps = mrb->heaps;
- gc_assert(mrb->heaps->next->next == NULL);
- gc_assert(mrb->free_heaps->next->next == NULL);
+ mrb_assert(mrb->heaps->next->next == NULL);
+ mrb_assert(mrb->free_heaps->next->next == NULL);
incremental_sweep_phase(mrb, MRB_HEAP_PAGE_SIZE*3);
- gc_assert(mrb->heaps->next == NULL);
- gc_assert(mrb->heaps == mrb->free_heaps);
+ mrb_assert(mrb->heaps->next == NULL);
+ mrb_assert(mrb->heaps == mrb->free_heaps);
mrb_close(mrb);
}
diff --git a/src/hash.c b/src/hash.c
index e31f7b3d7..1ffaed5fb 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -145,7 +145,9 @@ mrb_hash_set(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value val) /* mr
k = kh_get(ht, h, key);
if (k == kh_end(h)) {
/* expand */
+ int ai = mrb_gc_arena_save(mrb);
k = kh_put(ht, h, KEY(key));
+ mrb_gc_arena_restore(mrb, ai);
}
kh_value(h, k) = val;
@@ -169,7 +171,9 @@ mrb_hash_dup(mrb_state *mrb, mrb_value hash)
for (k = kh_begin(h); k != kh_end(h); k++) {
if (kh_exist(h,k)) {
+ int ai = mrb_gc_arena_save(mrb);
ret_k = kh_put(ht, ret_h, KEY(kh_key(h,k)));
+ mrb_gc_arena_restore(mrb, ai);
kh_val(ret_h, ret_k) = kh_val(h,k);
}
}
@@ -772,16 +776,9 @@ mrb_value
mrb_hash_empty_p(mrb_state *mrb, mrb_value self)
{
khash_t(ht) *h = RHASH_TBL(self);
- mrb_bool empty_p;
- if (h) {
- empty_p = (kh_size(h) == 0);
- }
- else {
- empty_p = 1;
- }
-
- return mrb_bool_value(empty_p);
+ if (h) return mrb_bool_value(kh_size(h) == 0);
+ return mrb_true_value();
}
static mrb_value
@@ -921,17 +918,12 @@ mrb_hash_has_keyWithKey(mrb_state *mrb, mrb_value hash, mrb_value key)
{
khash_t(ht) *h = RHASH_TBL(hash);
khiter_t k;
- mrb_bool result;
if (h) {
k = kh_get(ht, h, key);
- result = (k != kh_end(h));
- }
- else {
- result = 0;
+ return mrb_bool_value(k != kh_end(h));
}
-
- return mrb_bool_value(result);
+ return mrb_false_value();
}
/* 15.2.13.4.13 */
diff --git a/src/kernel.c b/src/kernel.c
index 4b3bed0d8..4b426c6b4 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -26,7 +26,7 @@ typedef enum {
NOEX_RESPONDS = 0x80
} mrb_method_flag_t;
-int
+mrb_bool
mrb_obj_basic_to_s_p(mrb_state *mrb, mrb_value obj)
{
struct RProc *me = mrb_method_search(mrb, mrb_class(mrb, obj), mrb_intern2(mrb, "to_s", 4));
@@ -521,7 +521,7 @@ mrb_obj_instance_eval(mrb_state *mrb, mrb_value self)
return mrb_yield_internal(mrb, b, 0, 0, self, c);
}
-int
+mrb_bool
mrb_obj_is_instance_of(mrb_state *mrb, mrb_value obj, struct RClass* c)
{
if (mrb_obj_class(mrb, obj) == c) return TRUE;
@@ -549,15 +549,40 @@ obj_is_instance_of(mrb_state *mrb, mrb_value self)
}
static void
-check_iv_name(mrb_state *mrb, mrb_sym id)
+valid_iv_name(mrb_state *mrb, mrb_sym iv_name_id, const char* s, size_t len)
+{
+ if (len < 2 || !(s[0] == '@' && s[1] != '@')) {
+ mrb_name_error(mrb, iv_name_id, "`%S' is not allowed as an instance variable name", mrb_sym2str(mrb, iv_name_id));
+ }
+}
+
+static void
+check_iv_name(mrb_state *mrb, mrb_sym iv_name_id)
{
const char *s;
size_t len;
- s = mrb_sym2name_len(mrb, id, &len);
- if (len < 2 || !(s[0] == '@' && s[1] != '@')) {
- mrb_name_error(mrb, id, "`%S' is not allowed as an instance variable name", mrb_sym2str(mrb, id));
+ s = mrb_sym2name_len(mrb, iv_name_id, &len);
+ valid_iv_name(mrb, iv_name_id, s, len);
+}
+
+static mrb_sym
+get_valid_iv_sym(mrb_state *mrb, mrb_value iv_name)
+{
+ mrb_sym iv_name_id;
+
+ mrb_assert(mrb_symbol_p(iv_name) || mrb_string_p(iv_name));
+
+ if (mrb_string_p(iv_name)) {
+ iv_name_id = mrb_intern_cstr(mrb, RSTRING_PTR(iv_name));
+ valid_iv_name(mrb, iv_name_id, RSTRING_PTR(iv_name), RSTRING_LEN(iv_name));
+ }
+ else {
+ iv_name_id = mrb_symbol(iv_name);
+ check_iv_name(mrb, iv_name_id);
}
+
+ return iv_name_id;
}
/* 15.3.1.3.20 */
@@ -582,10 +607,11 @@ mrb_value
mrb_obj_ivar_defined(mrb_state *mrb, mrb_value self)
{
mrb_sym mid;
+ mrb_value sym;
mrb_bool defined_p;
- mrb_get_args(mrb, "n", &mid);
- check_iv_name(mrb, mid);
+ mrb_get_args(mrb, "o", &sym);
+ mid = get_valid_iv_sym(mrb, sym);
defined_p = mrb_obj_iv_defined(mrb, mrb_obj_ptr(self), mid);
return mrb_bool_value(defined_p);
@@ -614,12 +640,13 @@ mrb_obj_ivar_defined(mrb_state *mrb, mrb_value self)
mrb_value
mrb_obj_ivar_get(mrb_state *mrb, mrb_value self)
{
- mrb_sym id;
+ mrb_sym iv_name_id;
+ mrb_value iv_name;
- mrb_get_args(mrb, "n", &id);
+ mrb_get_args(mrb, "o", &iv_name);
- check_iv_name(mrb, id);
- return mrb_iv_get(mrb, self, id);
+ iv_name_id = get_valid_iv_sym(mrb, iv_name);
+ return mrb_iv_get(mrb, self, iv_name_id);
}
/* 15.3.1.3.22 */
@@ -645,12 +672,13 @@ mrb_obj_ivar_get(mrb_state *mrb, mrb_value self)
mrb_value
mrb_obj_ivar_set(mrb_state *mrb, mrb_value self)
{
- mrb_sym id;
- mrb_value val;
+ mrb_sym iv_name_id;
+ mrb_value iv_name, val;
+
+ mrb_get_args(mrb, "oo", &iv_name, &val);
- mrb_get_args(mrb, "no", &id, &val);
- check_iv_name(mrb, id);
- mrb_iv_set(mrb, self, id, val);
+ iv_name_id = get_valid_iv_sym(mrb, iv_name);
+ mrb_iv_set(mrb, self, iv_name_id, val);
return val;
}
@@ -938,7 +966,7 @@ mrb_obj_remove_instance_variable(mrb_state *mrb, mrb_value self)
return val;
}
-static inline int
+static inline mrb_bool
basic_obj_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym id, int pub)
{
return mrb_respond_to(mrb, obj, id);
@@ -1101,5 +1129,5 @@ mrb_init_kernel(mrb_state *mrb)
mrb_define_method(mrb, krn, "to_s", mrb_any_to_s, MRB_ARGS_NONE()); /* 15.3.1.3.46 */
mrb_include_module(mrb, mrb->object_class, mrb->kernel_module);
- mrb_alias_method(mrb, mrb->module_class, mrb_intern(mrb, "dup"), mrb_intern(mrb, "clone"));
+ mrb_alias_method(mrb, mrb->module_class, mrb_intern2(mrb, "dup", 3), mrb_intern2(mrb, "clone", 5));
}
diff --git a/src/load.c b/src/load.c
index 62010e425..092ddbde8 100644
--- a/src/load.c
+++ b/src/load.c
@@ -187,7 +187,6 @@ read_rite_section_irep(mrb_state *mrb, const uint8_t *bin)
{
int result;
size_t sirep;
- size_t i;
uint32_t len;
uint16_t nirep;
uint16_t n;
@@ -200,14 +199,14 @@ read_rite_section_irep(mrb_state *mrb, const uint8_t *bin)
nirep = bin_to_uint16(header->nirep);
//Read Binary Data Section
- for (n = 0, i = sirep; n < nirep; n++, i++) {
+ for (n = 0; n < nirep; n++) {
result = read_rite_irep_record(mrb, bin, &len);
if (result != MRB_DUMP_OK)
goto error_exit;
bin += len;
}
- result = sirep + bin_to_uint16(header->sirep);
+ result = nirep;
error_exit:
if (result < MRB_DUMP_OK) {
irep_free(sirep, mrb);
@@ -368,7 +367,7 @@ mrb_read_irep(mrb_state *mrb, const uint8_t *bin)
bin += bin_to_uint32(section_header->section_size);
} while (memcmp(section_header->section_identify, RITE_BINARY_EOF, sizeof(section_header->section_identify)) != 0);
- return total_nirep;
+ return sirep;
}
static void
@@ -464,7 +463,6 @@ read_rite_section_irep_file(mrb_state *mrb, FILE *fp)
{
int32_t result;
size_t sirep;
- size_t i;
uint16_t nirep;
uint16_t n;
uint32_t len, buf_size;
@@ -488,7 +486,7 @@ read_rite_section_irep_file(mrb_state *mrb, FILE *fp)
}
//Read Binary Data Section
- for (n = 0, i = sirep; n < nirep; n++, i++) {
+ for (n = 0; n < nirep; n++) {
void *ptr;
if (fread(buf, record_header_size, 1, fp) == 0) {
@@ -516,7 +514,7 @@ read_rite_section_irep_file(mrb_state *mrb, FILE *fp)
goto error_exit;
}
- result = sirep + bin_to_uint16(header.sirep);
+ result = nirep;
error_exit:
if (buf) {
mrb_free(mrb, buf);
@@ -539,7 +537,9 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp)
size_t sirep;
struct rite_section_header section_header;
long fpos;
- const size_t block_size = 1 << 14;
+ size_t block_size = 1 << 14;
+ const uint8_t block_fallback_count = 4;
+ int i;
const size_t buf_size = sizeof(struct rite_binary_header);
if ((mrb == NULL) || (fp == NULL)) {
@@ -564,7 +564,10 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp)
/* verify CRC */
fpos = ftell(fp);
/* You don't need use SIZE_ERROR as block_size is enough small. */
- buf = mrb_malloc(mrb, block_size);
+ for (i = 0; i < block_fallback_count; i++,block_size >>= 1){
+ buf = mrb_malloc_simple(mrb, block_size);
+ if (buf) break;
+ }
if (!buf) {
return MRB_DUMP_GENERAL_FAILURE;
}
@@ -609,7 +612,7 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp)
fseek(fp, fpos + section_size, SEEK_SET);
} while (memcmp(section_header.section_identify, RITE_BINARY_EOF, sizeof(section_header.section_identify)) != 0);
- return total_nirep;
+ return sirep;
}
mrb_value
diff --git a/src/numeric.c b/src/numeric.c
index 91843fdf8..cfde61c8c 100644
--- a/src/numeric.c
+++ b/src/numeric.c
@@ -4,7 +4,6 @@
** See Copyright Notice in mruby.h
*/
-#include <assert.h>
#include <float.h>
#if defined(__FreeBSD__) && __FreeBSD__ < 4
# include <floatingpoint.h>
@@ -240,7 +239,8 @@ mrb_flo_to_str(mrb_state *mrb, mrb_value flo, int max_digit)
*(c++) = 'e';
if (exp > 0) {
*(c++) = '+';
- } else {
+ }
+ else {
*(c++) = '-';
exp = -exp;
}
@@ -781,7 +781,7 @@ fixdivmod(mrb_state *mrb, mrb_int x, mrb_int y, mrb_int *divp, mrb_int *modp)
{
mrb_int div, mod;
- /* TODO: add assert(y != 0) to make sure */
+ /* TODO: add mrb_assert(y != 0) to make sure */
if (y < 0) {
if (x < 0)
@@ -998,7 +998,7 @@ fix_xor(mrb_state *mrb, mrb_value x)
#define NUMERIC_SHIFT_WIDTH_MAX (sizeof(mrb_int)*CHAR_BIT-1)
static mrb_value
-lshift(mrb_state *mrb, mrb_int val, int width)
+lshift(mrb_state *mrb, mrb_int val, size_t width)
{
if (width > NUMERIC_SHIFT_WIDTH_MAX) {
mrb_raisef(mrb, E_RANGE_ERROR, "width(%S) > (%S:sizeof(mrb_int)*CHAR_BIT-1)",
@@ -1010,7 +1010,7 @@ lshift(mrb_state *mrb, mrb_int val, int width)
}
static mrb_value
-rshift(mrb_int val, int width)
+rshift(mrb_int val, size_t width)
{
if (width >= NUMERIC_SHIFT_WIDTH_MAX) {
if (val < 0) {
@@ -1253,12 +1253,14 @@ mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, int base)
if (val == 0) {
*--b = '0';
- } else if (val < 0) {
+ }
+ else if (val < 0) {
do {
*--b = mrb_digitmap[-(val % base)];
} while (val /= base);
*--b = '-';
- } else {
+ }
+ else {
do {
*--b = mrb_digitmap[(int)(val % base)];
} while (val /= base);
diff --git a/src/object.c b/src/object.c
index a2162f77f..5b2278767 100644
--- a/src/object.c
+++ b/src/object.c
@@ -5,18 +5,19 @@
*/
#include "mruby.h"
+#include "mruby/array.h"
#include "mruby/class.h"
#include "mruby/numeric.h"
#include "mruby/string.h"
#include "error.h"
-int
+mrb_bool
mrb_obj_eq(mrb_state *mrb, mrb_value v1, mrb_value v2)
{
if (mrb_type(v1) != mrb_type(v2)) return FALSE;
switch (mrb_type(v1)) {
case MRB_TT_TRUE:
- return 1;
+ return TRUE;
case MRB_TT_FALSE:
case MRB_TT_FIXNUM:
@@ -32,14 +33,14 @@ mrb_obj_eq(mrb_state *mrb, mrb_value v1, mrb_value v2)
}
}
-int
+mrb_bool
mrb_obj_equal(mrb_state *mrb, mrb_value v1, mrb_value v2)
{
/* temporary definition */
return mrb_obj_eq(mrb, v1, v2);
}
-int
+mrb_bool
mrb_equal(mrb_state *mrb, mrb_value obj1, mrb_value obj2)
{
mrb_value result;
@@ -67,7 +68,7 @@ mrb_equal(mrb_state *mrb, mrb_value obj1, mrb_value obj2)
static mrb_value
mrb_true(mrb_state *mrb, mrb_value obj)
{
- return mrb_true_value();
+ return mrb_true_value();
}
/* 15.2.4.3.5 */
@@ -171,9 +172,6 @@ true_to_s(mrb_state *mrb, mrb_value obj)
static mrb_value
true_or(mrb_state *mrb, mrb_value obj)
{
- mrb_bool obj2;
-
- mrb_get_args(mrb, "b", &obj2);
return mrb_true_value();
}
@@ -202,9 +200,6 @@ true_or(mrb_state *mrb, mrb_value obj)
static mrb_value
false_and(mrb_state *mrb, mrb_value obj)
{
- mrb_bool obj2;
-
- mrb_get_args(mrb, "b", &obj2);
return mrb_false_value();
}
@@ -302,7 +297,7 @@ convert_type(mrb_state *mrb, mrb_value val, const char *tname, const char *metho
{
mrb_sym m = 0;
- m = mrb_intern(mrb, method);
+ m = mrb_intern_cstr(mrb, method);
if (!mrb_respond_to(mrb, val, m)) {
if (raise) {
mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S into %S", val, mrb_str_new_cstr(mrb, tname));
@@ -318,18 +313,18 @@ convert_type(mrb_state *mrb, mrb_value val, const char *tname, const char *metho
mrb_value
mrb_check_to_integer(mrb_state *mrb, mrb_value val, const char *method)
{
- mrb_value v;
+ mrb_value v;
- if (mrb_type(val) == MRB_TT_FIXNUM) return val;
- v = convert_type(mrb, val, "Integer", method, FALSE);
- if (mrb_nil_p(v) || mrb_type(v) != MRB_TT_FIXNUM) {
- return mrb_nil_value();
- }
- return v;
+ if (mrb_type(val) == MRB_TT_FIXNUM) return val;
+ v = convert_type(mrb, val, "Integer", method, FALSE);
+ if (mrb_nil_p(v) || mrb_type(v) != MRB_TT_FIXNUM) {
+ return mrb_nil_value();
+ }
+ return v;
}
mrb_value
-mrb_convert_type(mrb_state *mrb, mrb_value val, mrb_int type, const char *tname, const char *method)
+mrb_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const char *tname, const char *method)
{
mrb_value v;
@@ -343,7 +338,7 @@ mrb_convert_type(mrb_state *mrb, mrb_value val, mrb_int type, const char *tname,
}
mrb_value
-mrb_check_convert_type(mrb_state *mrb, mrb_value val, mrb_int type, const char *tname, const char *method)
+mrb_check_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const char *tname, const char *method)
{
mrb_value v;
@@ -354,8 +349,8 @@ mrb_check_convert_type(mrb_state *mrb, mrb_value val, mrb_int type, const char *
}
static const struct types {
- unsigned char type;
- const char *name;
+ unsigned char type;
+ const char *name;
} builtin_types[] = {
// {MRB_TT_NIL, "nil"},
{MRB_TT_FALSE, "false"},
@@ -473,7 +468,7 @@ mrb_any_to_s(mrb_state *mrb, mrb_value obj)
* b.kind_of? M #=> true
*/
-int
+mrb_bool
mrb_obj_is_kind_of(mrb_state *mrb, mrb_value obj, struct RClass *c)
{
struct RClass *cl = mrb_class(mrb, obj);
@@ -499,21 +494,21 @@ mrb_obj_is_kind_of(mrb_state *mrb, mrb_value obj, struct RClass *c)
static mrb_value
mrb_to_integer(mrb_state *mrb, mrb_value val, const char *method)
{
- mrb_value v;
+ mrb_value v;
- if (mrb_fixnum_p(val)) return val;
- v = convert_type(mrb, val, "Integer", method, TRUE);
- if (!mrb_obj_is_kind_of(mrb, v, mrb->fixnum_class)) {
- mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S to Integer (%S#%S gives %S)",
- val, val, mrb_str_new_cstr(mrb, method), v);
- }
- return v;
+ if (mrb_fixnum_p(val)) return val;
+ v = convert_type(mrb, val, "Integer", method, TRUE);
+ if (!mrb_obj_is_kind_of(mrb, v, mrb->fixnum_class)) {
+ mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S to Integer (%S#%S gives %S)",
+ val, val, mrb_str_new_cstr(mrb, method), v);
+ }
+ return v;
}
mrb_value
mrb_to_int(mrb_state *mrb, mrb_value val)
{
- return mrb_to_integer(mrb, val, "to_int");
+ return mrb_to_integer(mrb, val, "to_int");
}
static mrb_value
@@ -529,7 +524,7 @@ mrb_convert_to_integer(mrb_state *mrb, mrb_value val, int base)
case MRB_TT_FLOAT:
if (base != 0) goto arg_error;
if (FIXABLE(mrb_float(val))) {
- break;
+ break;
}
return mrb_flo_to_fixnum(mrb, val);
@@ -545,14 +540,14 @@ string_conv:
break;
}
if (base != 0) {
- tmp = mrb_check_string_type(mrb, val);
- if (!mrb_nil_p(tmp)) goto string_conv;
- arg_error:
- mrb_raise(mrb, E_ARGUMENT_ERROR, "base specified for non string value");
+ tmp = mrb_check_string_type(mrb, val);
+ if (!mrb_nil_p(tmp)) goto string_conv;
+arg_error:
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "base specified for non string value");
}
tmp = convert_type(mrb, val, "Integer", "to_int", FALSE);
if (mrb_nil_p(tmp)) {
- return mrb_to_integer(mrb, val, "to_i");
+ return mrb_to_integer(mrb, val, "to_i");
}
return tmp;
}
@@ -560,14 +555,14 @@ string_conv:
mrb_value
mrb_Integer(mrb_state *mrb, mrb_value val)
{
- return mrb_convert_to_integer(mrb, val, 0);
+ return mrb_convert_to_integer(mrb, val, 0);
}
mrb_value
mrb_Float(mrb_state *mrb, mrb_value val)
{
if (mrb_nil_p(val)) {
- mrb_raise(mrb, E_TYPE_ERROR, "can't convert nil into Float");
+ mrb_raise(mrb, E_TYPE_ERROR, "can't convert nil into Float");
}
switch (mrb_type(val)) {
case MRB_TT_FIXNUM:
@@ -590,7 +585,7 @@ mrb_inspect(mrb_state *mrb, mrb_value obj)
return mrb_obj_as_string(mrb, mrb_funcall(mrb, obj, "inspect", 0, 0));
}
-int
+mrb_bool
mrb_eql(mrb_state *mrb, mrb_value obj1, mrb_value obj2)
{
if (mrb_obj_eq(mrb, obj1, obj2)) return TRUE;
diff --git a/src/opcode.h b/src/opcode.h
index b4f843116..f87611119 100644
--- a/src/opcode.h
+++ b/src/opcode.h
@@ -17,27 +17,27 @@
/* Ax:OP = 25: 7 */
/* A:Bz:Cz:OP = 9:14: 2: 7 */
-#define GET_OPCODE(i) ((int)(((mrb_code)(i)) & 0x7f))
-#define GETARG_A(i) ((int)((((mrb_code)(i)) >> 23) & 0x1ff))
-#define GETARG_B(i) ((int)((((mrb_code)(i)) >> 14) & 0x1ff))
-#define GETARG_C(i) ((int)((((mrb_code)(i)) >> 7) & 0x7f))
-#define GETARG_Bx(i) ((int)((((mrb_code)(i)) >> 7) & 0xffff))
-#define GETARG_sBx(i) ((int)(GETARG_Bx(i)-MAXARG_sBx))
-#define GETARG_Ax(i) ((int32_t)((((mrb_code)(i)) >> 7) & 0x1ffffff))
+#define GET_OPCODE(i) ((int)(((mrb_code)(i)) & 0x7f))
+#define GETARG_A(i) ((int)((((mrb_code)(i)) >> 23) & 0x1ff))
+#define GETARG_B(i) ((int)((((mrb_code)(i)) >> 14) & 0x1ff))
+#define GETARG_C(i) ((int)((((mrb_code)(i)) >> 7) & 0x7f))
+#define GETARG_Bx(i) ((int)((((mrb_code)(i)) >> 7) & 0xffff))
+#define GETARG_sBx(i) ((int)(GETARG_Bx(i)-MAXARG_sBx))
+#define GETARG_Ax(i) ((int32_t)((((mrb_code)(i)) >> 7) & 0x1ffffff))
#define GETARG_UNPACK_b(i,n1,n2) ((int)((((mrb_code)(i)) >> (7+(n2))) & (((1<<(n1))-1))))
#define GETARG_UNPACK_c(i,n1,n2) ((int)((((mrb_code)(i)) >> 7) & (((1<<(n2))-1))))
-#define GETARG_b(i) GETARG_UNPACK_b(i,14,2)
-#define GETARG_c(i) GETARG_UNPACK_c(i,14,2)
-
-#define MKOPCODE(op) ((op) & 0x7f)
-#define MKARG_A(c) ((mrb_code)((c) & 0x1ff) << 23)
-#define MKARG_B(c) ((mrb_code)((c) & 0x1ff) << 14)
-#define MKARG_C(c) (((c) & 0x7f) << 7)
-#define MKARG_Bx(v) ((mrb_code)((v) & 0xffff) << 7)
-#define MKARG_sBx(v) MKARG_Bx((v)+MAXARG_sBx)
-#define MKARG_Ax(v) ((mrb_code)((v) & 0x1ffffff) << 7)
+#define GETARG_b(i) GETARG_UNPACK_b(i,14,2)
+#define GETARG_c(i) GETARG_UNPACK_c(i,14,2)
+
+#define MKOPCODE(op) ((op) & 0x7f)
+#define MKARG_A(c) ((mrb_code)((c) & 0x1ff) << 23)
+#define MKARG_B(c) ((mrb_code)((c) & 0x1ff) << 14)
+#define MKARG_C(c) (((c) & 0x7f) << 7)
+#define MKARG_Bx(v) ((mrb_code)((v) & 0xffff) << 7)
+#define MKARG_sBx(v) MKARG_Bx((v)+MAXARG_sBx)
+#define MKARG_Ax(v) ((mrb_code)((v) & 0x1ffffff) << 7)
#define MKARG_PACK(b,n1,c,n2) ((((b) & ((1<<n1)-1)) << (7+n2))|(((c) & ((1<<n2)-1)) << 7))
-#define MKARG_bc(b,c) MKARG_PACK(b,14,c,2)
+#define MKARG_bc(b,c) MKARG_PACK(b,14,c,2)
#define MKOP_A(op,a) (MKOPCODE(op)|MKARG_A(a))
#define MKOP_AB(op,a,b) (MKOP_A(op,a)|MKARG_B(b))
@@ -50,98 +50,101 @@
#define MKOP_Abc(op,a,b,c) (MKOP_A(op,a)|MKARG_bc(b,c))
enum {
-OP_NOP=0,/* */
-OP_MOVE,/* A B R(A) := R(B) */
-OP_LOADL,/* A Bx R(A) := Lit(Bx) */
-OP_LOADI,/* A sBx R(A) := sBx */
-OP_LOADSYM,/* A Bx R(A) := Sym(Bx) */
-OP_LOADNIL,/* A R(A) := nil */
-OP_LOADSELF,/* A R(A) := self */
-OP_LOADT,/* A R(A) := true */
-OP_LOADF,/* A R(A) := false */
-
-OP_GETGLOBAL,/* A Bx R(A) := getglobal(Sym(Bx)) */
-OP_SETGLOBAL,/* A Bx setglobal(Sym(Bx), R(A)) */
-OP_GETSPECIAL,/*A Bx R(A) := Special[Bx] */
-OP_SETSPECIAL,/*A Bx Special[Bx] := R(A) */
-OP_GETIV,/* A Bx R(A) := ivget(Sym(Bx)) */
-OP_SETIV,/* A Bx ivset(Sym(Bx),R(A)) */
-OP_GETCV,/* A Bx R(A) := cvget(Sym(Bx)) */
-OP_SETCV,/* A Bx cvset(Sym(Bx),R(A)) */
-OP_GETCONST,/* A Bx R(A) := constget(Sym(Bx)) */
-OP_SETCONST,/* A Bx constset(Sym(Bx),R(A)) */
-OP_GETMCNST,/* A Bx R(A) := R(A)::Sym(B) */
-OP_SETMCNST,/* A Bx R(A+1)::Sym(B) := R(A) */
-OP_GETUPVAR,/* A B C R(A) := uvget(B,C) */
-OP_SETUPVAR,/* A B C uvset(B,C,R(A)) */
-
-OP_JMP,/* sBx pc+=sBx */
-OP_JMPIF,/* A sBx if R(A) pc+=sBx */
-OP_JMPNOT,/* A sBx if !R(A) pc+=sBx */
-OP_ONERR,/* sBx rescue_push(pc+sBx) */
-OP_RESCUE,/* A clear(exc); R(A) := exception (ignore when A=0) */
-OP_POPERR,/* A A.times{rescue_pop()} */
-OP_RAISE,/* A raise(R(A)) */
-OP_EPUSH,/* Bx ensure_push(SEQ[Bx]) */
-OP_EPOP,/* A A.times{ensure_pop().call} */
-
-OP_SEND,/* A B C R(A) := call(R(A),mSym(B),R(A+1),...,R(A+C)) */
-OP_SENDB,/* A B C R(A) := call(R(A),mSym(B),R(A+1),...,R(A+C),&R(A+C+1))*/
-OP_FSEND,/* A B C R(A) := fcall(R(A),mSym(B),R(A+1),...,R(A+C-1)) */
-OP_CALL,/* A B C R(A) := self.call(R(A),.., R(A+C)) */
-OP_SUPER,/* A B C R(A) := super(R(A+1),... ,R(A+C-1)) */
-OP_ARGARY,/* A Bx R(A) := argument array (16=6:1:5:4) */
-OP_ENTER,/* Ax arg setup according to flags (24=5:5:1:5:5:1:1) */
-OP_KARG,/* A B C R(A) := kdict[mSym(B)]; if C kdict.rm(mSym(B)) */
-OP_KDICT,/* A C R(A) := kdict */
-
-OP_RETURN,/* A B return R(A) (B=normal,in-block return/break) */
-OP_TAILCALL,/* A B C return call(R(A),mSym(B),*R(C)) */
-OP_BLKPUSH,/* A Bx R(A) := block (16=6:1:5:4) */
-
-OP_ADD,/* A B C R(A) := R(A)+R(A+1) (mSyms[B]=:+,C=1) */
-OP_ADDI,/* A B C R(A) := R(A)+C (mSyms[B]=:+) */
-OP_SUB,/* A B C R(A) := R(A)-R(A+1) (mSyms[B]=:-,C=1) */
-OP_SUBI,/* A B C R(A) := R(A)-C (mSyms[B]=:-) */
-OP_MUL,/* A B C R(A) := R(A)*R(A+1) (mSyms[B]=:*,C=1) */
-OP_DIV,/* A B C R(A) := R(A)/R(A+1) (mSyms[B]=:/,C=1) */
-OP_EQ,/* A B C R(A) := R(A)==R(A+1) (mSyms[B]=:==,C=1) */
-OP_LT,/* A B C R(A) := R(A)<R(A+1) (mSyms[B]=:<,C=1) */
-OP_LE,/* A B C R(A) := R(A)<=R(A+1) (mSyms[B]=:<=,C=1) */
-OP_GT,/* A B C R(A) := R(A)>R(A+1) (mSyms[B]=:>,C=1) */
-OP_GE,/* A B C R(A) := R(A)>=R(A+1) (mSyms[B]=:>=,C=1) */
-
-OP_ARRAY,/* A B C R(A) := ary_new(R(B),R(B+1)..R(B+C)) */
-OP_ARYCAT,/* A B ary_cat(R(A),R(B)) */
-OP_ARYPUSH,/* A B ary_push(R(A),R(B)) */
-OP_AREF,/* A B C R(A) := R(B)[C] */
-OP_ASET,/* A B C R(B)[C] := R(A) */
-OP_APOST,/* A B C *R(A),R(A+1)..R(A+C) := R(A) */
-
-OP_STRING,/* A Bx R(A) := str_dup(Lit(Bx)) */
-OP_STRCAT,/* A B str_cat(R(A),R(B)) */
-
-OP_HASH,/* A B C R(A) := hash_new(R(B),R(B+1)..R(B+C)) */
-OP_LAMBDA,/* A Bz Cz R(A) := lambda(SEQ[Bz],Cm) */
-OP_RANGE,/* A B C R(A) := range_new(R(B),R(B+1),C) */
-
-OP_OCLASS,/* A R(A) := ::Object */
-OP_CLASS,/* A B R(A) := newclass(R(A),mSym(B),R(A+1)) */
-OP_MODULE,/* A B R(A) := newmodule(R(A),mSym(B)) */
-OP_EXEC,/* A Bx R(A) := blockexec(R(A),SEQ[Bx]) */
-OP_METHOD,/* A B R(A).newmethod(mSym(B),R(A+1)) */
-OP_SCLASS,/* A B R(A) := R(B).singleton_class */
-OP_TCLASS,/* A R(A) := target_class */
-
-OP_DEBUG,/* A print R(A) */
-OP_STOP,/* stop VM */
-OP_ERR,/* Bx raise RuntimeError with message Lit(Bx) */
-
-OP_RSVD1,/* reserved instruction #1 */
-OP_RSVD2,/* reserved instruction #2 */
-OP_RSVD3,/* reserved instruction #3 */
-OP_RSVD4,/* reserved instruction #4 */
-OP_RSVD5,/* reserved instruction #5 */
+ /*-----------------------------------------------------------------------
+ operation code operand description
+ ------------------------------------------------------------------------*/
+ OP_NOP=0,/* */
+ OP_MOVE,/* A B R(A) := R(B) */
+ OP_LOADL,/* A Bx R(A) := Lit(Bx) */
+ OP_LOADI,/* A sBx R(A) := sBx */
+ OP_LOADSYM,/* A Bx R(A) := Sym(Bx) */
+ OP_LOADNIL,/* A R(A) := nil */
+ OP_LOADSELF,/* A R(A) := self */
+ OP_LOADT,/* A R(A) := true */
+ OP_LOADF,/* A R(A) := false */
+
+ OP_GETGLOBAL,/* A Bx R(A) := getglobal(Sym(Bx)) */
+ OP_SETGLOBAL,/* A Bx setglobal(Sym(Bx), R(A)) */
+ OP_GETSPECIAL,/*A Bx R(A) := Special[Bx] */
+ OP_SETSPECIAL,/*A Bx Special[Bx] := R(A) */
+ OP_GETIV,/* A Bx R(A) := ivget(Sym(Bx)) */
+ OP_SETIV,/* A Bx ivset(Sym(Bx),R(A)) */
+ OP_GETCV,/* A Bx R(A) := cvget(Sym(Bx)) */
+ OP_SETCV,/* A Bx cvset(Sym(Bx),R(A)) */
+ OP_GETCONST,/* A Bx R(A) := constget(Sym(Bx)) */
+ OP_SETCONST,/* A Bx constset(Sym(Bx),R(A)) */
+ OP_GETMCNST,/* A Bx R(A) := R(A)::Sym(B) */
+ OP_SETMCNST,/* A Bx R(A+1)::Sym(B) := R(A) */
+ OP_GETUPVAR,/* A B C R(A) := uvget(B,C) */
+ OP_SETUPVAR,/* A B C uvset(B,C,R(A)) */
+
+ OP_JMP,/* sBx pc+=sBx */
+ OP_JMPIF,/* A sBx if R(A) pc+=sBx */
+ OP_JMPNOT,/* A sBx if !R(A) pc+=sBx */
+ OP_ONERR,/* sBx rescue_push(pc+sBx) */
+ OP_RESCUE,/* A clear(exc); R(A) := exception (ignore when A=0) */
+ OP_POPERR,/* A A.times{rescue_pop()} */
+ OP_RAISE,/* A raise(R(A)) */
+ OP_EPUSH,/* Bx ensure_push(SEQ[Bx]) */
+ OP_EPOP,/* A A.times{ensure_pop().call} */
+
+ OP_SEND,/* A B C R(A) := call(R(A),mSym(B),R(A+1),...,R(A+C)) */
+ OP_SENDB,/* A B C R(A) := call(R(A),mSym(B),R(A+1),...,R(A+C),&R(A+C+1))*/
+ OP_FSEND,/* A B C R(A) := fcall(R(A),mSym(B),R(A+1),...,R(A+C-1)) */
+ OP_CALL,/* A B C R(A) := self.call(R(A),.., R(A+C)) */
+ OP_SUPER,/* A B C R(A) := super(R(A+1),... ,R(A+C-1)) */
+ OP_ARGARY,/* A Bx R(A) := argument array (16=6:1:5:4) */
+ OP_ENTER,/* Ax arg setup according to flags (24=5:5:1:5:5:1:1) */
+ OP_KARG,/* A B C R(A) := kdict[mSym(B)]; if C kdict.rm(mSym(B)) */
+ OP_KDICT,/* A C R(A) := kdict */
+
+ OP_RETURN,/* A B return R(A) (B=normal,in-block return/break) */
+ OP_TAILCALL,/* A B C return call(R(A),mSym(B),*R(C)) */
+ OP_BLKPUSH,/* A Bx R(A) := block (16=6:1:5:4) */
+
+ OP_ADD,/* A B C R(A) := R(A)+R(A+1) (mSyms[B]=:+,C=1) */
+ OP_ADDI,/* A B C R(A) := R(A)+C (mSyms[B]=:+) */
+ OP_SUB,/* A B C R(A) := R(A)-R(A+1) (mSyms[B]=:-,C=1) */
+ OP_SUBI,/* A B C R(A) := R(A)-C (mSyms[B]=:-) */
+ OP_MUL,/* A B C R(A) := R(A)*R(A+1) (mSyms[B]=:*,C=1) */
+ OP_DIV,/* A B C R(A) := R(A)/R(A+1) (mSyms[B]=:/,C=1) */
+ OP_EQ,/* A B C R(A) := R(A)==R(A+1) (mSyms[B]=:==,C=1) */
+ OP_LT,/* A B C R(A) := R(A)<R(A+1) (mSyms[B]=:<,C=1) */
+ OP_LE,/* A B C R(A) := R(A)<=R(A+1) (mSyms[B]=:<=,C=1) */
+ OP_GT,/* A B C R(A) := R(A)>R(A+1) (mSyms[B]=:>,C=1) */
+ OP_GE,/* A B C R(A) := R(A)>=R(A+1) (mSyms[B]=:>=,C=1) */
+
+ OP_ARRAY,/* A B C R(A) := ary_new(R(B),R(B+1)..R(B+C)) */
+ OP_ARYCAT,/* A B ary_cat(R(A),R(B)) */
+ OP_ARYPUSH,/* A B ary_push(R(A),R(B)) */
+ OP_AREF,/* A B C R(A) := R(B)[C] */
+ OP_ASET,/* A B C R(B)[C] := R(A) */
+ OP_APOST,/* A B C *R(A),R(A+1)..R(A+C) := R(A) */
+
+ OP_STRING,/* A Bx R(A) := str_dup(Lit(Bx)) */
+ OP_STRCAT,/* A B str_cat(R(A),R(B)) */
+
+ OP_HASH,/* A B C R(A) := hash_new(R(B),R(B+1)..R(B+C)) */
+ OP_LAMBDA,/* A Bz Cz R(A) := lambda(SEQ[Bz],Cm) */
+ OP_RANGE,/* A B C R(A) := range_new(R(B),R(B+1),C) */
+
+ OP_OCLASS,/* A R(A) := ::Object */
+ OP_CLASS,/* A B R(A) := newclass(R(A),mSym(B),R(A+1)) */
+ OP_MODULE,/* A B R(A) := newmodule(R(A),mSym(B)) */
+ OP_EXEC,/* A Bx R(A) := blockexec(R(A),SEQ[Bx]) */
+ OP_METHOD,/* A B R(A).newmethod(mSym(B),R(A+1)) */
+ OP_SCLASS,/* A B R(A) := R(B).singleton_class */
+ OP_TCLASS,/* A R(A) := target_class */
+
+ OP_DEBUG,/* A print R(A) */
+ OP_STOP,/* stop VM */
+ OP_ERR,/* Bx raise RuntimeError with message Lit(Bx) */
+
+ OP_RSVD1,/* reserved instruction #1 */
+ OP_RSVD2,/* reserved instruction #2 */
+ OP_RSVD3,/* reserved instruction #3 */
+ OP_RSVD4,/* reserved instruction #4 */
+ OP_RSVD5,/* reserved instruction #5 */
};
#define OP_L_STRICT 1
diff --git a/src/parse.y b/src/parse.y
index f5dbdb6fd..9a83d5cbd 100644
--- a/src/parse.y
+++ b/src/parse.y
@@ -1,6 +1,6 @@
/*
** parse.y - mruby parser
-**
+**
** See Copyright Notice in mruby.h
*/
@@ -272,7 +272,7 @@ new_scope(parser_state *p, node *body)
static node*
new_begin(parser_state *p, node *body)
{
- if (body)
+ if (body)
return list2((node*)NODE_BEGIN, body);
return cons((node*)NODE_BEGIN, 0);
}
@@ -909,7 +909,7 @@ parsing_heredoc_inf(parser_state *p)
node *nd = p->parsing_heredoc;
if (nd == NULL)
return NULL;
- /* assert(nd->car->car == NODE_HEREDOC); */
+ /* mrb_assert(nd->car->car == NODE_HEREDOC); */
return (parser_heredoc_info*)nd->car->cdr;
}
@@ -2744,7 +2744,7 @@ var_ref : variable
{
$$ = var_reference(p, $1);
}
- | keyword_nil
+ | keyword_nil
{
$$ = new_nil(p);
}
@@ -3293,7 +3293,7 @@ peek_n(parser_state *p, int c, int n)
list = push(list, (node*)(intptr_t)c0);
} while(n--);
if (p->pb) {
- p->pb = push(p->pb, (node*)list);
+ p->pb = append(p->pb, (node*)list);
}
else {
p->pb = list;
@@ -3408,7 +3408,7 @@ scan_oct(const int *start, int len, int *retlen)
const int *s = start;
int retval = 0;
- /* assert(len <= 3) */
+ /* mrb_assert(len <= 3) */
while (len-- && *s >= '0' && *s <= '7') {
retval <<= 3;
retval |= *s++ - '0';
@@ -3426,7 +3426,7 @@ scan_hex(const int *start, int len, int *retlen)
register int retval = 0;
char *tmp;
- /* assert(len <= 2) */
+ /* mrb_assert(len <= 2) */
while (len-- && *s && (tmp = (char*)strchr(hexdigit, *s))) {
retval <<= 4;
retval |= (tmp - hexdigit) & 15;
@@ -3620,12 +3620,14 @@ parse_string(parser_state *p)
tokadd(p, '\n');
}
else {
- pushback(p, c);
-
- if(type & STR_FUNC_REGEXP)
+ if (type & STR_FUNC_REGEXP) {
tokadd(p, '\\');
-
- tokadd(p, read_escape(p));
+ if (c != -1)
+ tokadd(p, c);
+ } else {
+ pushback(p, c);
+ tokadd(p, read_escape(p));
+ }
if (hinf)
hinf->line_head = FALSE;
}
@@ -3684,7 +3686,7 @@ parse_string(parser_state *p)
tokadd(p, c);
- }
+ }
tokfix(p);
p->lstate = EXPR_END;
@@ -3729,7 +3731,7 @@ parse_string(parser_state *p)
yylval.nd = new_str(p, tok(p), toklen(p));
return tSTRING;
}
-
+
static int
heredoc_identifier(parser_state *p)
@@ -4811,7 +4813,7 @@ parser_yylex(parser_state *p)
pushback(p, c);
if (last_state == EXPR_FNAME) goto gvar;
tokfix(p);
- yylval.nd = new_nth_ref(p, atoi(tok(p)));
+ yylval.nd = new_nth_ref(p, atoi(tok(p)));
return tNTH_REF;
default:
@@ -5174,7 +5176,7 @@ parser_state*
mrb_parse_file(mrb_state *mrb, FILE *f, mrbc_context *c)
{
parser_state *p;
-
+
p = mrb_parser_new(mrb);
if (!p) return 0;
p->s = p->send = NULL;
@@ -5559,7 +5561,7 @@ parser_dump(mrb_state *mrb, node *tree, int offset)
printf("NODE_CALL:\n");
parser_dump(mrb, tree->car, offset+1);
dump_prefix(offset+1);
- printf("method='%s' (%d)\n",
+ printf("method='%s' (%d)\n",
mrb_sym2name(mrb, sym(tree->cdr->car)),
(int)(intptr_t)tree->cdr->car);
tree = tree->cdr->cdr->car;
diff --git a/src/pool.c b/src/pool.c
index c992b5e53..f09df92c5 100644
--- a/src/pool.c
+++ b/src/pool.c
@@ -53,7 +53,7 @@ mrb_pool_open(mrb_state *mrb)
if (pool) {
pool->mrb = mrb;
- pool->pages = 0;
+ pool->pages = NULL;
}
return pool;
@@ -96,7 +96,7 @@ mrb_pool_alloc(mrb_pool *pool, size_t len)
struct mrb_pool_page *page;
size_t n;
- if (!pool) return 0;
+ if (!pool) return NULL;
len += ALIGN_PADDING(len);
page = pool->pages;
while (page) {
@@ -109,7 +109,7 @@ mrb_pool_alloc(mrb_pool *pool, size_t len)
page = page->next;
}
page = page_alloc(pool, len);
- if (!page) return 0;
+ if (!page) return NULL;
page->offset = len;
page->next = pool->pages;
pool->pages = page;
@@ -118,7 +118,7 @@ mrb_pool_alloc(mrb_pool *pool, size_t len)
return page->last;
}
-int
+mrb_bool
mrb_pool_can_realloc(mrb_pool *pool, void *p, size_t len)
{
struct mrb_pool_page *page;
@@ -145,7 +145,7 @@ mrb_pool_realloc(mrb_pool *pool, void *p, size_t oldlen, size_t newlen)
struct mrb_pool_page *page;
void *np;
- if (!pool) return 0;
+ if (!pool) return NULL;
oldlen += ALIGN_PADDING(oldlen);
newlen += ALIGN_PADDING(newlen);
page = pool->pages;
@@ -177,10 +177,10 @@ main(void)
mrb_pool *pool;
void *p;
- pool = mrb_pool_open(0);
+ pool = mrb_pool_open(NULL);
p = mrb_pool_alloc(pool, len);
for (i=1; i<20; i++) {
- printf("%p (len=%d) %d\n", p, len, mrb_pool_can_realloc(pool, p, len*2));
+ printf("%p (len=%d) %ud\n", p, len, mrb_pool_can_realloc(pool, p, len*2));
p = mrb_pool_realloc(pool, p, len, len*2);
len *= 2;
}
diff --git a/src/proc.c b/src/proc.c
index 5c50effaa..787a46492 100644
--- a/src/proc.c
+++ b/src/proc.c
@@ -139,7 +139,7 @@ mrb_proc_arity(mrb_state *mrb, mrb_value self)
mrb_code *iseq = mrb_proc_iseq(mrb, p);
mrb_aspec aspec = GETARG_Ax(*iseq);
int ma, ra, pa, arity;
-
+
ma = MRB_ASPEC_REQ(aspec);
ra = MRB_ASPEC_REST(aspec);
pa = MRB_ASPEC_POST(aspec);
@@ -201,8 +201,8 @@ mrb_init_proc(mrb_state *mrb)
mrb_define_method(mrb, mrb->proc_class, "arity", mrb_proc_arity, MRB_ARGS_NONE());
m = mrb_proc_new(mrb, call_irep);
- mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern(mrb, "call"), m);
- mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern(mrb, "[]"), m);
+ mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern2(mrb, "call", 4), m);
+ mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern2(mrb, "[]", 2), m);
mrb_define_class_method(mrb, mrb->kernel_module, "lambda", proc_lambda, MRB_ARGS_NONE()); /* 15.3.1.2.6 */
mrb_define_method(mrb, mrb->kernel_module, "lambda", proc_lambda, MRB_ARGS_NONE()); /* 15.3.1.3.27 */
diff --git a/src/range.c b/src/range.c
index 10a03ddb4..1d6519a6e 100644
--- a/src/range.c
+++ b/src/range.c
@@ -152,33 +152,25 @@ mrb_range_eq(mrb_state *mrb, mrb_value range)
struct RRange *rr;
struct RRange *ro;
mrb_value obj;
- mrb_bool eq_p;
mrb_get_args(mrb, "o", &obj);
- if (mrb_obj_equal(mrb, range, obj)) {
- eq_p = 1;
- }
- else if (!mrb_obj_is_instance_of(mrb, obj, mrb_obj_class(mrb, range))) { /* same class? */
- eq_p = 0;
- }
- else {
- rr = mrb_range_ptr(range);
- ro = mrb_range_ptr(obj);
- if (!mrb_obj_equal(mrb, rr->edges->beg, ro->edges->beg) ||
- !mrb_obj_equal(mrb, rr->edges->end, ro->edges->end) ||
- rr->excl != ro->excl) {
- eq_p = 0;
- }
- else {
- eq_p = 1;
- }
+ if (mrb_obj_equal(mrb, range, obj)) return mrb_true_value();
+ if (!mrb_obj_is_instance_of(mrb, obj, mrb_obj_class(mrb, range))) { /* same class? */
+ return mrb_false_value();
}
- return mrb_bool_value(eq_p);
+ rr = mrb_range_ptr(range);
+ ro = mrb_range_ptr(obj);
+ if (!mrb_bool(mrb_funcall(mrb, rr->edges->beg, "==", 1, ro->edges->beg)) ||
+ !mrb_bool(mrb_funcall(mrb, rr->edges->end, "==", 1, ro->edges->end)) ||
+ rr->excl != ro->excl) {
+ return mrb_false_value();
+ }
+ return mrb_true_value();
}
-static int
+static mrb_bool
r_le(mrb_state *mrb, mrb_value a, mrb_value b)
{
mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */
@@ -192,7 +184,7 @@ r_le(mrb_state *mrb, mrb_value a, mrb_value b)
return FALSE;
}
-static int
+static mrb_bool
r_gt(mrb_state *mrb, mrb_value a, mrb_value b)
{
mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b);
@@ -205,7 +197,7 @@ r_gt(mrb_state *mrb, mrb_value a, mrb_value b)
return FALSE;
}
-static int
+static mrb_bool
r_ge(mrb_state *mrb, mrb_value a, mrb_value b)
{
mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */
@@ -284,10 +276,10 @@ mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp,
if (beg < 0) {
beg += len;
- if (beg < 0) goto out_of_range;
+ if (beg < 0) return FALSE;
}
- if (beg > len) goto out_of_range;
+ if (beg > len) return FALSE;
if (end > len) end = len;
if (end < 0) end += len;
@@ -298,9 +290,6 @@ mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp,
*begp = beg;
*lenp = len;
return TRUE;
-
-out_of_range:
- return FALSE;
}
/* 15.2.14.4.12(x) */
@@ -385,34 +374,23 @@ range_eql(mrb_state *mrb, mrb_value range)
{
mrb_value obj;
struct RRange *r, *o;
- mrb_bool eql_p;
mrb_get_args(mrb, "o", &obj);
- if (mrb_obj_equal(mrb, range, obj)) {
- eql_p = 1;
- }
- else if (!mrb_obj_is_kind_of(mrb, obj, RANGE_CLASS)) {
- eql_p = 0;
+
+ if (mrb_obj_equal(mrb, range, obj)) return mrb_true_value();
+ if (!mrb_obj_is_kind_of(mrb, obj, RANGE_CLASS)) {
+ return mrb_false_value();
}
- else {
- r = mrb_range_ptr(range);
- if (mrb_type(obj) != MRB_TT_RANGE) {
- eql_p = 0;
- }
- else {
- o = mrb_range_ptr(obj);
- if (!mrb_eql(mrb, r->edges->beg, o->edges->beg) ||
- !mrb_eql(mrb, r->edges->end, o->edges->end) ||
- (r->excl != o->excl)) {
- eql_p = 0;
- }
- else {
- eql_p = 1;
- }
- }
+ if (mrb_type(obj) != MRB_TT_RANGE) return mrb_false_value();
+
+ r = mrb_range_ptr(range);
+ o = mrb_range_ptr(obj);
+ if (!mrb_eql(mrb, r->edges->beg, o->edges->beg) ||
+ !mrb_eql(mrb, r->edges->end, o->edges->end) ||
+ (r->excl != o->excl)) {
+ return mrb_false_value();
}
-
- return mrb_bool_value(eql_p);
+ return mrb_true_value();
}
/* 15.2.14.4.15(x) */
diff --git a/src/re.h b/src/re.h
index 5632bc399..20cd0b226 100644
--- a/src/re.h
+++ b/src/re.h
@@ -7,6 +7,7 @@
#ifndef RE_H
#define RE_H
-#define REGEXP_CLASS "Regexp"
+#define REGEXP_CLASS "Regexp"
+#define REGEXP_CLASS_CSTR_LEN 6
#endif
diff --git a/src/state.c b/src/state.c
index 34de1e45e..5dcc4a40a 100644
--- a/src/state.c
+++ b/src/state.c
@@ -21,10 +21,6 @@ inspect_main(mrb_state *mrb, mrb_value mod)
return mrb_str_new(mrb, "main", 4);
}
-#ifdef MRB_NAN_BOXING
-#include <assert.h>
-#endif
-
mrb_state*
mrb_open_allocf(mrb_allocf f, void *ud)
{
@@ -33,7 +29,7 @@ mrb_open_allocf(mrb_allocf f, void *ud)
mrb_state *mrb;
#ifdef MRB_NAN_BOXING
- assert(sizeof(void*) == 4);
+ mrb_assert(sizeof(void*) == 4);
#endif
mrb = (mrb_state *)(f)(NULL, NULL, sizeof(mrb_state), ud);
@@ -192,7 +188,7 @@ mrb_value
mrb_top_self(mrb_state *mrb)
{
if (!mrb->top_self) {
- mrb->top_self = (struct RObject*)mrb_obj_alloc(mrb, MRB_TT_OBJECT, mrb->object_class);
+ mrb->top_self = (struct RObject*)mrb_obj_alloc(mrb, MRB_TT_OBJECT, mrb->object_class);
mrb_define_singleton_method(mrb, mrb->top_self, "inspect", inspect_main, MRB_ARGS_NONE());
mrb_define_singleton_method(mrb, mrb->top_self, "to_s", inspect_main, MRB_ARGS_NONE());
}
diff --git a/src/string.c b/src/string.c
index 7cd727806..f3a788df3 100644
--- a/src/string.c
+++ b/src/string.c
@@ -74,7 +74,7 @@ mrb_str_modify(mrb_state *mrb, struct RString *s)
if (p) {
memcpy(ptr, p, len);
}
- ptr[len] = 0;
+ ptr[len] = '\0';
s->ptr = ptr;
s->aux.capa = len;
str_decref(mrb, shared);
@@ -104,10 +104,9 @@ mrb_str_resize(mrb_state *mrb, mrb_value str, mrb_int len)
mrb_str_modify(mrb, s);
slen = s->len;
if (len != slen) {
- if (slen < len || slen -len > 1024) {
- s->ptr = (char *)mrb_realloc(mrb, s->ptr, len+1);
+ if (slen < len || slen - len > 256) {
+ RESIZE_CAPA(s, len);
}
- s->aux.capa = len;
s->len = len;
s->ptr[len] = '\0'; /* sentinel */
}
@@ -261,14 +260,7 @@ mrb_str_new_cstr(mrb_state *mrb, const char *p)
len = 0;
}
- s = mrb_obj_alloc_string(mrb);
- s->ptr = (char *)mrb_malloc(mrb, len+1);
- if (p) {
- memcpy(s->ptr, p, len);
- }
- s->ptr[len] = 0;
- s->len = (mrb_int)len;
- s->aux.capa = (mrb_int)len;
+ s = str_new(mrb, p, len);
return mrb_obj_value(s);
}
@@ -406,7 +398,7 @@ mrb_str_concat(mrb_state *mrb, mrb_value self, mrb_value other)
}
memcpy(s1->ptr+s1->len, s2->ptr, s2->len);
s1->len = len;
- s1->ptr[len] = 0;
+ s1->ptr[len] = '\0';
}
/*
@@ -603,7 +595,7 @@ mrb_str_cmp_m(mrb_state *mrb, mrb_value str1)
return mrb_fixnum_value(result);
}
-static int
+static mrb_bool
str_eql(mrb_state *mrb, const mrb_value str1, const mrb_value str2)
{
const mrb_int len = RSTRING_LEN(str1);
@@ -614,7 +606,7 @@ str_eql(mrb_state *mrb, const mrb_value str1, const mrb_value str2)
return FALSE;
}
-int
+mrb_bool
mrb_str_equal(mrb_state *mrb, mrb_value str1, mrb_value str2)
{
if (mrb_obj_equal(mrb, str1, str2)) return TRUE;
@@ -2542,7 +2534,6 @@ mrb_init_string(mrb_state *mrb)
mrb_define_method(mrb, s, "*", mrb_str_times, MRB_ARGS_REQ(1)); /* 15.2.10.5.1 */
mrb_define_method(mrb, s, "<=>", mrb_str_cmp_m, MRB_ARGS_REQ(1)); /* 15.2.10.5.3 */
mrb_define_method(mrb, s, "==", mrb_str_equal_m, MRB_ARGS_REQ(1)); /* 15.2.10.5.4 */
- mrb_define_method(mrb, s, "=~", noregexp, MRB_ARGS_REQ(1)); /* 15.2.10.5.5 */
mrb_define_method(mrb, s, "[]", mrb_str_aref_m, MRB_ARGS_ANY()); /* 15.2.10.5.6 */
mrb_define_method(mrb, s, "capitalize", mrb_str_capitalize, MRB_ARGS_NONE()); /* 15.2.10.5.7 */
mrb_define_method(mrb, s, "capitalize!", mrb_str_capitalize_bang, MRB_ARGS_REQ(1)); /* 15.2.10.5.8 */
@@ -2555,26 +2546,18 @@ mrb_init_string(mrb_state *mrb)
mrb_define_method(mrb, s, "empty?", mrb_str_empty_p, MRB_ARGS_NONE()); /* 15.2.10.5.16 */
mrb_define_method(mrb, s, "eql?", mrb_str_eql, MRB_ARGS_REQ(1)); /* 15.2.10.5.17 */
- // NOTE: Regexp not implemented
- mrb_define_method(mrb, s, "gsub", noregexp, MRB_ARGS_REQ(1)); /* 15.2.10.5.18 */
- mrb_define_method(mrb, s, "gsub!", noregexp, MRB_ARGS_REQ(1)); /* 15.2.10.5.19 */
-
mrb_define_method(mrb, s, "hash", mrb_str_hash_m, MRB_ARGS_REQ(1)); /* 15.2.10.5.20 */
mrb_define_method(mrb, s, "include?", mrb_str_include, MRB_ARGS_REQ(1)); /* 15.2.10.5.21 */
mrb_define_method(mrb, s, "index", mrb_str_index_m, MRB_ARGS_ANY()); /* 15.2.10.5.22 */
mrb_define_method(mrb, s, "initialize", mrb_str_init, MRB_ARGS_REQ(1)); /* 15.2.10.5.23 */
mrb_define_method(mrb, s, "initialize_copy", mrb_str_replace, MRB_ARGS_REQ(1)); /* 15.2.10.5.24 */
mrb_define_method(mrb, s, "intern", mrb_str_intern, MRB_ARGS_NONE()); /* 15.2.10.5.25 */
- mrb_define_method(mrb, s, "match", noregexp, MRB_ARGS_REQ(1)); /* 15.2.10.5.27 */
mrb_define_method(mrb, s, "replace", mrb_str_replace, MRB_ARGS_REQ(1)); /* 15.2.10.5.28 */
mrb_define_method(mrb, s, "reverse", mrb_str_reverse, MRB_ARGS_NONE()); /* 15.2.10.5.29 */
mrb_define_method(mrb, s, "reverse!", mrb_str_reverse_bang, MRB_ARGS_NONE()); /* 15.2.10.5.30 */
mrb_define_method(mrb, s, "rindex", mrb_str_rindex_m, MRB_ARGS_ANY()); /* 15.2.10.5.31 */
- mrb_define_method(mrb, s, "scan", noregexp, MRB_ARGS_REQ(1)); /* 15.2.10.5.32 */
mrb_define_method(mrb, s, "slice", mrb_str_aref_m, MRB_ARGS_ANY()); /* 15.2.10.5.34 */
mrb_define_method(mrb, s, "split", mrb_str_split_m, MRB_ARGS_ANY()); /* 15.2.10.5.35 */
- mrb_define_method(mrb, s, "sub", noregexp, MRB_ARGS_REQ(1)); /* 15.2.10.5.36 */
- mrb_define_method(mrb, s, "sub!", noregexp, MRB_ARGS_REQ(1)); /* 15.2.10.5.37 */
mrb_define_method(mrb, s, "to_i", mrb_str_to_i, MRB_ARGS_ANY()); /* 15.2.10.5.38 */
mrb_define_method(mrb, s, "to_f", mrb_str_to_f, MRB_ARGS_NONE()); /* 15.2.10.5.39 */
diff --git a/src/symbol.c b/src/symbol.c
index c0bb48f32..c145a4a1a 100644
--- a/src/symbol.c
+++ b/src/symbol.c
@@ -251,7 +251,7 @@ sym_to_sym(mrb_state *mrb, mrb_value sym)
#endif
#define is_identchar(c) (SIGN_EXTEND_CHAR(c)!=-1&&(ISALNUM(c) || (c) == '_'))
-static int
+static mrb_bool
is_special_global_name(const char* m)
{
switch (*m) {
@@ -274,7 +274,7 @@ is_special_global_name(const char* m)
return !*m;
}
-static int
+static mrb_bool
symname_p(const char *name)
{
const char *m = name;
@@ -382,7 +382,7 @@ mrb_sym2str(mrb_state *mrb, mrb_sym sym)
size_t len;
const char *name = mrb_sym2name_len(mrb, sym, &len);
mrb_value str;
-
+
if (!name) return mrb_undef_value(); /* can't happen */
str = mrb_str_new_static(mrb, name, len);
if (symname_p(name) && strlen(name) == len) {
@@ -452,5 +452,5 @@ mrb_init_symbol(mrb_state *mrb)
mrb_define_method(mrb, sym, "to_sym", sym_to_sym, MRB_ARGS_NONE()); /* 15.2.11.3.4 */
mrb_define_method(mrb, sym, "inspect", sym_inspect, MRB_ARGS_NONE()); /* 15.2.11.3.5(x) */
mrb_define_method(mrb, sym, "<=>", sym_cmp, MRB_ARGS_REQ(1));
- mrb->init_sym = mrb_intern(mrb, "initialize");
+ mrb->init_sym = mrb_intern2(mrb, "initialize", 10);
}
diff --git a/src/variable.c b/src/variable.c
index 2610c5d7a..048b63bca 100644
--- a/src/variable.c
+++ b/src/variable.c
@@ -27,12 +27,21 @@ typedef struct segment {
struct segment *next;
} segment;
+/* Instance variable table structure */
typedef struct iv_tbl {
segment *rootseg;
size_t size;
size_t last_len;
} iv_tbl;
+/*
+ * Creates the instance variable table.
+ *
+ * Parameters
+ * mrb
+ * Returns
+ * the instance variable table.
+ */
static iv_tbl*
iv_new(mrb_state *mrb)
{
@@ -47,6 +56,15 @@ iv_new(mrb_state *mrb)
return t;
}
+/*
+ * Set the value for the symbol in the instance variable table.
+ *
+ * Parameters
+ * mrb
+ * t the instance variable table to be set in.
+ * sym the symbol to be used as the key.
+ * val the value to be set.
+ */
static void
iv_put(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value val)
{
@@ -59,7 +77,7 @@ iv_put(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value val)
while (seg) {
for (i=0; i<MRB_SEGMENT_SIZE; i++) {
mrb_sym key = seg->key[i];
- /* found room in last segment after last_len */
+ /* Found room in last segment after last_len */
if (!seg->next && i >= t->last_len) {
seg->key[i] = sym;
seg->val[i] = val;
@@ -80,7 +98,7 @@ iv_put(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value val)
seg = seg->next;
}
- /* not found */
+ /* Not found */
t->size++;
if (matched_seg) {
matched_seg->key[matched_idx] = sym;
@@ -103,6 +121,18 @@ iv_put(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value val)
return;
}
+/*
+ * Get a value for a symbol from the instance the variable table.
+ *
+ * Parameters
+ * mrb
+ * t the variable table to be searched.
+ * sym the symbol to be used as the key.
+ * vp the value pointer. Recieves the value if the specified symbol contains
+ * in the instance variable table.
+ * Returns
+ * true if the specfiyed symbol contains in the instance variable table.
+ */
static mrb_bool
iv_get(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp)
{
@@ -127,6 +157,17 @@ iv_get(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp)
return FALSE;
}
+/*
+ * Deletes the value for the symbol from the instance variable table.
+ *
+ * Parameters
+ * t the variable table to be searched.
+ * sym the symbol to be used as the key.
+ * vp the value pointer. Recieve the deleted value if the symbol contans
+ * in the instance varible table.
+ * Returns
+ * true if the specfied symbol contains in the instance variable table.
+ */
static mrb_bool
iv_del(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp)
{
@@ -916,7 +957,7 @@ mrb_const_remove(mrb_state *mrb, mrb_value mod, mrb_sym sym)
void
mrb_define_const(mrb_state *mrb, struct RClass *mod, const char *name, mrb_value v)
{
- mrb_obj_iv_set(mrb, (struct RObject*)mod, mrb_intern(mrb, name), v);
+ mrb_obj_iv_set(mrb, (struct RObject*)mod, mrb_intern_cstr(mrb, name), v);
}
void
diff --git a/src/vm.c b/src/vm.c
index 38e3cd6ed..3cdf57551 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -1,4 +1,4 @@
-/*
+ /*
** vm.c - virtual machine for mruby
**
** See Copyright Notice in mruby.h
@@ -92,12 +92,12 @@ stack_init(mrb_state *mrb)
{
struct mrb_context *c = mrb->c;
- /* assert(mrb->stack == NULL); */
+ /* mrb_assert(mrb->stack == NULL); */
c->stbase = (mrb_value *)mrb_calloc(mrb, STACK_INIT_SIZE, sizeof(mrb_value));
c->stend = c->stbase + STACK_INIT_SIZE;
c->stack = c->stbase;
- /* assert(ci == NULL); */
+ /* mrb_assert(ci == NULL); */
c->cibase = (mrb_callinfo *)mrb_calloc(mrb, CALLINFO_INIT_SIZE, sizeof(mrb_callinfo));
c->ciend = c->cibase + CALLINFO_INIT_SIZE;
c->ci = c->cibase;
@@ -174,22 +174,22 @@ uvenv(mrb_state *mrb, int up)
struct REnv *e = mrb->c->ci->proc->env;
while (up--) {
- if (!e) return 0;
+ if (!e) return NULL;
e = (struct REnv*)e->c;
}
return e;
}
-static inline int
+static inline mrb_bool
is_strict(mrb_state *mrb, struct REnv *e)
{
int cioff = e->cioff;
if (cioff >= 0 && mrb->c->cibase[cioff].proc &&
MRB_PROC_STRICT_P(mrb->c->cibase[cioff].proc)) {
- return 1;
+ return TRUE;
}
- return 0;
+ return FALSE;
}
static inline struct REnv*
@@ -279,7 +279,7 @@ ecall(mrb_state *mrb, int i)
mrb_value
mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, int argc, ...)
{
- mrb_sym mid = mrb_intern(mrb, name);
+ mrb_sym mid = mrb_intern_cstr(mrb, name);
if (argc == 0) {
return mrb_funcall_argv(mrb, self, mid, 0, 0);
@@ -544,7 +544,7 @@ void mrb_gv_val_set(mrb_state *mrb, mrb_sym sym, mrb_value val);
mrb_value
mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
{
- /* assert(mrb_proc_cfunc_p(proc)) */
+ /* mrb_assert(mrb_proc_cfunc_p(proc)) */
mrb_irep *irep = proc->body.irep;
mrb_code *pc = irep->iseq;
mrb_value *pool = irep->pool;
@@ -1261,7 +1261,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
mrb->c->stack = mrb->c->stbase + ci[1].stackidx;
if (ci[1].acc < 0 && prev_jmp) {
mrb->jmp = prev_jmp;
- longjmp(*(jmp_buf*)mrb->jmp, 1);
+ mrb_longjmp(mrb);
}
while (eidx > ci->eidx) {
ecall(mrb, --eidx);
@@ -2127,3 +2127,9 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
}
END_DISPATCH;
}
+
+void
+mrb_longjmp(mrb_state *mrb)
+{
+ longjmp(*(jmp_buf*)mrb->jmp, 1);
+}
diff --git a/tasks/mrbgem_spec.rake b/tasks/mrbgem_spec.rake
index 3363b4885..df55e749f 100644
--- a/tasks/mrbgem_spec.rake
+++ b/tasks/mrbgem_spec.rake
@@ -275,13 +275,20 @@ module MRuby
req_versions = dep[:requirements]
# check each GEM dependency against all available GEMs
+ found_dep_gem = false
each do |dep_g|
if name == dep_g.name
unless dep_g.version_ok?(req_versions)
fail "#{name} version should be #{req_versions.join(' and ')} but was '#{dep_g.version}'"
end
+
+ found_dep_gem = true
+ break
end
end
+
+ fail "The GEM '#{g.name}' depends on the GEM '#{name}' but it could not be found" unless found_dep_gem
+
end
end
end
diff --git a/tasks/mrbgems.rake b/tasks/mrbgems.rake
index 5f156c45a..d8f56f88e 100644
--- a/tasks/mrbgems.rake
+++ b/tasks/mrbgems.rake
@@ -74,9 +74,10 @@ please check the following additional licenses too:
GEMS_LEGAL
gems.map do |g|
+ authors = [g.authors].flatten.sort.join(", ")
f.puts
f.puts "GEM: #{g.name}"
- f.puts "Copyright (c) #{Time.now.year} #{g.authors}"
+ f.puts "Copyright (c) #{Time.now.year} #{authors}"
f.puts "License: #{g.licenses}"
end
end
diff --git a/tasks/mrbgems_test.rake b/tasks/mrbgems_test.rake
index 717f0d76b..1050b84bb 100644
--- a/tasks/mrbgems_test.rake
+++ b/tasks/mrbgems_test.rake
@@ -38,7 +38,7 @@ MRuby.each_target do
f.puts %Q[ }]
f.puts %Q[ mrb_const_set(mrb2, mrb_obj_value(mrb2->object_class), mrb_intern(mrb2, "GEMNAME"), mrb_str_new(mrb2, "#{g.name}", #{g.name.length}));]
- if not g.test_args.empty?
+ unless g.test_args.empty?
f.puts %Q[ test_args_hash = mrb_hash_new_capa(mrb, #{g.test_args.length}); ]
g.test_args.each do |arg_name, arg_value|
escaped_arg_name = arg_name.gsub('\\', '\\\\\\\\').gsub('"', '\"')
diff --git a/tasks/mruby_build.rake b/tasks/mruby_build.rake
index eeebd161b..ef7f06a81 100644
--- a/tasks/mruby_build.rake
+++ b/tasks/mruby_build.rake
@@ -43,7 +43,7 @@ module MRuby
end
include Rake::DSL
include LoadGems
- attr_accessor :name, :bins, :exts, :file_separator
+ attr_accessor :name, :bins, :exts, :file_separator, :build_dir
attr_reader :libmruby, :gems
COMPILERS = %w(cc cxx objc asm)
@@ -63,6 +63,7 @@ module MRuby
end
@file_separator = '/'
+ @build_dir = "#{MRUBY_ROOT}/build/#{@name}"
@cc = Command::Compiler.new(self, %w(.c))
@cxx = Command::Compiler.new(self, %w(.cc .cxx .cpp))
@objc = Command::Compiler.new(self, %w(.m))
@@ -95,10 +96,6 @@ module MRuby
MRUBY_ROOT
end
- def build_dir
- "#{MRUBY_ROOT}/build/#{self.name}"
- end
-
def mrbcfile
MRuby.targets['host'].exefile("#{MRuby.targets['host'].build_dir}/bin/mrbc")
end
diff --git a/tasks/mruby_build_commands.rake b/tasks/mruby_build_commands.rake
index 1d69fa54d..349b8717d 100644
--- a/tasks/mruby_build_commands.rake
+++ b/tasks/mruby_build_commands.rake
@@ -220,19 +220,28 @@ module MRuby
class Command::Git < Command
attr_accessor :flags
- attr_accessor :clone_options
+ attr_accessor :clone_options, :pull_options
def initialize(build)
super
@command = 'git'
@flags = []
@clone_options = "clone %{flags} %{url} %{dir}"
+ @pull_options = "pull"
end
def run_clone(dir, url, _flags = [])
_pp "GIT", url, dir.relative_path
_run clone_options, { :flags => [flags, _flags].flatten.join(' '), :url => url, :dir => filename(dir) }
end
+
+ def run_pull(dir, url)
+ root = Dir.pwd
+ Dir.chdir dir
+ _pp "GIT PULL", url, dir.relative_path
+ _run pull_options
+ Dir.chdir root
+ end
end
class Command::Mrbc < Command
@@ -250,9 +259,14 @@ module MRuby
infiles.each do |f|
_pp "MRBC", f.relative_path, nil, :indent => 2
end
- IO.popen("#{filename @command} #{@compile_options % {:funcname => funcname}} #{infiles.join(' ')}", 'r+') do |io|
+ IO.popen("#{filename @command} #{@compile_options % {:funcname => funcname}} #{filename(infiles).join(' ')}", 'r+') do |io|
out.puts io.read
end
+ # if mrbc execution fail, drop the file
+ unless $?.exitstatus
+ File.delete(out.path)
+ exit -1
+ end
end
end
diff --git a/tasks/mruby_build_gem.rake b/tasks/mruby_build_gem.rake
index 870ccfa57..24aea71ab 100644
--- a/tasks/mruby_build_gem.rake
+++ b/tasks/mruby_build_gem.rake
@@ -39,14 +39,20 @@ module MRuby
gemdir = "#{root}/mrbgems/#{params[:core]}"
elsif params[:git]
url = params[:git]
- gemdir = "build/mrbgems/#{url.match(/([-\w]+)(\.[-\w]+|)$/).to_a[1]}"
- return gemdir if File.exists?(gemdir)
+ gemdir = "#{build_dir}/mrbgems/#{url.match(/([-\w]+)(\.[-\w]+|)$/).to_a[1]}"
- options = [params[:options]] || []
- options << "--branch \"#{params[:branch]}\"" if params[:branch]
-
- FileUtils.mkdir_p "build/mrbgems"
- git.run_clone gemdir, url, options
+ if File.exists?(gemdir)
+ if $pull_gems
+ git.run_pull gemdir, url
+ else
+ gemdir
+ end
+ else
+ options = [params[:options]] || []
+ options << "--branch \"#{params[:branch]}\"" if params[:branch]
+ FileUtils.mkdir_p "#{build_dir}/mrbgems"
+ git.run_clone gemdir, url, options
+ end
else
fail "unknown gem option #{params}"
end
diff --git a/tasks/toolchains/androideabi.rake b/tasks/toolchains/androideabi.rake
index a69fd1a9d..a20027c0d 100644
--- a/tasks/toolchains/androideabi.rake
+++ b/tasks/toolchains/androideabi.rake
@@ -41,20 +41,23 @@ MRuby::Toolchain.new(:androideabi) do |conf|
end
if ANDROID_STANDALONE_TOOLCHAIN == nil then
- if RUBY_PLATFORM.include?('darwin') then
+ case RUBY_PLATFORM
+ when /cygwin|mswin|mingw|bccwin|wince|emx/i
+ HOST_PLATFORM = 'windows'
+ when /darwin/i
HOST_PLATFORM = 'darwin-x86'
- elsif RUBY_PLATFORM.include?('linux') then
+ when /x86_64-linux/i
+ HOST_PLATFORM = 'linux-x86_64'
+ when /linux/i
HOST_PLATFORM = 'linux-x86'
- elsif RUBY_PLATFORM.include?('win') then
- HOST_PLATFORM = 'windows'
else
- # Unknown host platform.
+ # Unknown host platform
end
ANDROID_TARGET_PLATFORM = ENV['ANDROID_TARGET_PLATFORM'] || DEFAULT_ANDROID_TARGET_PLATFORM
path_to_toolchain = ANDROID_NDK_HOME + '/toolchains/'
- path_to_sysroot = ANDROID_NDK_HOME + '/platforms/' + ANDROID_TARGET_PLATFORM
+ path_to_sysroot = ANDROID_NDK_HOME + '/platforms/' + ANDROID_TARGET_PLATFORM
if ANDROID_TOOLCHAIN.downcase == 'gcc' then
case ANDROID_TARGET_ARCH.downcase
when 'arch-arm', 'arm' then
diff --git a/test/t/integer.rb b/test/t/integer.rb
index 46011f94a..9b19216d9 100644
--- a/test/t/integer.rb
+++ b/test/t/integer.rb
@@ -104,6 +104,14 @@ assert('Integer#<<', '15.2.8.3.12') do
# 00010111 (23)
# = 00101110 (46)
assert_equal 23 << 1, 46
+
+ # Left Shift by a negative is Right Shift
+ assert_equal 46 << -1, 23
+
+ # Raise when shift is too large
+ assert_raise(RangeError) do
+ 2 << 128
+ end
end
assert('Integer#>>', '15.2.8.3.13') do
@@ -111,6 +119,17 @@ assert('Integer#>>', '15.2.8.3.13') do
# 00101110 (46)
# = 00010111 (23)
assert_equal 46 >> 1, 23
+
+ # Right Shift by a negative is Left Shift
+ assert_equal 23 >> -1, 46
+
+ # Don't raise on large Right Shift
+ assert_equal 23 >> 128, 0
+
+ # Raise when shift is too large
+ assert_raise(RangeError) do
+ 2 >> -128
+ end
end
assert('Integer#ceil', '15.2.8.3.14') do
diff --git a/test/t/module.rb b/test/t/module.rb
index 9d735f5da..618b57f06 100644
--- a/test/t/module.rb
+++ b/test/t/module.rb
@@ -37,6 +37,145 @@ assert('Module#append_features', '15.2.2.4.10') do
assert_equal Test4AppendFeatures2.const_get(:Const4AppendFeatures2), Test4AppendFeatures2
end
+assert('Module#attr NameError') do
+ %w[
+ foo?
+ @foo
+ @@foo
+ $foo
+ ].each do |name|
+ module NameTest; end
+
+ assert_raise(NameError) do
+ NameTest.module_eval { attr_reader name.to_sym }
+ end
+
+ assert_raise(NameError) do
+ NameTest.module_eval { attr_writer name.to_sym }
+ end
+
+ assert_raise(NameError) do
+ NameTest.module_eval { attr name.to_sym }
+ end
+
+ assert_raise(NameError) do
+ NameTest.module_eval { attr_accessor name.to_sym }
+ end
+ end
+
+end
+
+assert('Module#attr', '15.2.2.4.11') do
+ class AttrTest
+ class << self
+ attr :cattr
+ def cattr_val=(val)
+ @cattr = val
+ end
+ end
+ attr :iattr
+ def iattr_val=(val)
+ @iattr = val
+ end
+ end
+
+ test = AttrTest.new
+ assert_true AttrTest.respond_to?(:cattr)
+ assert_true test.respond_to?(:iattr)
+
+ assert_false AttrTest.respond_to?(:vattr=)
+ assert_false test.respond_to?(:iattr=)
+
+ test.iattr_val = 'test'
+ assert_equal 'test', test.iattr
+
+ AttrTest.cattr_val = 'test'
+ assert_equal 'test', AttrTest.cattr
+end
+
+assert('Module#attr_accessor', '15.2.2.4.12') do
+ class AttrTestAccessor
+ class << self
+ attr_accessor :cattr
+ end
+ attr_accessor :iattr, 'iattr2'
+ end
+
+ attr_instance = AttrTestAccessor.new
+ assert_true AttrTestAccessor.respond_to?(:cattr=)
+ assert_true attr_instance.respond_to?(:iattr=)
+ assert_true attr_instance.respond_to?(:iattr2=)
+ assert_true AttrTestAccessor.respond_to?(:cattr)
+ assert_true attr_instance.respond_to?(:iattr)
+ assert_true attr_instance.respond_to?(:iattr2)
+
+ attr_instance.iattr = 'test'
+ assert_equal 'test', attr_instance.iattr
+
+ AttrTestAccessor.cattr = 'test'
+ assert_equal 'test', AttrTestAccessor.cattr
+end
+
+assert('Module#attr_reader', '15.2.2.4.13') do
+ class AttrTestReader
+ class << self
+ attr_reader :cattr
+ def cattr_val=(val)
+ @cattr = val
+ end
+ end
+ attr_reader :iattr, 'iattr2'
+ def iattr_val=(val)
+ @iattr = val
+ end
+ end
+
+ attr_instance = AttrTestReader.new
+ assert_true AttrTestReader.respond_to?(:cattr)
+ assert_true attr_instance.respond_to?(:iattr)
+ assert_true attr_instance.respond_to?(:iattr2)
+
+ assert_false AttrTestReader.respond_to?(:cattr=)
+ assert_false attr_instance.respond_to?(:iattr=)
+ assert_false attr_instance.respond_to?(:iattr2=)
+
+ attr_instance.iattr_val = 'test'
+ assert_equal 'test', attr_instance.iattr
+
+ AttrTestReader.cattr_val = 'test'
+ assert_equal 'test', AttrTestReader.cattr
+end
+
+assert('Module#attr_writer', '15.2.2.4.14') do
+ class AttrTestWriter
+ class << self
+ attr_writer :cattr
+ def cattr_val
+ @cattr
+ end
+ end
+ attr_writer :iattr, 'iattr2'
+ def iattr_val
+ @iattr
+ end
+ end
+
+ attr_instance = AttrTestWriter.new
+ assert_true AttrTestWriter.respond_to?(:cattr=)
+ assert_true attr_instance.respond_to?(:iattr=)
+ assert_true attr_instance.respond_to?(:iattr2=)
+
+ assert_false AttrTestWriter.respond_to?(:cattr)
+ assert_false attr_instance.respond_to?(:iattr)
+ assert_false attr_instance.respond_to?(:iattr2)
+
+ attr_instance.iattr = 'test'
+ assert_equal 'test', attr_instance.iattr_val
+
+ AttrTestWriter.cattr = 'test'
+ assert_equal 'test', AttrTestWriter.cattr_val
+end
+
assert('Module#class_eval', '15.2.2.4.15') do
class Test4ClassEval
@a = 11
diff --git a/test/t/nil.rb b/test/t/nil.rb
index 99b1215e9..08d2acdf1 100644
--- a/test/t/nil.rb
+++ b/test/t/nil.rb
@@ -27,4 +27,3 @@ end
assert('NilClass#to_s', '15.2.4.3.5') do
assert_equal nil.to_s, ''
end
-
diff --git a/test/t/range.rb b/test/t/range.rb
index fdf6b415c..da25abc0e 100644
--- a/test/t/range.rb
+++ b/test/t/range.rb
@@ -12,6 +12,7 @@ end
assert('Range#==', '15.2.14.4.1') do
assert_true (1..10) == (1..10)
assert_false (1..10) == (1..100)
+ assert_true (1..10) == Range.new(1.0, 10.0)
end
assert('Range#===', '15.2.14.4.2') do
@@ -72,3 +73,10 @@ assert('Range#member?', '15.2.14.4.11') do
assert_true a.member?(5)
assert_false a.member?(20)
end
+
+assert('Range#eql?', '15.2.14.4.14') do
+ assert_true (1..10).eql? (1..10)
+ assert_false (1..10).eql? (1..100)
+ assert_false (1..10).eql? (Range.new(1.0, 10.0))
+ assert_false (1..10).eql? "1..10"
+end
diff --git a/test/t/string.rb b/test/t/string.rb
index ddae92d4a..c208835b4 100644
--- a/test/t/string.rb
+++ b/test/t/string.rb
@@ -399,12 +399,12 @@ end
assert('String#to_i', '15.2.10.5.38') do
a = ''.to_i
- b = '123456789'.to_i
+ b = '32143'.to_i
c = 'a'.to_i(16)
d = '100'.to_i(2)
assert_equal a, 0
- assert_equal b, 123456789
+ assert_equal b, 32143
assert_equal c, 10
assert_equal d, 4
end
diff --git a/travis_config.rb b/travis_config.rb
index 040b1a255..bd2939f94 100644
--- a/travis_config.rb
+++ b/travis_config.rb
@@ -3,4 +3,5 @@ MRuby::Build.new do |conf|
# include all core GEMs
conf.gembox 'full-core'
+ conf.cc.defines = %w(MRB_DEBUG)
end