diff options
| -rw-r--r-- | include/mrbconf.h | 8 | ||||
| -rw-r--r-- | include/mruby.h | 23 | ||||
| -rw-r--r-- | include/mruby/class.h | 2 | ||||
| -rw-r--r-- | include/mruby/value.h | 4 | ||||
| -rw-r--r-- | src/class.c | 10 | ||||
| -rw-r--r-- | src/numeric.c | 118 | ||||
| -rw-r--r-- | src/string.c | 2 | ||||
| -rw-r--r-- | src/symbol.c | 1 | ||||
| -rw-r--r-- | src/vm.c | 37 |
9 files changed, 154 insertions, 51 deletions
diff --git a/include/mrbconf.h b/include/mrbconf.h index b485642dc..030e00c9f 100644 --- a/include/mrbconf.h +++ b/include/mrbconf.h @@ -115,10 +115,18 @@ typedef short mrb_sym; # define strtoll _strtoi64 # define PRId32 "I32d" # define PRId64 "I64d" +# ifdef __cplusplus +typedef bool mrb_bool; +# else typedef unsigned int mrb_bool; +# endif #else # include <inttypes.h> +# ifdef __cplusplus +typedef bool mrb_bool; +# else typedef _Bool mrb_bool; +# endif #endif #ifdef ENABLE_STDIO diff --git a/include/mruby.h b/include/mruby.h index 6411f4bdb..4e4751c38 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -37,6 +37,7 @@ extern "C" { #include "mruby/value.h" typedef int32_t mrb_code; +typedef int32_t mrb_aspec; struct mrb_state; @@ -145,10 +146,10 @@ struct RClass *mrb_define_module(mrb_state *, const char*); mrb_value mrb_singleton_class(mrb_state*, mrb_value); void mrb_include_module(mrb_state*, struct RClass*, struct RClass*); -void mrb_define_method(mrb_state*, struct RClass*, const char*, mrb_func_t,int); -void mrb_define_class_method(mrb_state *, struct RClass *, const char *, mrb_func_t, int); -void mrb_define_singleton_method(mrb_state*, struct RObject*, const char*, mrb_func_t,int); -void mrb_define_module_function(mrb_state*, struct RClass*, const char*, mrb_func_t,int); +void mrb_define_method(mrb_state*, struct RClass*, const char*, mrb_func_t, mrb_aspec); +void mrb_define_class_method(mrb_state *, struct RClass *, const char *, mrb_func_t, mrb_aspec); +void mrb_define_singleton_method(mrb_state*, struct RObject*, const char*, mrb_func_t, mrb_aspec); +void mrb_define_module_function(mrb_state*, struct RClass*, const char*, mrb_func_t, mrb_aspec); void mrb_define_const(mrb_state*, struct RClass*, const char *name, mrb_value); void mrb_undef_method(mrb_state*, struct RClass*, const char*); void mrb_undef_class_method(mrb_state*, struct RClass*, const char*); @@ -166,22 +167,22 @@ struct RClass * mrb_define_class_under(mrb_state *mrb, struct RClass *outer, con struct RClass * mrb_define_module_under(mrb_state *mrb, struct RClass *outer, const char *name); /* required arguments */ -#define ARGS_REQ(n) (((n)&0x1f) << 19) +#define ARGS_REQ(n) ((mrb_aspec)((n)&0x1f) << 19) /* optional arguments */ -#define ARGS_OPT(n) (((n)&0x1f) << 14) +#define ARGS_OPT(n) ((mrb_aspec)((n)&0x1f) << 14) /* rest argument */ -#define ARGS_REST() (1 << 13) +#define ARGS_REST() ((mrb_aspec)(1 << 13)) /* required arguments after rest */ -#define ARGS_POST(n) (((n)&0x1f) << 8) +#define ARGS_POST(n) ((mrb_aspec)((n)&0x1f) << 8) /* keyword arguments (n of keys, kdict) */ -#define ARGS_KEY(n1,n2) ((((n1)&0x1f) << 3) | ((n2)?(1<<2):0)) +#define ARGS_KEY(n1,n2) ((mrb_aspec)((((n1)&0x1f) << 3) | ((n2)?(1<<2):0))) /* block argument */ -#define ARGS_BLOCK() (1 << 1) +#define ARGS_BLOCK() ((mrb_aspec)(1 << 1)) /* accept any number of arguments */ #define ARGS_ANY() ARGS_REST() /* accept no arguments */ -#define ARGS_NONE() 0 +#define ARGS_NONE() ((mrb_aspec)0) int mrb_get_args(mrb_state *mrb, const char *format, ...); diff --git a/include/mruby/class.h b/include/mruby/class.h index c303db9ae..b36c6f7f1 100644 --- a/include/mruby/class.h +++ b/include/mruby/class.h @@ -55,7 +55,7 @@ struct RClass *mrb_vm_define_class(mrb_state*, mrb_value, mrb_value, mrb_sym); struct RClass *mrb_vm_define_module(mrb_state*, mrb_value, mrb_sym); void mrb_define_method_vm(mrb_state*, struct RClass*, mrb_sym, mrb_value); void mrb_define_method_raw(mrb_state*, struct RClass*, mrb_sym, struct RProc *); -void mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, int aspec); +void mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, mrb_aspec aspec); void mrb_alias_method(mrb_state *mrb, struct RClass *c, mrb_sym a, mrb_sym b); struct RClass *mrb_class_outer_module(mrb_state*, struct RClass *); diff --git a/include/mruby/value.h b/include/mruby/value.h index 7f31b0982..eae08855d 100644 --- a/include/mruby/value.h +++ b/include/mruby/value.h @@ -158,8 +158,8 @@ mrb_float_value(mrb_float f) #define MRB_OBJECT_HEADER \ enum mrb_vtype tt:8;\ - unsigned int color:3;\ - unsigned int flags:21;\ + uint32_t color:3;\ + uint32_t flags:21;\ struct RClass *c;\ struct RBasic *gcnext diff --git a/src/class.c b/src/class.c index d53629636..01b383fa0 100644 --- a/src/class.c +++ b/src/class.c @@ -297,7 +297,7 @@ mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, struct RPro } void -mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, int aspec) +mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, mrb_aspec aspec) { struct RProc *p; int ai = mrb_gc_arena_save(mrb); @@ -309,7 +309,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, int aspec) +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); } @@ -928,20 +928,20 @@ mrb_singleton_class(mrb_state *mrb, mrb_value v) } void -mrb_define_singleton_method(mrb_state *mrb, struct RObject *o, const char *name, mrb_func_t func, int aspec) +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); } void -mrb_define_class_method(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, int aspec) +mrb_define_class_method(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec) { mrb_define_singleton_method(mrb, (struct RObject*)c, name, func, aspec); } void -mrb_define_module_function(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, int aspec) +mrb_define_module_function(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec) { mrb_define_class_method(mrb, c, name, func, aspec); mrb_define_method(mrb, c, name, func, aspec); diff --git a/src/numeric.c b/src/numeric.c index 5560bbc7f..2cd255a2d 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -9,6 +9,7 @@ #include "mruby/string.h" #include "mruby/array.h" +#include <float.h> #include <math.h> #include <assert.h> #include <stdlib.h> @@ -17,10 +18,6 @@ #include <floatingpoint.h> #endif -#ifdef HAVE_FLOAT_H -#include <float.h> -#endif - #ifdef HAVE_IEEEFP_H #include <ieeefp.h> #endif @@ -166,6 +163,99 @@ num_abs(mrb_state *mrb, mrb_value num) * representation. */ +mrb_value +mrb_flo_to_str(mrb_state *mrb, mrb_float n, int max_digit) +{ + mrb_value result; + + if (max_digit > 40) { + mrb_raise(mrb, E_RANGE_ERROR, "Too large max_digit."); + } + + if (isnan(n)) { + result = mrb_str_new(mrb, "NaN", 3); + } + else if (isinf(n)) { + if (n < 0) { + result = mrb_str_new(mrb, "-inf", 4); + } + else { + result = mrb_str_new(mrb, "inf", 3); + } + } + else { + int digit; + int m; + int exp; + int e = 0; + char s[48]; + char *c = &s[0]; + + if (n < 0) { + n = -n; + *(c++) = '-'; + } + + exp = log10(n); + + if ((exp < 0 ? -exp : exp) > max_digit) { + /* exponent representation */ + e = 1; + m = exp; + if (m < 0) { + m -= 1; + } + n = n / pow(10.0, m); + m = 0; + } + else { + /* un-exponent (normal) representation */ + m = exp; + if (m < 0) { + m = 0; + } + } + + /* puts digits */ + while (max_digit >= 0) { + mrb_float weight = pow(10.0, m); + digit = floor(n / weight + FLT_EPSILON); + *(c++) = '0' + digit; + n -= (digit * weight); + max_digit--; + if (m-- == 0) { + *(c++) = '.'; + } + else if (m < -1 && n < FLT_EPSILON) { + break; + } + } + + if (e) { + *(c++) = 'e'; + if (exp > 0) { + *(c++) = '+'; + } else { + *(c++) = '-'; + exp = -exp; + } + + if (exp >= 100) { + mrb_raise(mrb, E_RANGE_ERROR, "Too large expornent."); + } + + *(c++) = '0' + exp / 10; + *(c++) = '0' + exp % 10; + } + + *c = '\0'; + + result = mrb_str_new(mrb, &s[0], c - &s[0]); + } + + return result; +} + /* 15.2.9.3.16(x) */ /* * call-seq: @@ -180,27 +270,11 @@ num_abs(mrb_state *mrb, mrb_value num) static mrb_value flo_to_s(mrb_state *mrb, mrb_value flt) { - char buf[32]; - int n; - - mrb_float value = mrb_float(flt); - - if (isinf(value)) { - static const char s[2][5] = { "-inf", "inf" }; - static const int n[] = { 4, 3 }; - int idx; - idx = (value < 0) ? 0 : 1; - return mrb_str_new(mrb, s[idx], n[idx]); - } else if(isnan(value)) - return mrb_str_new(mrb, "NaN", 3); - #ifdef MRB_USE_FLOAT - n = sprintf(buf, "%.7g", value); + return mrb_flo_to_str(mrb, mrb_float(flt), 7); #else - n = sprintf(buf, "%.14g", value); + return mrb_flo_to_str(mrb, mrb_float(flt), 14); #endif - assert(n >= 0); - return mrb_str_new(mrb, buf, n); } /* 15.2.9.3.2 */ diff --git a/src/string.c b/src/string.c index 32daaa3b5..7fefbefb5 100644 --- a/src/string.c +++ b/src/string.c @@ -2050,7 +2050,7 @@ mrb_cstr_to_inum(mrb_state *mrb, const char *str, int base, int badcheck) char *end; char sign = 1; int c; - unsigned int n; + unsigned long n; mrb_int val; #undef ISDIGIT diff --git a/src/symbol.c b/src/symbol.c index 34d274787..1c56af4cf 100644 --- a/src/symbol.c +++ b/src/symbol.c @@ -44,7 +44,6 @@ mrb_intern2(mrb_state *mrb, const char *name, size_t len) mrb_sym sym; char *p; - if (len < 0) len = 0; sname.len = len; sname.name = name; k = kh_get(n2s, h, sname); @@ -55,6 +55,27 @@ The value below allows about 60000 recursive calls in the simplest case. */ #endif static inline void +value_move(mrb_value *s1, const mrb_value *s2, size_t n) +{ + if (s1 > s2 && s1 < s2 + n) + { + s1 += n; + s2 += n; + while (n-- > 0) { + *--s1 = *--s2; + } + } + else if (s1 != s2) { + while (n-- > 0) { + *s1++ = *s2++; + } + } + else { + /* nothing to do. */ + } +} + +static inline void stack_clear(mrb_value *from, size_t count) { const mrb_value mrb_value_zero = { { 0 } }; @@ -855,7 +876,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) mrb_ary_unshift(mrb, regs[a+1], sym); } else { - memmove(regs+a+2, regs+a+1, sizeof(mrb_value)*(n+1)); + value_move(regs+a+2, regs+a+1, n+1); regs[a+1] = sym; n++; } @@ -994,7 +1015,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) mrb_ary_unshift(mrb, regs[a+1], mrb_symbol_value(ci->mid)); } else { - memmove(regs+a+2, regs+a+1, sizeof(mrb_value)*(n+1)); + value_move(regs+a+2, regs+a+1, n+1); SET_SYM_VALUE(regs[a+1], ci->mid); n++; } @@ -1138,10 +1159,10 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) if (argc < len) { regs[len+1] = *blk; /* move block */ if (argv0 != argv) { - memmove(®s[1], argv, sizeof(mrb_value)*(argc-m2)); /* m1 + o */ + value_move(®s[1], argv, argc-m2); /* m1 + o */ } if (m2) { - memmove(®s[len-m2+1], &argv[argc-m2], sizeof(mrb_value)*m2); /* m2 */ + value_move(®s[len-m2+1], &argv[argc-m2], m2); /* m2 */ } if (r) { /* r */ regs[m1+o+1] = mrb_ary_new_capa(mrb, 0); @@ -1153,13 +1174,13 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) else { if (argv0 != argv) { regs[len+1] = *blk; /* move block */ - memmove(®s[1], argv, sizeof(mrb_value)*(m1+o)); /* m1 + o */ + value_move(®s[1], argv, m1+o); /* m1 + o */ } if (r) { /* r */ regs[m1+o+1] = mrb_ary_new_from_values(mrb, argc-m1-o-m2, argv+m1+o); } if (m2) { - memmove(®s[m1+o+r+1], &argv[argc-m2], sizeof(mrb_value)*m2); + value_move(®s[m1+o+r+1], &argv[argc-m2], m2); } if (argv0 == argv) { regs[len+1] = *blk; /* move block */ @@ -1313,7 +1334,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) mrb_ary_unshift(mrb, regs[a+1], sym); } else { - memmove(regs+a+2, regs+a+1, sizeof(mrb_value)*(n+1)); + value_move(regs+a+2, regs+a+1, n+1); regs[a+1] = sym; n++; } @@ -1328,7 +1349,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) if (ci->argc == CALL_MAXARGS) ci->argc = -1; /* move stack */ - memmove(mrb->stack, ®s[a], (ci->argc+1)*sizeof(mrb_value)); + value_move(mrb->stack, ®s[a], ci->argc+1); if (MRB_PROC_CFUNC_P(m)) { mrb->stack[0] = m->body.func(mrb, recv); |
