mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Merge upstream
This commit is contained in:
@@ -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,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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 << ''
|
||||
|
||||
@@ -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,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
@@ -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
|
||||
|
||||
@@ -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
@@ -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])
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,4 +1,4 @@
|
||||
MRuby::Gem::Specification.new('mruby-array-ext') do |spec|
|
||||
spec.license = 'MIT'
|
||||
spec.authors = 'mruby developers'
|
||||
spec.author = 'mruby developers'
|
||||
end
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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,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,4 +1,4 @@
|
||||
MRuby::Gem::Specification.new('mruby-eval') do |spec|
|
||||
spec.license = 'MIT'
|
||||
spec.authors = 'mruby developers'
|
||||
spec.author = 'mruby developers'
|
||||
end
|
||||
|
||||
@@ -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,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,4 +1,4 @@
|
||||
MRuby::Gem::Specification.new('mruby-math') do |spec|
|
||||
spec.license = 'MIT'
|
||||
spec.authors = 'mruby developers'
|
||||
spec.author = 'mruby developers'
|
||||
end
|
||||
|
||||
@@ -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,4 +1,4 @@
|
||||
MRuby::Gem::Specification.new('mruby-numeric-ext') do |spec|
|
||||
spec.license = 'MIT'
|
||||
spec.authors = 'mruby developers'
|
||||
spec.author = 'mruby developers'
|
||||
end
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
MRuby::Gem::Specification.new('mruby-object-ext') do |spec|
|
||||
spec.license = 'MIT'
|
||||
spec.author = 'mruby developers'
|
||||
end
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
@@ -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
|
||||
@@ -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,4 +1,4 @@
|
||||
MRuby::Gem::Specification.new('mruby-objectspace') do |spec|
|
||||
spec.license = 'MIT'
|
||||
spec.authors = 'mruby developers'
|
||||
spec.author = 'mruby developers'
|
||||
end
|
||||
|
||||
@@ -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,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,4 +1,4 @@
|
||||
MRuby::Gem::Specification.new('mruby-random') do |spec|
|
||||
spec.license = 'MIT'
|
||||
spec.authors = 'mruby developers'
|
||||
spec.author = 'mruby developers'
|
||||
end
|
||||
|
||||
@@ -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,4 +1,4 @@
|
||||
MRuby::Gem::Specification.new('mruby-range-ext') do |spec|
|
||||
spec.license = 'MIT'
|
||||
spec.authors = 'mruby developers'
|
||||
spec.author = 'mruby developers'
|
||||
end
|
||||
|
||||
@@ -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,4 +1,4 @@
|
||||
MRuby::Gem::Specification.new('mruby-sprintf') do |spec|
|
||||
spec.license = 'MIT'
|
||||
spec.authors = 'mruby developers'
|
||||
spec.author = 'mruby developers'
|
||||
end
|
||||
|
||||
@@ -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,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,4 +1,4 @@
|
||||
MRuby::Gem::Specification.new('mruby-struct') do |spec|
|
||||
spec.license = 'MIT'
|
||||
spec.authors = 'mruby developers'
|
||||
spec.author = 'mruby developers'
|
||||
end
|
||||
|
||||
@@ -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,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,4 +1,4 @@
|
||||
MRuby::Gem::Specification.new('mruby-time') do |spec|
|
||||
spec.license = 'MIT'
|
||||
spec.authors = 'mruby developers'
|
||||
spec.author = 'mruby developers'
|
||||
end
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <stddef.h>
|
||||
|
||||
// Calculate CRC (CRC-16-CCITT)
|
||||
//
|
||||
|
||||
+4
-5
@@ -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
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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) */
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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('"', '\"')
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -27,4 +27,3 @@ end
|
||||
assert('NilClass#to_s', '15.2.4.3.5') do
|
||||
assert_equal nil.to_s, ''
|
||||
end
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -3,4 +3,5 @@ MRuby::Build.new do |conf|
|
||||
|
||||
# include all core GEMs
|
||||
conf.gembox 'full-core'
|
||||
conf.cc.defines = %w(MRB_DEBUG)
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user