summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/mrbconf.h8
-rw-r--r--include/mruby.h23
-rw-r--r--include/mruby/class.h2
-rw-r--r--include/mruby/value.h4
-rw-r--r--src/class.c10
-rw-r--r--src/numeric.c118
-rw-r--r--src/string.c2
-rw-r--r--src/symbol.c1
-rw-r--r--src/vm.c37
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);
diff --git a/src/vm.c b/src/vm.c
index 06963260a..8ae0c1612 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -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(&regs[1], argv, sizeof(mrb_value)*(argc-m2)); /* m1 + o */
+ value_move(&regs[1], argv, argc-m2); /* m1 + o */
}
if (m2) {
- memmove(&regs[len-m2+1], &argv[argc-m2], sizeof(mrb_value)*m2); /* m2 */
+ value_move(&regs[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(&regs[1], argv, sizeof(mrb_value)*(m1+o)); /* m1 + o */
+ value_move(&regs[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(&regs[m1+o+r+1], &argv[argc-m2], sizeof(mrb_value)*m2);
+ value_move(&regs[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, &regs[a], (ci->argc+1)*sizeof(mrb_value));
+ value_move(mrb->stack, &regs[a], ci->argc+1);
if (MRB_PROC_CFUNC_P(m)) {
mrb->stack[0] = m->body.func(mrb, recv);