Merge upstream

This commit is contained in:
Daniel Bovensiepen
2013-06-15 03:53:50 +08:00
89 changed files with 1340 additions and 765 deletions
+5
View File
@@ -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
+2 -2
View File
@@ -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.
+3 -1
View File
@@ -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.
+5 -2
View File
@@ -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
@@ -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 << ''
@@ -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'
@@ -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 << ''
+28 -2
View File
@@ -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
+24
View File
@@ -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
+38 -27
View File
@@ -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
+3 -2
View File
@@ -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;
+25 -30
View File
@@ -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])
+1 -1
View File
@@ -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);
+22 -16
View File
@@ -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
+5
View File
@@ -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
+6
View File
@@ -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"
+1 -1
View File
@@ -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
+4 -1
View File
@@ -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
+33 -2
View File
@@ -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;
}
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -1,4 +1,4 @@
MRuby::Gem::Specification.new('mruby-eval') do |spec|
spec.license = 'MIT'
spec.authors = 'mruby developers'
spec.author = 'mruby developers'
end
+1 -1
View File
@@ -1,4 +1,4 @@
MRuby::Gem::Specification.new('mruby-fiber') do |spec|
spec.license = 'MIT'
spec.authors = 'mruby developers'
spec.author = 'mruby developers'
end
+1 -1
View File
@@ -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
+1 -1
View File
@@ -1,4 +1,4 @@
MRuby::Gem::Specification.new('mruby-math') do |spec|
spec.license = 'MIT'
spec.authors = 'mruby developers'
spec.author = 'mruby developers'
end
+8 -14
View File
@@ -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
+1 -1
View File
@@ -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
+4
View File
@@ -0,0 +1,4 @@
MRuby::Gem::Specification.new('mruby-object-ext') do |spec|
spec.license = 'MIT'
spec.author = 'mruby developers'
end
+108
View File
@@ -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)
{
}
+11
View File
@@ -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
+9
View File
@@ -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
+1 -1
View File
@@ -1,4 +1,4 @@
MRuby::Gem::Specification.new('mruby-objectspace') do |spec|
spec.license = 'MIT'
spec.authors = 'mruby developers'
spec.author = 'mruby developers'
end
+1 -1
View File
@@ -1,4 +1,4 @@
MRuby::Gem::Specification.new('mruby-print') do |spec|
spec.license = 'MIT'
spec.authors = 'mruby developers'
spec.author = 'mruby developers'
end
+1 -1
View File
@@ -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
+1 -1
View File
@@ -1,4 +1,4 @@
MRuby::Gem::Specification.new('mruby-random') do |spec|
spec.license = 'MIT'
spec.authors = 'mruby developers'
spec.author = 'mruby developers'
end
+18 -13
View File
@@ -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;
}
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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);
+1 -1
View File
@@ -1,4 +1,4 @@
MRuby::Gem::Specification.new('mruby-sprintf') do |spec|
spec.license = 'MIT'
spec.authors = 'mruby developers'
spec.author = 'mruby developers'
end
-4
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -1,4 +1,4 @@
MRuby::Gem::Specification.new('mruby-struct') do |spec|
spec.license = 'MIT'
spec.authors = 'mruby developers'
spec.author = 'mruby developers'
end
+2 -3
View File
@@ -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;
+1 -1
View File
@@ -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
+1 -1
View File
@@ -1,4 +1,4 @@
MRuby::Gem::Specification.new('mruby-time') do |spec|
spec.license = 'MIT'
spec.authors = 'mruby developers'
spec.author = 'mruby developers'
end
+1 -1
View File
@@ -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 {
+4
View File
@@ -0,0 +1,4 @@
MRuby::Gem::Specification.new('mruby-toplevel-ext') do |spec|
spec.license = 'MIT'
spec.author = 'mruby developers'
end
@@ -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
@@ -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
+15 -9
View File
@@ -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)
+12
View File
@@ -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
##
+23 -47
View File
@@ -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
+2 -2
View File
@@ -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];
+70 -49
View File
@@ -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;
@@ -902,6 +910,12 @@ mrb_mod_module_eval(mrb_state *mrb, mrb_value mod)
return mrb_yield_internal(mrb, b, 0, 0, mod, c);
}
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)
{
@@ -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());
+17 -15
View File
@@ -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
+1 -1
View File
@@ -6,7 +6,7 @@
#include <limits.h>
#include <stdint.h>
#include <sys/types.h>
#include <stddef.h>
// Calculate CRC (CRC-16-CCITT)
//
+4 -5
View File
@@ -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;
}
+7 -5
View File
@@ -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);
}
}
+1
View File
@@ -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 */
+192 -143
View File
@@ -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_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_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->allocf)(mrb, p, len, mrb->ud);
if (!p2 && len > 0 && mrb->heaps) {
mrb_garbage_collect(mrb);
p2 = (mrb->allocf)(mrb, p, len, mrb->ud);
}
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;
@@ -181,6 +208,12 @@ mrb_malloc(mrb_state *mrb, size_t len)
return mrb_realloc(mrb, 0, 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)
{
@@ -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);
@@ -390,6 +424,20 @@ add_gray_list(mrb_state *mrb, struct RBasic *obj)
mrb->gray_list = obj;
}
static void
mark_context_stack(mrb_state *mrb, struct mrb_context *c)
{
size_t i;
size_t e;
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)
{
@@ -398,12 +446,8 @@ mark_context(mrb_state *mrb, struct mrb_context *c)
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]);
}
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);
}
+8 -16
View File
@@ -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));
return mrb_bool_value(k != kh_end(h));
}
else {
result = 0;
}
return mrb_bool_value(result);
return mrb_false_value();
}
/* 15.2.13.4.13 */
+47 -19
View File
@@ -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, "no", &id, &val);
check_iv_name(mrb, id);
mrb_iv_set(mrb, self, id, val);
mrb_get_args(mrb, "oo", &iv_name, &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));
}
+13 -10
View File
@@ -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
+9 -7
View File
@@ -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);
+37 -42
View File
@@ -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;
+101 -98
View File
@@ -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 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 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 */
/*-----------------------------------------------------------------------
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_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_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_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_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_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_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_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_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_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_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 */
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
+19 -17
View File
@@ -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;
+7 -7
View File
@@ -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;
}
+3 -3
View File
@@ -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 */
+30 -52
View File
@@ -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;
}
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;
}
}
}
return mrb_bool_value(eql_p);
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();
}
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_true_value();
}
/* 15.2.14.4.15(x) */
+2 -1
View File
@@ -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
+2 -6
View File
@@ -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());
}
+7 -24
View File
@@ -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 */
+4 -4
View File
@@ -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);
}
+44 -3
View File
@@ -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
+16 -10
View File
@@ -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);
}
+7
View File
@@ -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
+2 -1
View File
@@ -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
+1 -1
View File
@@ -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('"', '\"')
+2 -5
View File
@@ -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
+16 -2
View File
@@ -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
+13 -7
View File
@@ -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
+10 -7
View File
@@ -41,20 +41,23 @@ MRuby::Toolchain.new(:androideabi) do |conf|
end
if ANDROID_STANDALONE_TOOLCHAIN == nil then
if RUBY_PLATFORM.include?('darwin') then
HOST_PLATFORM = 'darwin-x86'
elsif RUBY_PLATFORM.include?('linux') then
HOST_PLATFORM = 'linux-x86'
elsif RUBY_PLATFORM.include?('win') then
case RUBY_PLATFORM
when /cygwin|mswin|mingw|bccwin|wince|emx/i
HOST_PLATFORM = 'windows'
when /darwin/i
HOST_PLATFORM = 'darwin-x86'
when /x86_64-linux/i
HOST_PLATFORM = 'linux-x86_64'
when /linux/i
HOST_PLATFORM = 'linux-x86'
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
+19
View File
@@ -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
+139
View File
@@ -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
-1
View File
@@ -27,4 +27,3 @@ end
assert('NilClass#to_s', '15.2.4.3.5') do
assert_equal nil.to_s, ''
end
+8
View File
@@ -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
+2 -2
View File
@@ -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
+1
View File
@@ -3,4 +3,5 @@ MRuby::Build.new do |conf|
# include all core GEMs
conf.gembox 'full-core'
conf.cc.defines = %w(MRB_DEBUG)
end