diff options
| -rw-r--r-- | Rakefile | 49 | ||||
| -rw-r--r-- | include/mrbconf.h | 47 | ||||
| -rw-r--r-- | include/mruby.h | 1 | ||||
| -rw-r--r-- | include/mruby/dump.h | 14 | ||||
| -rwxr-xr-x | minirake | 2 | ||||
| -rw-r--r-- | mrblib/mrblib.rake | 15 | ||||
| -rw-r--r-- | src/codegen.c | 321 | ||||
| -rw-r--r-- | src/dump.c | 16 | ||||
| -rw-r--r-- | src/error.c | 3 | ||||
| -rw-r--r-- | src/etc.c | 3 | ||||
| -rw-r--r-- | src/hash.c | 8 | ||||
| -rw-r--r-- | src/load.c | 24 | ||||
| -rw-r--r-- | src/mruby_core.rake | 19 | ||||
| -rw-r--r-- | src/numeric.c | 169 | ||||
| -rw-r--r-- | src/string.c | 40 | ||||
| -rw-r--r-- | src/struct.c | 10 | ||||
| -rw-r--r-- | tasks/mrbgems.rake | 5 | ||||
| -rw-r--r-- | tasks/mrbgems_test.rake | 4 | ||||
| -rw-r--r-- | tasks/mruby_build.rake | 24 | ||||
| -rw-r--r-- | tasks/mruby_build_commands.rake | 18 | ||||
| -rw-r--r-- | tasks/ruby_ext.rake | 4 | ||||
| -rw-r--r-- | tasks/toolchains/gcc.rake | 2 | ||||
| -rw-r--r-- | tasks/toolchains/vs2012.rake | 2 | ||||
| -rw-r--r-- | test/mrbtest.rake | 20 | ||||
| -rw-r--r-- | test/t/exception.rb | 28 | ||||
| -rw-r--r-- | tools/mirb/mirb.rake | 6 | ||||
| -rw-r--r-- | tools/mrbc/mrbc.rake | 6 | ||||
| -rw-r--r-- | tools/mruby/mruby.rake | 6 |
28 files changed, 485 insertions, 381 deletions
@@ -1,46 +1,47 @@ # encoding: utf-8 # Build description. # basic build file for mruby +MRUBY_ROOT = File.dirname(File.expand_path(__FILE__)) -load 'tasks/ruby_ext.rake' -load 'tasks/mruby_build.rake' -load 'tasks/mrbgem_spec.rake' +# load build systems +load "#{MRUBY_ROOT}/tasks/ruby_ext.rake" +load "#{MRUBY_ROOT}/tasks/mruby_build.rake" +load "#{MRUBY_ROOT}/tasks/mrbgem_spec.rake" -############################## -# compile flags -load 'build_config.rb' - -MRUBY_CONFIGS = ['build_config.rb'] -if ENV['MRUBY_CONFIG'] - MRUBY_CONFIGS << ENV['MRUBY_CONFIG'] - load ENV['MRUBY_CONFIG'] +# load configuration file +MRUBY_CONFIGS = ["#{MRUBY_ROOT}/build_config.rb", ENV['MRUBY_CONFIG']].compact +MRUBY_CONFIGS.each do |config| + load config unless config.empty? end +# load basic rules MRuby.each_target do |build| build.define_rules end -load 'src/mruby_core.rake' -load 'mrblib/mrblib.rake' -load 'tools/mrbc/mrbc.rake' +# load custom rules +load "#{MRUBY_ROOT}/src/mruby_core.rake" +load "#{MRUBY_ROOT}/mrblib/mrblib.rake" +load "#{MRUBY_ROOT}/tools/mrbc/mrbc.rake" + +load "#{MRUBY_ROOT}/tasks/mrbgems.rake" +load "#{MRUBY_ROOT}/tasks/libmruby.rake" +load "#{MRUBY_ROOT}/tools/mruby/mruby.rake" +load "#{MRUBY_ROOT}/tools/mirb/mirb.rake" -load 'tasks/mrbgems.rake' -load 'tasks/libmruby.rake' -load 'tools/mruby/mruby.rake' -load 'tools/mirb/mirb.rake' +load "#{MRUBY_ROOT}/tasks/mrbgems_test.rake" +load "#{MRUBY_ROOT}/test/mrbtest.rake" -load 'tasks/mrbgems_test.rake' -load 'test/mrbtest.rake' ############################## # generic build targets, rules task :default => :all depfiles = MRuby.targets['host'].bins.map do |bin| - install_path = MRuby.targets['host'].exefile("bin/#{bin}") - - file install_path => MRuby.targets['host'].exefile("build/host/bin/#{bin}") do |t| - FileUtils.rm t.name, :force => true + install_path = MRuby.targets['host'].exefile("#{MRUBY_ROOT}/bin/#{bin}") + source_path = MRuby.targets['host'].exefile("#{MRuby.targets['host'].build_dir}/bin/#{bin}") + + file install_path => source_path do |t| FileUtils.cp t.prerequisites.first, t.name end diff --git a/include/mrbconf.h b/include/mrbconf.h index b5cb58ee6..472bd12cf 100644 --- a/include/mrbconf.h +++ b/include/mrbconf.h @@ -43,59 +43,42 @@ /* page size of memory pool */ //#define POOL_PAGE_SIZE 16000 -/* -DDISABLE_XXXX to drop the feature */ +/* -DDISABLE_XXXX to drop following features */ //#define DISABLE_SPRINTF /* Kernel.sprintf method */ //#define DISABLE_MATH /* Math functions */ //#define DISABLE_TIME /* Time class */ //#define DISABLE_STRUCT /* Struct class */ //#define DISABLE_STDIO /* use of stdio */ -//#define ENABLE_DEBUG /* hooks for debugger */ -/* Now DISABLE_GEMS is added as a command line flag in Rakefile, */ -/* we do not need to set it here. */ - -#undef HAVE_UNISTD_H /* WINDOWS */ -#define HAVE_UNISTD_H /* LINUX */ +/* -DENABLE_XXXX to enable following features */ +//#define ENABLE_DEBUG /* hooks for debugger */ /* end of configuration */ #ifdef MRB_USE_FLOAT typedef float mrb_float; -# define mrb_float_to_str(buf, i) sprintf((buf), "%.7e", (i)) -# define str_to_mrb_float(buf) (mrb_float)strtof((buf),NULL) +# define mrb_float_to_str(buf, i) sprintf(buf, "%.7e", i) +# define str_to_mrb_float(buf) strtof(buf, NULL) #else typedef double mrb_float; -# define mrb_float_to_str(buf, i) sprintf((buf), "%.16e", (i)) -# define str_to_mrb_float(buf) (mrb_float)strtod((buf),NULL) +# define mrb_float_to_str(buf, i) sprintf(buf, "%.16e", i) +# define str_to_mrb_float(buf) strtod(buf, NULL) #endif -#ifdef MRB_NAN_BOXING -# ifdef MRB_INT64 +#ifdef MRB_INT64 +# ifdef MRB_NAN_BOXING # error Cannot use NaN boxing when mrb_int is 64bit # else - typedef int32_t mrb_int; -# define MRB_INT_MIN INT32_MIN -# define MRB_INT_MAX INT32_MAX -# define MRB_INT_FORMAT PRId32 -# define mrb_int_to_str(buf, i) sprintf((buf), "%" MRB_INT_FORMAT, (i)) -# define str_to_mrb_int(buf) (mrb_int)strtol((buf), NULL, 10) -# endif -#else -# ifdef MRB_INT64 typedef int64_t mrb_int; # define MRB_INT_MIN INT64_MIN # define MRB_INT_MAX INT64_MAX -# define MRB_INT_FORMAT PRId64 -# define mrb_int_to_str(buf, i) sprintf((buf), "%" MRB_INT_FORMAT, (i)) -# define str_to_mrb_int(buf) (mrb_int)strtoll((buf), NULL, 10) -# else - typedef int32_t mrb_int; -# define MRB_INT_MIN INT32_MIN -# define MRB_INT_MAX INT32_MAX -# define MRB_INT_FORMAT PRId32 -# define mrb_int_to_str(buf, i) sprintf((buf), "%" MRB_INT_FORMAT, (i)) -# define str_to_mrb_int(buf) (mrb_int)strtol((buf), NULL, 10) +# define str_to_mrb_int(buf) strtoll(buf, NULL, 10) # endif +#else + typedef int32_t mrb_int; +# define MRB_INT_MIN INT32_MIN +# define MRB_INT_MAX INT32_MAX +# define str_to_mrb_int(buf) strtol(buf, NULL, 10) #endif typedef short mrb_sym; diff --git a/include/mruby.h b/include/mruby.h index e10be59fe..61df6e9ed 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -272,7 +272,6 @@ mrb_value mrb_obj_clone(mrb_state *mrb, mrb_value self); mrb_value mrb_exc_new(mrb_state *mrb, struct RClass *c, const char *ptr, long len); void mrb_exc_raise(mrb_state *mrb, mrb_value exc); -int mrb_block_given_p(void); void mrb_raise(mrb_state *mrb, struct RClass *c, const char *msg); void mrb_raisef(mrb_state *mrb, struct RClass *c, const char *fmt, ...); void mrb_warn(const char *fmt, ...); diff --git a/include/mruby/dump.h b/include/mruby/dump.h index 650651a7e..eb8fe55dd 100644 --- a/include/mruby/dump.h +++ b/include/mruby/dump.h @@ -12,16 +12,22 @@ extern "C" { #endif #include "mruby.h" +#ifdef ENABLE_STDIO #include <stdio.h> +#endif #include <stdint.h> +#ifdef ENABLE_STDIO int mrb_dump_irep(mrb_state*,int,FILE*); -int mrb_read_irep(mrb_state*,const char*); +int mrb_bdump_irep(mrb_state *mrb, int n, FILE *f,const char *initname); + int mrb_read_irep_file(mrb_state*,FILE*); -/* mrb_value mrb_load_irep(mrb_state*,const char*); */ /* declared in <irep.h> */ -mrb_value mrb_load_irep_file(mrb_state*,FILE*); +#endif +int mrb_read_irep(mrb_state*,const char*); -int mrb_bdump_irep(mrb_state *mrb, int n, FILE *f,const char *initname); +#ifdef ENABLE_STDIO +mrb_value mrb_load_irep_file(mrb_state*,FILE*); +#endif /* dump type */ #define DUMP_TYPE_CODE 0 @@ -237,7 +237,7 @@ module MiniRake # Time stamp for file task. def timestamp - File.new(name.to_s).mtime + File::stat(name.to_s).mtime end end diff --git a/mrblib/mrblib.rake b/mrblib/mrblib.rake index 5b4070745..3cd66d0d5 100644 --- a/mrblib/mrblib.rake +++ b/mrblib/mrblib.rake @@ -1,14 +1,17 @@ MRuby.each_target do - dir = File.dirname(__FILE__).relative_path_from(root) - self.libmruby << objfile("#{build_dir}/#{dir}/mrblib") + current_dir = File.dirname(__FILE__).relative_path_from(Dir.pwd) + relative_from_root = File.dirname(__FILE__).relative_path_from(MRUBY_ROOT) + current_build_dir = "#{build_dir}/#{relative_from_root}" + + self.libmruby << objfile("#{current_build_dir}/mrblib") - file objfile("#{build_dir}/#{dir}/mrblib") => "#{build_dir}/#{dir}/mrblib.c" - file "#{build_dir}/#{dir}/mrblib.c" => [mrbcfile] + Dir.glob("#{dir}/*.rb") do |t| + file objfile("#{current_build_dir}/mrblib") => "#{current_build_dir}/mrblib.c" + file "#{current_build_dir}/mrblib.c" => [mrbcfile] + Dir.glob("#{current_dir}/*.rb") do |t| mrbc_, *rbfiles = t.prerequisites FileUtils.mkdir_p File.dirname(t.name) open(t.name, 'w') do |f| - _pp "GEN", "*.rb", "#{t.name}" - f.puts File.read("#{dir}/init_mrblib.c") + _pp "GEN", "*.rb", "#{t.name.relative_path}" + f.puts File.read("#{current_dir}/init_mrblib.c") mrbc.run f, rbfiles, 'mrblib_irep' end end diff --git a/src/codegen.c b/src/codegen.c index 8cb571a28..d3239259b 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -168,8 +168,8 @@ genop_peep(codegen_scope *s, mrb_code i, int val) switch (c1) { case OP_MOVE: if (GETARG_A(i) == GETARG_B(i)) { - /* skip useless OP_MOVE */ - return; + /* skip useless OP_MOVE */ + return; } if (val) break; switch (c0) { @@ -178,10 +178,10 @@ genop_peep(codegen_scope *s, mrb_code i, int val) /* skip swapping OP_MOVE */ return; } - if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) { - s->iseq[s->pc-1] = MKOP_AB(OP_MOVE, GETARG_A(i), GETARG_B(i0)); - return; - } + if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) { + s->iseq[s->pc-1] = MKOP_AB(OP_MOVE, GETARG_A(i), GETARG_B(i0)); + return; + } break; case OP_LOADI: if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) { @@ -229,7 +229,7 @@ genop_peep(codegen_scope *s, mrb_code i, int val) } break; default: - break; + break; } break; case OP_SETIV: @@ -269,33 +269,33 @@ genop_peep(codegen_scope *s, mrb_code i, int val) case OP_RETURN: switch (c0) { case OP_RETURN: - return; + return; case OP_MOVE: - s->iseq[s->pc-1] = MKOP_AB(OP_RETURN, GETARG_B(i0), OP_R_NORMAL); - return; + s->iseq[s->pc-1] = MKOP_AB(OP_RETURN, GETARG_B(i0), OP_R_NORMAL); + return; case OP_LOADI: - s->iseq[s->pc-1] = MKOP_AsBx(OP_LOADI, 0, GETARG_sBx(i0)); - genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL)); - return; + s->iseq[s->pc-1] = MKOP_AsBx(OP_LOADI, 0, GETARG_sBx(i0)); + genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL)); + return; case OP_ARRAY: case OP_HASH: case OP_RANGE: case OP_AREF: case OP_GETUPVAR: - s->iseq[s->pc-1] = MKOP_ABC(c0, 0, GETARG_B(i0), GETARG_C(i0)); - genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL)); - return; + s->iseq[s->pc-1] = MKOP_ABC(c0, 0, GETARG_B(i0), GETARG_C(i0)); + genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL)); + return; case OP_SETIV: case OP_SETCV: case OP_SETCONST: case OP_SETMCNST: case OP_SETUPVAR: case OP_SETGLOBAL: - s->pc--; - genop_peep(s, i0, NOVAL); - i0 = s->iseq[s->pc-1]; - genop(s, MKOP_AB(OP_RETURN, GETARG_A(i0), OP_R_NORMAL)); - return; + s->pc--; + genop_peep(s, i0, NOVAL); + i0 = s->iseq[s->pc-1]; + genop(s, MKOP_AB(OP_RETURN, GETARG_A(i0), OP_R_NORMAL)); + return; case OP_LOADSYM: case OP_GETGLOBAL: case OP_GETIV: @@ -304,37 +304,37 @@ genop_peep(codegen_scope *s, mrb_code i, int val) case OP_GETSPECIAL: case OP_LOADL: case OP_STRING: - s->iseq[s->pc-1] = MKOP_ABx(c0, 0, GETARG_Bx(i0)); - genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL)); - return; + s->iseq[s->pc-1] = MKOP_ABx(c0, 0, GETARG_Bx(i0)); + genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL)); + return; case OP_SCLASS: - s->iseq[s->pc-1] = MKOP_AB(c0, GETARG_A(i), GETARG_B(i0)); - genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL)); - return; + s->iseq[s->pc-1] = MKOP_AB(c0, GETARG_A(i), GETARG_B(i0)); + genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL)); + return; case OP_LOADNIL: case OP_LOADSELF: case OP_LOADT: case OP_LOADF: case OP_OCLASS: - s->iseq[s->pc-1] = MKOP_A(c0, 0); - genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL)); - return; + s->iseq[s->pc-1] = MKOP_A(c0, 0); + genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL)); + return; default: - break; + break; } break; case OP_ADD: case OP_SUB: if (c0 == OP_LOADI) { - int c = GETARG_sBx(i0); - - if (c1 == OP_SUB) c = -c; - if (c > 127 || c < -127) break; - if (0 <= c) - s->iseq[s->pc-1] = MKOP_ABC(OP_ADDI, GETARG_A(i), GETARG_B(i), c); - else - s->iseq[s->pc-1] = MKOP_ABC(OP_SUBI, GETARG_A(i), GETARG_B(i), -c); - return; + int c = GETARG_sBx(i0); + + if (c1 == OP_SUB) c = -c; + if (c > 127 || c < -127) break; + if (0 <= c) + s->iseq[s->pc-1] = MKOP_ABC(OP_ADDI, GETARG_A(i), GETARG_B(i), c); + else + s->iseq[s->pc-1] = MKOP_ABC(OP_SUBI, GETARG_A(i), GETARG_B(i), -c); + return; } default: break; @@ -419,7 +419,7 @@ new_lit(codegen_scope *s, mrb_value val) } s->irep->pool[s->irep->plen] = val; i = s->irep->plen++; - + return i; } @@ -681,33 +681,33 @@ gen_values(codegen_scope *s, node *t, int val) while (t) { if ((intptr_t)t->car->car == NODE_SPLAT) { // splat mode if (val) { - pop_n(n); - genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), n)); - push(); - codegen(s, t->car, VAL); - pop(); pop(); - genop(s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1)); - t = t->cdr; - while (t) { - push(); - codegen(s, t->car, VAL); - pop(); pop(); - if ((intptr_t)t->car->car == NODE_SPLAT) { - genop(s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1)); - } - else { - genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1)); - } - t = t->cdr; - } + pop_n(n); + genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), n)); + push(); + codegen(s, t->car, VAL); + pop(); pop(); + genop(s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1)); + t = t->cdr; + while (t) { + push(); + codegen(s, t->car, VAL); + pop(); pop(); + if ((intptr_t)t->car->car == NODE_SPLAT) { + genop(s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1)); + } + else { + genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1)); + } + t = t->cdr; + } } else { - codegen(s, t->car->cdr, NOVAL); - t = t->cdr; - while (t) { - codegen(s, t->car, NOVAL); - t = t->cdr; - } + codegen(s, t->car->cdr, NOVAL); + t = t->cdr; + while (t) { + codegen(s, t->car, NOVAL); + t = t->cdr; + } } return -1; } @@ -792,11 +792,11 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val) } else { if (sendv) n = CALL_MAXARGS; - if (blk > 0) { /* no block */ - genop(s, MKOP_ABC(OP_SEND, cursp(), idx, n)); + if (blk > 0) { /* no block */ + genop(s, MKOP_ABC(OP_SEND, cursp(), idx, n)); } else { - genop(s, MKOP_ABC(OP_SENDB, cursp(), idx, n)); + genop(s, MKOP_ABC(OP_SENDB, cursp(), idx, n)); } } } @@ -947,9 +947,9 @@ readint_float(codegen_scope *s, const char *p, int base) c = tolower((unsigned char)c); for (n=0; n<base; n++) { if (mrb_digitmap[n] == c) { - f *= base; - f += n; - break; + f *= base; + f += n; + break; } } if (n == base) { @@ -973,7 +973,7 @@ readint_mrb_int(codegen_scope *s, const char *p, int base, int neg, int *overflo c = tolower((unsigned char)c); for (n=0; n<base; n++) { if (mrb_digitmap[n] == c) { - break; + break; } } if (n == base) { @@ -1034,7 +1034,7 @@ codegen(codegen_scope *s, node *tree, int val) lp->pc1 = onerr; if (tree->car) { codegen(s, tree->car, val); - if (val) pop(); + if (val) pop(); } lp->type = LOOP_RESCUE; noexc = new_label(s); @@ -1083,6 +1083,7 @@ codegen(codegen_scope *s, node *tree, int val) } if (n3->cdr->cdr->car) { codegen(s, n3->cdr->cdr->car, val); + if (val) pop(); } tmp = new_label(s); genop(s, MKOP_sBx(OP_JMP, exend)); @@ -1102,6 +1103,9 @@ codegen(codegen_scope *s, node *tree, int val) if (tree->car) { codegen(s, tree->car, val); } + else if (val) { + push(); + } dispatch_linked(s, exend); loop_pop(s, NOVAL); } @@ -1166,16 +1170,16 @@ codegen(codegen_scope *s, node *tree, int val) else { if (val) { pop(); - pos2 = new_label(s); - genop(s, MKOP_sBx(OP_JMP, 0)); - dispatch(s, pos1); + pos2 = new_label(s); + genop(s, MKOP_sBx(OP_JMP, 0)); + dispatch(s, pos1); genop(s, MKOP_A(OP_LOADNIL, cursp())); - dispatch(s, pos2); + dispatch(s, pos2); push(); } - else { - dispatch(s, pos1); - } + else { + dispatch(s, pos1); + } } } break; @@ -1268,8 +1272,8 @@ codegen(codegen_scope *s, node *tree, int val) genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern(s->mrb, "===")), 1)); } else { - pop(); - } + pop(); + } tmp = new_label(s); genop(s, MKOP_AsBx(OP_JMPIF, cursp(), pos2)); pos2 = tmp; @@ -1281,7 +1285,7 @@ codegen(codegen_scope *s, node *tree, int val) dispatch_linked(s, pos2); } codegen(s, tree->car->cdr, val); - if (val) pop(); + if (val) pop(); tmp = new_label(s); genop(s, MKOP_sBx(OP_JMP, pos3)); pos3 = tmp; @@ -1289,8 +1293,8 @@ codegen(codegen_scope *s, node *tree, int val) tree = tree->cdr; } if (val) { - genop(s, MKOP_A(OP_LOADNIL, cursp())); - push(); + genop(s, MKOP_A(OP_LOADNIL, cursp())); + push(); } if (pos3) dispatch_linked(s, pos3); } @@ -1353,7 +1357,7 @@ codegen(codegen_scope *s, node *tree, int val) n = gen_values(s, tree, val); if (n >= 0) { if (val) { - pop_n(n); + pop_n(n); genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), n)); push(); } @@ -1375,7 +1379,7 @@ codegen(codegen_scope *s, node *tree, int val) tree = tree->cdr; } if (val) { - pop_n(len*2); + pop_n(len*2); genop(s, MKOP_ABC(OP_HASH, cursp(), cursp(), len)); push(); } @@ -1465,18 +1469,18 @@ codegen(codegen_scope *s, node *tree, int val) codegen(s, tree->car, VAL); if (len == 2 && - ((name[0] == '|' && name[1] == '|') || - (name[0] == '&' && name[1] == '&'))) { - int pos; - - pop(); - pos = new_label(s); - genop(s, MKOP_AsBx(name[0] == '|' ? OP_JMPIF : OP_JMPNOT, cursp(), 0)); - codegen(s, tree->cdr->cdr->car, VAL); - pop(); - gen_assignment(s, tree->car, cursp(), val); - dispatch(s, pos); - break; + ((name[0] == '|' && name[1] == '|') || + (name[0] == '&' && name[1] == '&'))) { + int pos; + + pop(); + pos = new_label(s); + genop(s, MKOP_AsBx(name[0] == '|' ? OP_JMPIF : OP_JMPNOT, cursp(), 0)); + codegen(s, tree->cdr->cdr->car, VAL); + pop(); + gen_assignment(s, tree->car, cursp(), val); + dispatch(s, pos); + break; } codegen(s, tree->cdr->cdr->car, VAL); pop(); pop(); @@ -1501,7 +1505,7 @@ codegen(codegen_scope *s, node *tree, int val) genop(s, MKOP_ABC(OP_GE, cursp(), idx, 1)); } else { - genop(s, MKOP_ABC(OP_SEND, cursp(), idx, 1)); + genop(s, MKOP_ABC(OP_SEND, cursp(), idx, 1)); } } gen_assignment(s, tree->car, cursp(), val); @@ -1511,16 +1515,16 @@ codegen(codegen_scope *s, node *tree, int val) { int n = 0, noop = 0, sendv = 0; - push(); /* room for receiver */ + push(); /* room for receiver */ if (tree) { node *args = tree->car; - if (args) { - n = gen_values(s, args, VAL); - if (n < 0) { - n = noop = sendv = 1; - push(); - } - } + if (args) { + n = gen_values(s, args, VAL); + if (n < 0) { + n = noop = sendv = 1; + push(); + } + } } if (tree && tree->cdr) { codegen(s, tree->cdr, VAL); @@ -1541,7 +1545,7 @@ codegen(codegen_scope *s, node *tree, int val) codegen_scope *s2 = s; int lv = 0, ainfo = 0; - push(); /* room for receiver */ + push(); /* room for receiver */ while (!s2->mscope) { lv++; s2 = s2->prev; @@ -1550,7 +1554,7 @@ codegen(codegen_scope *s, node *tree, int val) if (s2) ainfo = s2->ainfo; genop(s, MKOP_ABx(OP_ARGARY, cursp(), (ainfo<<4)|(lv & 0xf))); if (tree && tree->cdr) { - push(); + push(); codegen(s, tree->cdr, VAL); pop_n(2); } @@ -1782,20 +1786,20 @@ codegen(codegen_scope *s, node *tree, int val) i = readint_mrb_int(s, p, base, FALSE, &overflow); if (overflow) { - double f = readint_float(s, p, base); - int off = new_lit(s, mrb_float_value(f)); + double f = readint_float(s, p, base); + int off = new_lit(s, mrb_float_value(f)); - genop(s, MKOP_ABx(OP_LOADL, cursp(), off)); + genop(s, MKOP_ABx(OP_LOADL, cursp(), off)); } else { - if (i < MAXARG_sBx && i > -MAXARG_sBx) { - co = MKOP_AsBx(OP_LOADI, cursp(), i); - } - else { - int off = new_lit(s, mrb_fixnum_value(i)); - co = MKOP_ABx(OP_LOADL, cursp(), off); - } - genop(s, co); + if (i < MAXARG_sBx && i > -MAXARG_sBx) { + co = MKOP_AsBx(OP_LOADI, cursp(), i); + } + else { + int off = new_lit(s, mrb_fixnum_value(i)); + co = MKOP_ABx(OP_LOADL, cursp(), off); + } + genop(s, co); } push(); } @@ -1838,21 +1842,21 @@ codegen(codegen_scope *s, node *tree, int val) i = readint_mrb_int(s, p, base, TRUE, &overflow); if (overflow) { - double f = readint_float(s, p, base); - int off = new_lit(s, mrb_float_value(-f)); - - genop(s, MKOP_ABx(OP_LOADL, cursp(), off)); - } - else { - if (i < MAXARG_sBx && i > -MAXARG_sBx) { - co = MKOP_AsBx(OP_LOADI, cursp(), i); - } - else { - int off = new_lit(s, mrb_fixnum_value(i)); - co = MKOP_ABx(OP_LOADL, cursp(), off); - } - genop(s, co); - } + double f = readint_float(s, p, base); + int off = new_lit(s, mrb_float_value(-f)); + + genop(s, MKOP_ABx(OP_LOADL, cursp(), off)); + } + else { + if (i < MAXARG_sBx && i > -MAXARG_sBx) { + co = MKOP_AsBx(OP_LOADI, cursp(), i); + } + else { + int off = new_lit(s, mrb_fixnum_value(i)); + co = MKOP_ABx(OP_LOADL, cursp(), off); + } + genop(s, co); + } push(); } break; @@ -1914,18 +1918,27 @@ codegen(codegen_scope *s, node *tree, int val) case NODE_REGX: if (val) { char *p1 = (char*)tree->car; - //char *p2 = (char*)tree->cdr; + char *p2 = (char*)tree->cdr; int ai = mrb_gc_arena_save(s->mrb); - struct RClass* c = mrb_class_get(s->mrb, REGEXP_CLASS); - mrb_value args[2]; - int off; - - args[0] = mrb_str_new(s->mrb, p1, strlen(p1)); - // TODO: Some regexp implementation does not have second argument - //args[1] = mrb_str_new(s->mrb, p2, strlen(p2)) - off = new_lit(s, mrb_class_new_instance(s->mrb, 1, args, c)); - mrb_gc_arena_restore(s->mrb, ai); - genop(s, MKOP_ABx(OP_LOADL, cursp(), off)); + int sym = new_sym(s, mrb_intern(s->mrb, REGEXP_CLASS)); + int off = new_lit(s, mrb_str_new(s->mrb, p1, strlen(p1))); + int n = 1; + + genop(s, MKOP_A(OP_OCLASS, cursp())); + genop(s, MKOP_ABx(OP_GETMCNST, cursp(), sym)); + push(); + genop(s, MKOP_ABx(OP_STRING, cursp(), off)); + if (p2) { + push(); + off = new_lit(s, mrb_str_new(s->mrb, p2, strlen(p2))); + genop(s, MKOP_ABx(OP_STRING, cursp(), off)); + n++; + pop(); + } + pop(); + sym = new_sym(s, mrb_intern(s->mrb, "compile")); + genop(s, MKOP_ABC(OP_SEND, cursp(), sym, n)); + mrb_gc_arena_restore(s->mrb, ai); push(); } break; @@ -2169,7 +2182,7 @@ scope_new(mrb_state *mrb, codegen_scope *prev, node *lv) p->irep->slen = 0; p->lv = lv; - p->sp += node_len(lv)+1; /* add self */ + p->sp += node_len(lv)+1; /* add self */ p->nlocals = p->sp; p->ai = mrb_gc_arena_save(mrb); @@ -2186,7 +2199,7 @@ scope_finish(codegen_scope *s) { mrb_state *mrb = s->mrb; mrb_irep *irep = s->irep; - + irep->flags = 0; if (s->iseq) { irep->iseq = (mrb_code *)codegen_realloc(s, s->iseq, sizeof(mrb_code)*s->pc); @@ -2531,10 +2544,10 @@ codedump(mrb_state *mrb, int n) break; case OP_STRING: { - mrb_value s = irep->pool[GETARG_Bx(c)]; - - s = mrb_str_dump(mrb, s); - printf("OP_STRING\tR%d\t%s\n", GETARG_A(c), RSTRING_PTR(s)); + mrb_value s = irep->pool[GETARG_Bx(c)]; + + s = mrb_str_dump(mrb, s); + printf("OP_STRING\tR%d\t%s\n", GETARG_A(c), RSTRING_PTR(s)); } break; case OP_STRCAT: diff --git a/src/dump.c b/src/dump.c index e8d96c570..ba5a69a56 100644 --- a/src/dump.c +++ b/src/dump.c @@ -10,6 +10,7 @@ #include "mruby/string.h" #include "mruby/irep.h" +#include "mruby/numeric.h" static const unsigned char def_rite_binary_header[] = RITE_FILE_IDENFIFIER @@ -50,6 +51,8 @@ enum { DUMP_SECTION_NUM, }; +#ifdef ENABLE_STDIO + uint16_t calc_crc_16_ccitt(unsigned char*,int); static inline int uint8_dump(uint8_t,char*,int); static inline int uint16_dump(uint16_t,char*,int); @@ -187,8 +190,7 @@ str_dump_len(char *str, uint16_t len, int type) if (*src >= ' ' && *src <= '~') { dump_len++; } else { - // dump_len += sprintf(buf, "\\%03o", *src & 0377); - dump_len += 4; + dump_len += 4; /* octet "\\nnn" */ } break; } @@ -241,8 +243,8 @@ get_pool_block_size(mrb_state *mrb, mrb_irep *irep, int type) switch (mrb_type(irep->pool[pool_no])) { case MRB_TT_FIXNUM: - len = mrb_int_to_str( buf, mrb_fixnum(irep->pool[pool_no])); - size += (uint32_t)len; + str = mrb_fix2str(mrb, irep->pool[pool_no], 10); + size += (uint32_t)RSTRING_LEN(str); break; case MRB_TT_FLOAT: len = mrb_float_to_str( buf, mrb_float(irep->pool[pool_no])); @@ -358,7 +360,9 @@ write_pool_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type) switch (mrb_type(irep->pool[pool_no])) { case MRB_TT_FIXNUM: - len = mrb_int_to_str(char_buf, mrb_fixnum(irep->pool[pool_no])); + str = mrb_fix2str(mrb, irep->pool[pool_no], 10); + memcpy(char_buf, RSTRING_PTR(str), RSTRING_LEN(str)); + len = RSTRING_LEN(str); break; case MRB_TT_FLOAT: @@ -742,3 +746,5 @@ mrb_bdump_irep(mrb_state *mrb, int n, FILE *f,const char *initname) return rc; } + +#endif /* ENABLE_STDIO */ diff --git a/src/error.c b/src/error.c index d3faa7daa..70a84455f 100644 --- a/src/error.c +++ b/src/error.c @@ -209,6 +209,9 @@ mrb_exc_raise(mrb_state *mrb, mrb_value exc) mrb->exc = (struct RObject*)mrb_object(exc); exc_debug_info(mrb, mrb->exc); if (!mrb->jmp) { +#ifdef ENABLE_STDIO + mrb_p(mrb, exc); +#endif abort(); } longjmp(*(jmp_buf*)mrb->jmp, 1); @@ -74,7 +74,6 @@ mrb_lastline_get(mrb_state *mrb) mrb_value mrb_exec_recursive(mrb_state *mrb, mrb_value (*func) (mrb_state *, mrb_value, mrb_value, int), mrb_value obj, void *arg) { - // return mrb_exec_recursive(mrb, io_puts_ary, line, &out); return func(mrb, obj, *(mrb_value*)arg, 0); } @@ -118,7 +117,7 @@ mrb_to_id(mrb_state *mrb, mrb_value name) mrb_value mrb_block_proc(void) { - return mrb_nil_value();//proc_new(mrb_cProc, FALSE); + return mrb_nil_value(); } static mrb_int diff --git a/src/hash.c b/src/hash.c index b7ac59ada..5fa3c1ef8 100644 --- a/src/hash.c +++ b/src/hash.c @@ -181,12 +181,6 @@ mrb_hash_dup(mrb_state *mrb, mrb_value hash) return mrb_obj_value(ret); } -static void -mrb_hash_modify_check(mrb_state *mrb, mrb_value hash) -{ - //if (OBJ_FROZEN(hash)) mrb_error_frozen("hash"); -} - mrb_value mrb_check_hash_type(mrb_state *mrb, mrb_value hash) { @@ -207,7 +201,6 @@ mrb_hash_tbl(mrb_state *mrb, mrb_value hash) static void mrb_hash_modify(mrb_state *mrb, mrb_value hash) { - //mrb_hash_modify_check(mrb, hash); mrb_hash_tbl(mrb, hash); } @@ -755,7 +748,6 @@ mrb_hash_replace(mrb_state *mrb, mrb_value hash) khiter_t k; mrb_get_args(mrb, "o", &hash2); - mrb_hash_modify_check(mrb, hash); hash2 = to_hash(mrb, hash2); if (mrb_obj_equal(mrb, hash, hash2)) return hash; mrb_hash_clear(mrb, hash); diff --git a/src/load.c b/src/load.c index a61af509c..850fa6e8d 100644 --- a/src/load.c +++ b/src/load.c @@ -11,6 +11,7 @@ #include "mruby/proc.h" #include "mruby/irep.h" +#ifdef ENABLE_STDIO typedef struct _RiteFILE { FILE* fp; @@ -18,6 +19,7 @@ typedef struct _RiteFILE int cnt; int readlen; } RiteFILE; +#endif const char hex2bin[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //00-0f @@ -38,15 +40,18 @@ static uint16_t hex_to_uint16(unsigned char*); static uint32_t hex_to_uint32(unsigned char*); static char* hex_to_str(char*,char*,uint16_t*); uint16_t calc_crc_16_ccitt(unsigned char*,int); +#ifdef ENABLE_STDIO static unsigned char rite_fgetcSub(RiteFILE*); static unsigned char rite_fgetc(RiteFILE*,int); static unsigned char* rite_fgets(RiteFILE*,unsigned char*,int,int); static int load_rite_header(FILE*,rite_binary_header*,unsigned char*); static int load_rite_irep_record(mrb_state*, RiteFILE*,unsigned char*,uint32_t*); +#endif static int read_rite_header(mrb_state*,unsigned char*,rite_binary_header*); static int read_rite_irep_record(mrb_state*,unsigned char*,uint32_t*); +#ifdef ENABLE_STDIO static unsigned char rite_fgetcSub(RiteFILE* rfp) { @@ -65,7 +70,9 @@ rite_fgetcSub(RiteFILE* rfp) } return rfp->buf[(rfp->cnt)++]; } +#endif /* ENABLE_STDIO */ +#ifdef ENABLE_STDIO static unsigned char rite_fgetc(RiteFILE* rfp, int ignorecomment) { @@ -87,7 +94,9 @@ rite_fgetc(RiteFILE* rfp, int ignorecomment) } } } +#endif /* ENABLE_STDIO */ +#ifdef ENABLE_STDIO static unsigned char* rite_fgets(RiteFILE* rfp, unsigned char* dst, int len, int ignorecomment) { @@ -100,7 +109,9 @@ rite_fgets(RiteFILE* rfp, unsigned char* dst, int len, int ignorecomment) } return dst; } +#endif /* ENABLE_STDIO */ +#ifdef ENABLE_STDIO static int load_rite_header(FILE* fp, rite_binary_header* bin_header, unsigned char* hcrc) { @@ -128,7 +139,9 @@ load_rite_header(FILE* fp, rite_binary_header* bin_header, unsigned char* hcrc) return MRB_DUMP_OK; } +#endif /* ENABLE_STDIO */ +#ifdef ENABLE_STDIO static int load_rite_irep_record(mrb_state *mrb, RiteFILE* rfp, unsigned char* dst, uint32_t* len) { @@ -152,8 +165,10 @@ load_rite_irep_record(mrb_state *mrb, RiteFILE* rfp, unsigned char* dst, uint32_ //IREP HEADER BLOCK *dst = rite_fgetc(rfp, TRUE); //record identifier - if (*dst != RITE_IREP_IDENFIFIER) - return MRB_DUMP_INVALID_IREP; + if (*dst != RITE_IREP_IDENFIFIER) { + result = MRB_DUMP_INVALID_IREP; + goto error_exit; + } dst += sizeof(unsigned char); *dst = rite_fgetc(rfp, TRUE); //class or module dst += sizeof(unsigned char); @@ -247,7 +262,9 @@ error_exit: return result; } +#endif /* ENABLE_STDIO */ +#ifdef ENABLE_STDIO int mrb_read_irep_file(mrb_state *mrb, FILE* fp) { @@ -306,6 +323,7 @@ error_exit: return ret; } +#endif /* ENABLE_STDIO */ static int read_rite_header(mrb_state *mrb, unsigned char *bin, rite_binary_header* bin_header) @@ -668,6 +686,7 @@ irep_error(mrb_state *mrb, int n) mrb->exc = (struct RObject*)mrb_object(mrb_exc_new(mrb, E_SCRIPT_ERROR, msg, sizeof(msg) - 1)); } +#ifdef ENABLE_STDIO mrb_value mrb_load_irep_file(mrb_state *mrb, FILE* fp) { @@ -679,6 +698,7 @@ mrb_load_irep_file(mrb_state *mrb, FILE* fp) } return mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb)); } +#endif mrb_value mrb_load_irep(mrb_state *mrb, const char *bin) diff --git a/src/mruby_core.rake b/src/mruby_core.rake index 44d62c1e9..db335223d 100644 --- a/src/mruby_core.rake +++ b/src/mruby_core.rake @@ -1,8 +1,11 @@ MRuby.each_target do - dir = File.dirname(__FILE__).relative_path_from(root) - - lex_def = "#{dir}/lex.def" - objs = Dir.glob("src/*.{c}").map { |f| objfile(f.pathmap("#{build_dir}/%X")) } + [objfile("#{build_dir}/#{dir}/y.tab")] + current_dir = File.dirname(__FILE__).relative_path_from(Dir.pwd) + relative_from_root = File.dirname(__FILE__).relative_path_from(MRUBY_ROOT) + current_build_dir = "#{build_dir}/#{relative_from_root}" + + lex_def = "#{current_dir}/lex.def" + objs = Dir.glob("#{current_dir}/*.c").map { |f| objfile(f.pathmap("#{current_build_dir}/%n")) } + objs += [objfile("#{current_build_dir}/y.tab")] self.libmruby << objs file libfile("#{build_dir}/lib/libmruby_core") => objs do |t| @@ -10,16 +13,16 @@ MRuby.each_target do end # Parser - file "#{build_dir}/#{dir}/y.tab.c" => ["#{dir}/parse.y"] do |t| + file "#{current_build_dir}/y.tab.c" => ["#{current_dir}/parse.y"] do |t| yacc.run t.name, t.prerequisites.first end - file objfile("#{build_dir}/#{dir}/y.tab") => ["#{build_dir}/#{dir}/y.tab.c", lex_def] do |t| - cc.run t.name, t.prerequisites.first, [], [dir] + file objfile("#{current_build_dir}/y.tab") => ["#{current_build_dir}/y.tab.c", lex_def] do |t| + cc.run t.name, t.prerequisites.first, [], [current_dir] end # Lexical analyzer - file lex_def => "#{dir}/keywords" do |t| + file lex_def => "#{current_dir}/keywords" do |t| gperf.run t.name, t.prerequisites.first end end diff --git a/src/numeric.c b/src/numeric.c index f6894a57b..b5bff652d 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -25,8 +25,6 @@ #include <ieeefp.h> #endif -#define RSHIFT(x,y) ((x)>>(int)(y)) - #ifdef MRB_USE_FLOAT #define floor(f) floorf(f) #define ceil(f) ceilf(f) @@ -184,6 +182,7 @@ flo_to_s(mrb_state *mrb, mrb_value flt) { char buf[32]; int n; + mrb_float value = mrb_float(flt); if (isinf(value)) { @@ -243,22 +242,25 @@ flo_mul(mrb_state *mrb, mrb_value x) static void flodivmod(mrb_state *mrb, mrb_float x, mrb_float y, mrb_float *divp, mrb_float *modp) { - mrb_float div, mod; + mrb_float div; + mrb_float mod; if (y == 0.0) { - *divp = str_to_mrb_float("inf"); - *modp = str_to_mrb_float("nan"); - return; + div = str_to_mrb_float("inf"); + mod = str_to_mrb_float("nan"); } - mod = fmod(x, y); - if (isinf(x) && !isinf(y) && !isnan(y)) - div = x; - else - div = (x - mod) / y; - if (y*mod < 0) { - mod += y; - div -= 1.0; + else { + mod = fmod(x, y); + if (isinf(x) && !isinf(y) && !isnan(y)) + div = x; + else + div = (x - mod) / y; + if (y*mod < 0) { + mod += y; + div -= 1.0; + } } + if (modp) *modp = mod; if (divp) *divp = div; } @@ -280,6 +282,7 @@ flo_mod(mrb_state *mrb, mrb_value x) { mrb_value y; mrb_float fy, mod; + mrb_get_args(mrb, "o", &y); fy = mrb_to_flo(mrb, y); @@ -339,6 +342,7 @@ flo_eq(mrb_state *mrb, mrb_value x) { mrb_value y; volatile mrb_float a, b; + mrb_get_args(mrb, "o", &y); switch (mrb_type(y)) { @@ -727,6 +731,7 @@ static mrb_value fix_mul(mrb_state *mrb, mrb_value x) { mrb_value y; + mrb_get_args(mrb, "o", &y); return mrb_fixnum_mul(mrb, x, y); } @@ -736,6 +741,8 @@ 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 */ + if (y < 0) { if (x < 0) div = -x / -y; @@ -802,6 +809,7 @@ static mrb_value fix_divmod(mrb_state *mrb, mrb_value x) { mrb_value y; + mrb_get_args(mrb, "o", &y); if (mrb_fixnum_p(y)) { @@ -841,6 +849,7 @@ static mrb_value fix_equal(mrb_state *mrb, mrb_value x) { mrb_value y; + mrb_get_args(mrb, "o", &y); if (mrb_obj_equal(mrb, x, y)) return mrb_true_value(); @@ -900,6 +909,7 @@ fix_and(mrb_state *mrb, mrb_value x) { mrb_value y; mrb_int val; + mrb_get_args(mrb, "o", &y); y = bit_coerce(mrb, y); @@ -920,6 +930,7 @@ fix_or(mrb_state *mrb, mrb_value x) { mrb_value y; mrb_int val; + mrb_get_args(mrb, "o", &y); y = bit_coerce(mrb, y); @@ -942,31 +953,51 @@ fix_xor(mrb_state *mrb, mrb_value x) mrb_int val; mrb_get_args(mrb, "o", &y); + y = bit_coerce(mrb, y); val = mrb_fixnum(x) ^ mrb_fixnum(y); return mrb_fixnum_value(val); } +#define NUMERIC_SHIFT_WIDTH_MAX (sizeof(mrb_int)*CHAR_BIT-1) + static mrb_value lshift(mrb_state *mrb, mrb_int val, int width) { - if (width > (sizeof(mrb_int)*CHAR_BIT-1)) { + if (width > NUMERIC_SHIFT_WIDTH_MAX) { mrb_raisef(mrb, E_RANGE_ERROR, "width(%d) > (%d:sizeof(mrb_int)*CHAR_BIT-1)", width, - sizeof(mrb_int)*CHAR_BIT-1); + NUMERIC_SHIFT_WIDTH_MAX); } val = val << width; return mrb_fixnum_value(val); } static mrb_value -rshift(mrb_int val, int i) +rshift(mrb_int val, int width) { - if (i >= sizeof(mrb_int)*CHAR_BIT-1) { - if (val < 0) return mrb_fixnum_value(-1); - return mrb_fixnum_value(0); + if (width >= NUMERIC_SHIFT_WIDTH_MAX) { + if (val < 0) { + val = -1; } - val = RSHIFT(val, i); - return mrb_fixnum_value(val); + else { + val = 0; + } + } + else { + val = val >> width; + } + + return mrb_fixnum_value(val); +} + +static inline void +fix_shift_get_width(mrb_state *mrb, mrb_int *width) +{ + mrb_value y; + + mrb_get_args(mrb, "o", &y); + y = bit_coerce(mrb, y); + *width = mrb_fixnum(y); } /* 15.2.8.3.12 */ @@ -980,16 +1011,27 @@ rshift(mrb_int val, int i) static mrb_value fix_lshift(mrb_state *mrb, mrb_value x) { - mrb_value y; - mrb_int val, width; + mrb_int width; + mrb_value result; - mrb_get_args(mrb, "o", &y); - val = mrb_fixnum(x); - y = bit_coerce(mrb, y); - width = mrb_fixnum(y); - if (width < 0) - return rshift(val, -width); - return lshift(mrb, val, width); + fix_shift_get_width(mrb, &width); + + if (width == 0) { + result = x; + } + else { + mrb_int val; + + val = mrb_fixnum(x); + if (width < 0) { + result = rshift(val, -width); + } + else { + result = lshift(mrb, val, width); + } + } + + return result; } /* 15.2.8.3.13 */ @@ -1003,17 +1045,27 @@ fix_lshift(mrb_state *mrb, mrb_value x) static mrb_value fix_rshift(mrb_state *mrb, mrb_value x) { - mrb_value y; - mrb_int i, val; + mrb_int width; + mrb_value result; - mrb_get_args(mrb, "o", &y); - val = mrb_fixnum(x); - y = bit_coerce(mrb, y); - i = mrb_fixnum(y); - if (i == 0) return x; - if (i < 0) - return lshift(mrb, val, -i); - return rshift(val, i); + fix_shift_get_width(mrb, &width); + + if (width == 0) { + result = x; + } + else { + mrb_int val; + + val = mrb_fixnum(x); + if (width < 0) { + result = lshift(mrb, val, -width); + } + else { + result = rshift(val, width); + } + } + + return result; } /* 15.2.8.3.23 */ @@ -1148,48 +1200,32 @@ fix_minus(mrb_state *mrb, mrb_value self) return mrb_fixnum_minus(mrb, self, other); } -/* 15.2.8.3.29 (x) */ -/* - * call-seq: - * fix > other => true or false - * - * Returns <code>true</code> if the value of <code>fix</code> is - * greater than that of <code>other</code>. - */ mrb_value mrb_fix2str(mrb_state *mrb, mrb_value x, int base) { - char buf[sizeof(mrb_int)*CHAR_BIT+2], *b = buf + sizeof buf; + char buf[sizeof(mrb_int)*CHAR_BIT+1]; + char *b = buf + sizeof buf; mrb_int val = mrb_fixnum(x); - int neg = 0; if (base < 2 || 36 < base) { mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %d", base); } + if (val == 0) { - return mrb_str_new(mrb, "0", 1); - } - if (val < 0) { - val = -val; - neg = 1; - } - *--b = '\0'; - if (neg && val < 0) { + *--b = '0'; + } else if (val < 0) { do { - *--b = mrb_digitmap[abs(val % base)]; + *--b = mrb_digitmap[-(val % base)]; } while (val /= base); - } - else { + *--b = '-'; + } else { do { *--b = mrb_digitmap[(int)(val % base)]; } while (val /= base); } - if (neg) { - *--b = '-'; - } - return mrb_str_new2(mrb, b); + return mrb_str_new(mrb, b, buf + sizeof(buf) - b); } /* 15.2.8.3.25 */ @@ -1279,6 +1315,7 @@ void mrb_init_numeric(mrb_state *mrb) { struct RClass *numeric, *integer, *fixnum, *fl; + /* Numeric Class */ numeric = mrb_define_class(mrb, "Numeric", mrb->object_class); mrb_include_module(mrb, numeric, mrb_class_get(mrb, "Comparable")); diff --git a/src/string.c b/src/string.c index 6afb4f6ca..205c39876 100644 --- a/src/string.c +++ b/src/string.c @@ -14,6 +14,7 @@ #include "mruby/range.h" #include "mruby/array.h" #include "mruby/class.h" +#include "mruby/numeric.h" #include <stdio.h> #include "re.h" @@ -1319,7 +1320,6 @@ mrb_str_include(mrb_state *mrb, mrb_value self) return mrb_true_value(); return mrb_false_value(); } - //StringValue(arg); mrb_string_value(mrb, &str2); i = mrb_str_index(mrb, self, str2, 0); @@ -1985,14 +1985,6 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str) } -int -mrb_block_given_p() -{ - /*if (ruby_frame->iter == ITER_CUR && ruby_block) - return 1;*//*Qtrue*/ - return FALSE; -} - /* 15.2.10.5.37 */ /* * call-seq: @@ -2281,8 +2273,6 @@ mrb_cstr_to_dbl(mrb_state *mrb, const char * p, int badcheck) { char *end; double d; -// const char *ellipsis = ""; -// int w; #if !defined(DBL_DIG) #define DBL_DIG 16 #endif @@ -2353,7 +2343,6 @@ mrb_str_to_dbl(mrb_state *mrb, mrb_value str, int badcheck) char *s; int len; - //StringValue(str); mrb_string_value(mrb, &str); s = RSTRING_PTR(str); len = RSTRING_LEN(str); @@ -2552,9 +2541,16 @@ mrb_str_dump(mrb_state *mrb, mrb_value str) *q++ = c; } else { - *q++ = '\\'; - sprintf(q, "%03o", c&0xff); - q += 3; + mrb_value octstr; + mrb_value chr; + const char *ptr; + int len; + chr = mrb_fixnum_value(c & 0xff); + octstr = mrb_fix2str(mrb, chr, 8); + ptr = mrb_str_body(octstr, &len); + memcpy(q, "\\000", 4); + memcpy(q + 4 - len, ptr, len); + q += 4; } } *q++ = '"'; @@ -2637,9 +2633,17 @@ mrb_str_inspect(mrb_state *mrb, mrb_value str) continue; } else { - int n = sprintf(buf, "\\%03o", c & 0377); - mrb_str_buf_cat(mrb, result, buf, n); - continue; + mrb_value octstr; + mrb_value chr; + const char *ptr; + int len; + chr = mrb_fixnum_value(c & 0xff); + octstr = mrb_fix2str(mrb, chr, 8); + ptr = mrb_str_body(octstr, &len); + memcpy(buf, "\\000", 4); + memcpy(buf + 4 - len, ptr, len); + mrb_str_buf_cat(mrb, result, buf, 4); + continue; } } mrb_str_buf_cat(mrb, result, "\"", 1); diff --git a/src/struct.c b/src/struct.c index 1efdca66f..5026a6ab4 100644 --- a/src/struct.c +++ b/src/struct.c @@ -172,12 +172,6 @@ static mrb_value (*const ref_func[])(mrb_state*, mrb_value) = { mrb_struct_ref9, }; -static void -mrb_struct_modify(mrb_value s) -{ - //if (OBJ_FROZEN(s)) mrb_error_frozen("Struct"); -} - mrb_sym mrb_id_attrset(mrb_state *mrb, mrb_sym id) { @@ -212,7 +206,6 @@ mrb_struct_set(mrb_state *mrb, mrb_value obj, mrb_value val) members = mrb_struct_members(mrb, obj); ptr_members = RARRAY_PTR(members); len = RARRAY_LEN(members); - mrb_struct_modify(obj); ptr = RSTRUCT_PTR(obj); for (i=0; i<len; i++) { slot = ptr_members[i]; @@ -429,7 +422,6 @@ mrb_struct_initialize_withArg(mrb_state *mrb, int argc, mrb_value *argv, mrb_val int n; struct RStruct *st; - mrb_struct_modify(self); n = num_members(mrb, klass); if (n < argc) { mrb_raise(mrb, E_ARGUMENT_ERROR, "struct size differs"); @@ -616,7 +608,6 @@ mrb_struct_aset_id(mrb_state *mrb, mrb_value s, mrb_sym id, mrb_value val) members = mrb_struct_members(mrb, s); len = RARRAY_LEN(members); - mrb_struct_modify(s); if (RSTRUCT_LEN(s) != len) { mrb_raisef(mrb, E_TYPE_ERROR, "struct size differs (%ld required %ld given)", len, RSTRUCT_LEN(s)); @@ -678,7 +669,6 @@ mrb_struct_aset(mrb_state *mrb, mrb_value s) mrb_raisef(mrb, E_INDEX_ERROR, "offset %ld too large for struct(size:%ld)", i, RSTRUCT_LEN(s)); } - mrb_struct_modify(s); return RSTRUCT_PTR(s)[i] = val; } diff --git a/tasks/mrbgems.rake b/tasks/mrbgems.rake index 285aa75b8..17f266105 100644 --- a/tasks/mrbgems.rake +++ b/tasks/mrbgems.rake @@ -1,5 +1,6 @@ MRuby.each_target do - dir = File.dirname(__FILE__).relative_path_from(root) + current_dir = File.dirname(__FILE__).relative_path_from(Dir.pwd) + relative_from_root = File.dirname(__FILE__).relative_path_from(MRUBY_ROOT) if enable_gems? # set up all gems @@ -8,7 +9,7 @@ MRuby.each_target do # loader all gems self.libmruby << objfile("#{build_dir}/mrbgems/gem_init") file objfile("#{build_dir}/mrbgems/gem_init") => "#{build_dir}/mrbgems/gem_init.c" - file "#{build_dir}/mrbgems/gem_init.c" => [MRUBY_CONFIGS].flatten do |t| + file "#{build_dir}/mrbgems/gem_init.c" => MRUBY_CONFIGS.flatten do |t| FileUtils.mkdir_p "#{build_dir}/mrbgems" open(t.name, 'w') do |f| f.puts %Q[/*] diff --git a/tasks/mrbgems_test.rake b/tasks/mrbgems_test.rake index 2c8ee2ab2..6d40d092a 100644 --- a/tasks/mrbgems_test.rake +++ b/tasks/mrbgems_test.rake @@ -1,5 +1,7 @@ MRuby.each_target do - dir = File.dirname(__FILE__).relative_path_from(root) + current_dir = File.dirname(__FILE__).relative_path_from(Dir.pwd) + relative_from_root = File.dirname(__FILE__).relative_path_from(MRUBY_ROOT) + current_build_dir = "#{build_dir}/#{relative_from_root}" gems.each do |g| test_rbobj = g.test_rbireps.ext(exts.object) diff --git a/tasks/mruby_build.rake b/tasks/mruby_build.rake index b296e8d37..4d28b1d95 100644 --- a/tasks/mruby_build.rake +++ b/tasks/mruby_build.rake @@ -1,5 +1,5 @@ -load 'tasks/mruby_build_gem.rake' -load 'tasks/mruby_build_commands.rake' +load "#{MRUBY_ROOT}/tasks/mruby_build_gem.rake" +load "#{MRUBY_ROOT}/tasks/mruby_build_commands.rake" module MRuby class << self @@ -30,7 +30,7 @@ module MRuby end def self.load - Dir.glob("#{File.dirname(__FILE__)}/toolchains/*.rake").each do |file| + Dir.glob("#{MRUBY_ROOT}/tasks/toolchains/*.rake").each do |file| Kernel.load file end end @@ -44,7 +44,7 @@ module MRuby include Rake::DSL include LoadGems attr_accessor :name, :bins, :exts, :file_separator - attr_reader :root, :libmruby, :gems + attr_reader :libmruby, :gems COMPILERS = %w(cc cxx objc asm) COMMANDS = COMPILERS + %w(linker archiver yacc gperf git exts mrbc) @@ -56,8 +56,6 @@ module MRuby @name = name.to_s unless MRuby.targets[@name] - @root = File.expand_path("#{File.dirname(__FILE__)}/..") - if ENV['OS'] == 'Windows_NT' @exts = Exts.new('.o', '.exe', '.a') else @@ -93,12 +91,16 @@ module MRuby tc.setup(self) end + def root + MRUBY_ROOT + end + def build_dir - "build/#{self.name}" + "#{MRUBY_ROOT}/build/#{self.name}" end def mrbcfile - MRuby.targets['host'].exefile("build/host/bin/mrbc") + MRuby.targets['host'].exefile("#{MRuby.targets['host'].build_dir}/bin/mrbc") end def compilers @@ -114,7 +116,7 @@ module MRuby else compiler.defines += %w(DISABLE_GEMS) end - compiler.define_rules build_dir + compiler.define_rules build_dir, File.expand_path(File.join(File.dirname(__FILE__), '..')) end end @@ -161,14 +163,14 @@ module MRuby def run_test puts ">>> Test #{name} <<<" mrbtest = exefile("#{build_dir}/test/mrbtest") - sh "#{filename mrbtest}" + sh "#{filename mrbtest.relative_path}" puts end def print_build_summary puts "================================================" puts " Config Name: #{@name}" - puts " Output Directory: #{self.build_dir}" + puts " Output Directory: #{self.build_dir.relative_path}" puts " Binaries: #{@bins.join(', ')}" unless @bins.empty? unless @gems.empty? puts " Included Gems:" diff --git a/tasks/mruby_build_commands.rake b/tasks/mruby_build_commands.rake index 884f2027f..ec8a8d3e3 100644 --- a/tasks/mruby_build_commands.rake +++ b/tasks/mruby_build_commands.rake @@ -39,7 +39,7 @@ module MRuby @command = ENV['CC'] || 'cc' @flags = [ENV['CFLAGS'] || []] @source_exts = source_exts - @include_paths = ["#{build.root}/include"] + @include_paths = ["#{MRUBY_ROOT}/include"] @defines = %w() @option_include_path = '-I%s' @option_define = '-D%s' @@ -60,7 +60,7 @@ module MRuby include_path_flags = [include_paths, _include_paths, File.dirname(infile)].flatten.map do |f| option_include_path % filename(f) end - _pp "CC", infile, outfile + _pp "CC", infile.relative_path, outfile.relative_path _run compile_options, { :flags => all_flags(_defineds, _include_paths, _flags), :infile => filename(infile), :outfile => filename(outfile) } end @@ -76,7 +76,7 @@ module MRuby source_exts.each do |ext, compile| rule generated_file_matcher => [ proc { |file| - file.sub(generated_file_matcher, "#{source_dir}\\1#{ext}") + file.sub(generated_file_matcher, "#{source_dir}/\\1#{ext}") }, proc { |file| get_dependencies(file) @@ -141,7 +141,7 @@ module MRuby library_flags = [libraries, _libraries].flatten.map { |d| option_library % d } library_path_flags = [library_paths, _library_paths].flatten.map { |f| option_library_path % filename(f) } - _pp "LD", outfile + _pp "LD", outfile.relative_path _run link_options, { :flags => all_flags(_library_paths, _flags), :outfile => filename(outfile) , :objs => filename(objfiles).join(' '), :flags_before_libraries => [flags_before_libraries, _flags_before_libraries].flatten.join(' '), @@ -161,7 +161,7 @@ module MRuby def run(outfile, objfiles) FileUtils.mkdir_p File.dirname(outfile) - _pp "AR", outfile + _pp "AR", outfile.relative_path _run archive_options, { :outfile => filename(outfile), :objs => filename(objfiles).join(' ') } end end @@ -177,7 +177,7 @@ module MRuby def run(outfile, infile) FileUtils.mkdir_p File.dirname(outfile) - _pp "YACC", infile, outfile + _pp "YACC", infile.relative_path, outfile.relative_path _run compile_options, { :outfile => filename(outfile) , :infile => filename(infile) } end end @@ -193,7 +193,7 @@ module MRuby def run(outfile, infile) FileUtils.mkdir_p File.dirname(outfile) - _pp "GPERF", infile, outfile + _pp "GPERF", infile.relative_path, outfile.relative_path _run compile_options, { :outfile => filename(outfile) , :infile => filename(infile) } end end @@ -210,7 +210,7 @@ module MRuby end def run_clone(dir, url, _flags = []) - _pp "GIT", url, dir + _pp "GIT", url, dir.relative_path _run clone_options, { :flags => [flags, _flags].flatten.join(' '), :url => url, :dir => filename(dir) } end end @@ -226,7 +226,7 @@ module MRuby @command ||= @build.mrbcfile IO.popen("#{filename @command} #{@compile_options % {:funcname => funcname}}", 'r+') do |io| [infiles].flatten.each do |f| - _pp "MRBC", "#{f}", nil, :indent => 2 + _pp "MRBC", f.relative_path, nil, :indent => 2 io.write IO.read(f) end io.close_write diff --git a/tasks/ruby_ext.rake b/tasks/ruby_ext.rake index 6817f6018..a0fbe7b72 100644 --- a/tasks/ruby_ext.rake +++ b/tasks/ruby_ext.rake @@ -12,6 +12,10 @@ class String def relative_path_from(dir) Pathname.new(File.expand_path(self)).relative_path_from(Pathname.new(File.expand_path(dir))).to_s end + + def relative_path + relative_path_from(Dir.pwd) + end # Compatible with 1.9 on 1.8 def %(params) diff --git a/tasks/toolchains/gcc.rake b/tasks/toolchains/gcc.rake index bef9b8618..66fa75dcb 100644 --- a/tasks/toolchains/gcc.rake +++ b/tasks/toolchains/gcc.rake @@ -2,7 +2,7 @@ MRuby::Toolchain.new(:gcc) do |conf| [conf.cc, conf.cxx, conf.objc, conf.asm].each do |cc| cc.command = ENV['CC'] || 'gcc' cc.flags = [ENV['CFLAGS'] || %w(-g -O3 -Wall -Werror-implicit-function-declaration)] - cc.include_paths = ["#{root}/include"] + cc.include_paths = ["#{MRUBY_ROOT}/include"] cc.defines = %w(DISABLE_GEMS) cc.option_include_path = '-I%s' cc.option_define = '-D%s' diff --git a/tasks/toolchains/vs2012.rake b/tasks/toolchains/vs2012.rake index 2f1a608b0..f4039cc29 100644 --- a/tasks/toolchains/vs2012.rake +++ b/tasks/toolchains/vs2012.rake @@ -2,7 +2,7 @@ MRuby::Toolchain.new(:vs2012) do |conf| [conf.cc, conf.cxx].each do |cc| cc.command = ENV['CC'] || 'cl.exe' cc.flags = [ENV['CFLAGS'] || %w(/c /nologo /W3 /D_DEBUG /MDd /Zi /Od /RTC1 /DHAVE_STRING_H /DNO_GETTIMEOFDAY /D_CRT_SECURE_NO_WARNINGS)] - cc.include_paths = ["#{root}/include"] + cc.include_paths = ["#{MRUBY_ROOT}/include"] cc.defines = %w(DISABLE_GEMS) cc.option_include_path = '/I%s' cc.option_define = '/D%s' diff --git a/test/mrbtest.rake b/test/mrbtest.rake index 03e6c7ece..0507981d6 100644 --- a/test/mrbtest.rake +++ b/test/mrbtest.rake @@ -1,20 +1,22 @@ MRuby.each_target do - dir = File.dirname(__FILE__).relative_path_from(root) + current_dir = File.dirname(__FILE__).relative_path_from(Dir.pwd) + relative_from_root = File.dirname(__FILE__).relative_path_from(MRUBY_ROOT) + current_build_dir = "#{build_dir}/#{relative_from_root}" - exec = exefile("#{build_dir}/#{dir}/mrbtest") - clib = "#{build_dir}/#{dir}/mrbtest.c" + exec = exefile("#{current_build_dir}/mrbtest") + clib = "#{current_build_dir}/mrbtest.c" mlib = clib.ext(exts.object) - mrbs = Dir.glob("#{dir}/t/*.rb") - init = "#{dir}/init_mrbtest.c" - asslib = "#{dir}/assert.rb" + mrbs = Dir.glob("#{current_dir}/t/*.rb") + init = "#{current_dir}/init_mrbtest.c" + asslib = "#{current_dir}/assert.rb" - mrbtest_lib = libfile("#{build_dir}/#{dir}/mrbtest") + mrbtest_lib = libfile("#{current_build_dir}/mrbtest") file mrbtest_lib => [mlib, gems.map(&:test_objs), gems.map { |g| g.test_rbireps.ext(exts.object) }].flatten do |t| archiver.run t.name, t.prerequisites end unless build_mrbtest_lib_only? - driver_obj = objfile("#{build_dir}/#{dir}/driver") + driver_obj = objfile("#{current_build_dir}/driver") file exec => [driver_obj, mrbtest_lib, libfile("#{build_dir}/lib/libmruby")] do |t| gem_flags = gems.map { |g| g.linker.flags } gem_flags_before_libraries = gems.map { |g| g.linker.flags_before_libraries } @@ -27,7 +29,7 @@ MRuby.each_target do file mlib => [clib] file clib => [mrbcfile, init, asslib] + mrbs do |t| - _pp "GEN", "*.rb", "#{clib}" + _pp "GEN", "*.rb", "#{clib.relative_path}" FileUtils.mkdir_p File.dirname(clib) open(clib, 'w') do |f| f.puts IO.read(init) diff --git a/test/t/exception.rb b/test/t/exception.rb index a2e6acc07..663c8f337 100644 --- a/test/t/exception.rb +++ b/test/t/exception.rb @@ -287,6 +287,34 @@ assert('Exception 16') do end end +assert('Exception 17') do + begin + raise "a" # StandardError + rescue ArgumentError + 1 + rescue StandardError + 2 + else + 3 + ensure + 4 + end == 2 +end + +assert('Exception 18') do + begin + 0 + rescue ArgumentError + 1 + rescue StandardError + 2 + else + 3 + ensure + 4 + end == 3 +end + assert('Exception#inspect without message') do Exception.new.inspect end diff --git a/tools/mirb/mirb.rake b/tools/mirb/mirb.rake index 46e69136e..f258a9df9 100644 --- a/tools/mirb/mirb.rake +++ b/tools/mirb/mirb.rake @@ -1,9 +1,11 @@ MRuby.each_target do - dir = File.dirname(__FILE__).relative_path_from(root) + current_dir = File.dirname(__FILE__).relative_path_from(Dir.pwd) + relative_from_root = File.dirname(__FILE__).relative_path_from(MRUBY_ROOT) + current_build_dir = "#{build_dir}/#{relative_from_root}" if bins.find { |s| s.to_s == 'mirb' } exec = exefile("#{build_dir}/bin/mirb") - objs = Dir.glob("#{dir}/*.c").map { |f| objfile(f.pathmap("#{build_dir}/%X")) }.flatten + objs = Dir.glob("#{current_dir}/*.c").map { |f| objfile(f.pathmap("#{current_build_dir}/%n")) } file exec => objs + [libfile("#{build_dir}/lib/libmruby")] do |t| gem_flags = gems.map { |g| g.linker.flags } diff --git a/tools/mrbc/mrbc.rake b/tools/mrbc/mrbc.rake index 0121b7f81..1a0309a0d 100644 --- a/tools/mrbc/mrbc.rake +++ b/tools/mrbc/mrbc.rake @@ -1,9 +1,11 @@ MRuby.each_target do - dir = File.dirname(__FILE__).relative_path_from(root) + current_dir = File.dirname(__FILE__).relative_path_from(Dir.pwd) + relative_from_root = File.dirname(__FILE__).relative_path_from(MRUBY_ROOT) + current_build_dir = "#{build_dir}/#{relative_from_root}" if bins.find { |s| s.to_s == 'mrbc' } exec = exefile("#{build_dir}/bin/mrbc") - objs = Dir.glob("#{dir}/*.c").map { |f| objfile(f.pathmap("#{build_dir}/%X")) }.flatten + objs = Dir.glob("#{current_dir}/*.c").map { |f| objfile(f.pathmap("#{current_build_dir}/%n")) }.flatten file exec => objs + [libfile("#{build_dir}/lib/libmruby_core")] do |t| linker.run t.name, t.prerequisites diff --git a/tools/mruby/mruby.rake b/tools/mruby/mruby.rake index fccebff63..dc3cbe2a2 100644 --- a/tools/mruby/mruby.rake +++ b/tools/mruby/mruby.rake @@ -1,9 +1,11 @@ MRuby.each_target do - dir = File.dirname(__FILE__).relative_path_from(root) + current_dir = File.dirname(__FILE__).relative_path_from(Dir.pwd) + relative_from_root = File.dirname(__FILE__).relative_path_from(MRUBY_ROOT) + current_build_dir = "#{build_dir}/#{relative_from_root}" if bins.find { |s| s.to_s == 'mruby' } exec = exefile("#{build_dir}/bin/mruby") - objs = Dir.glob("#{dir}/*.c").map { |f| objfile(f.pathmap("#{build_dir}/%X")) }.flatten + objs = Dir.glob("#{current_dir}/*.c").map { |f| objfile(f.pathmap("#{current_build_dir}/%n")) }.flatten file exec => objs + [libfile("#{build_dir}/lib/libmruby")] do |t| gem_flags = gems.map { |g| g.linker.flags } |
