summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--INSTALL14
-rw-r--r--README.md2
-rw-r--r--include/mruby/debug.h8
-rw-r--r--include/mruby/dump.h6
-rw-r--r--include/mruby/string.h12
-rw-r--r--include/mruby/value.h2
-rw-r--r--mrbgems/mruby-bin-mirb/tools/mirb/mirb.c30
-rw-r--r--mrbgems/mruby-bin-mruby/tools/mruby/mruby.c2
-rw-r--r--mrbgems/mruby-proc-ext/src/proc.c2
-rw-r--r--mrbgems/mruby-random/src/mt19937ar.c6
-rw-r--r--mrbgems/mruby-random/src/mt19937ar.h8
-rw-r--r--mrbgems/mruby-random/src/random.c103
-rw-r--r--mrbgems/mruby-random/test/random.rb2
-rw-r--r--mrbgems/mruby-struct/src/struct.c2
-rw-r--r--src/class.c35
-rw-r--r--src/codegen.c17
-rw-r--r--src/debug.c24
-rw-r--r--src/dump.c269
-rw-r--r--src/gc.c4
-rw-r--r--src/hash.c15
-rw-r--r--src/load.c115
-rw-r--r--src/mrb_throw.h2
-rw-r--r--src/numeric.c10
-rw-r--r--src/object.c6
-rw-r--r--src/parse.y6
-rw-r--r--src/pool.c9
-rw-r--r--src/re.h2
-rw-r--r--src/string.c29
-rw-r--r--src/symbol.c8
-rw-r--r--src/variable.c2
-rw-r--r--tasks/mrbgem_spec.rake4
-rw-r--r--tasks/mrbgems_test.rake50
-rw-r--r--test/assert.rb18
-rw-r--r--test/mrbtest.rake17
-rw-r--r--test/t/hash.rb1
35 files changed, 571 insertions, 271 deletions
diff --git a/INSTALL b/INSTALL
index 7a0e6cd47..865ea218e 100644
--- a/INSTALL
+++ b/INSTALL
@@ -28,6 +28,20 @@ send a detailed report to the developers that includes the error log, machine,
and OS type.
+* Adding existing gems
+
+Gems from the [list of mruby gems](http://www.mruby.org/libraries/) can be added by adding
+their respective GitHub URLs to build_config.rb. For example, to add implementations of the
+File and IO Ruby core classes to mruby, insert the following in build_config.rb under the
+comment section `Use mrbgems`:
+
+ conf.gem :git => '[email protected]:iij/mruby-io.git', :branch => 'master'
+
+ Afterwards, re-run:
+
+ ruby ./minirake
+
+
* Porting to other platforms
diff --git a/README.md b/README.md
index f7633019f..fbfed5fc6 100644
--- a/README.md
+++ b/README.md
@@ -41,7 +41,7 @@ The URL of the mruby home-page is:
To subscribe to the mruby mailing list....[T.B.D.]
-## How to compile and install
+## How to compile and install (mruby and gems)
See the INSTALL file.
diff --git a/include/mruby/debug.h b/include/mruby/debug.h
index 2e358a4ca..a56321d42 100644
--- a/include/mruby/debug.h
+++ b/include/mruby/debug.h
@@ -28,10 +28,10 @@ typedef struct mrb_irep_debug_info_file {
uint32_t line_entry_count;
mrb_debug_line_type line_type;
union {
- void *line_ptr;
- mrb_irep_debug_info_line *line_flat_map;
- uint16_t *line_ary;
- };
+ void *ptr;
+ mrb_irep_debug_info_line *flat_map;
+ uint16_t *ary;
+ } lines;
} mrb_irep_debug_info_file;
typedef struct mrb_irep_debug_info {
diff --git a/include/mruby/dump.h b/include/mruby/dump.h
index 69fd776b3..35546f9de 100644
--- a/include/mruby/dump.h
+++ b/include/mruby/dump.h
@@ -92,14 +92,14 @@ struct rite_binary_footer {
RITE_SECTION_HEADER;
};
-static inline int
+static inline size_t
uint8_to_bin(uint8_t s, uint8_t *bin)
{
*bin = s;
return sizeof(uint8_t);
}
-static inline int
+static inline size_t
uint16_to_bin(uint16_t s, uint8_t *bin)
{
*bin++ = (s >> 8) & 0xff;
@@ -107,7 +107,7 @@ uint16_to_bin(uint16_t s, uint8_t *bin)
return sizeof(uint16_t);
}
-static inline int
+static inline size_t
uint32_to_bin(uint32_t l, uint8_t *bin)
{
*bin++ = (l >> 24) & 0xff;
diff --git a/include/mruby/string.h b/include/mruby/string.h
index 7e7fb13d9..31e101246 100644
--- a/include/mruby/string.h
+++ b/include/mruby/string.h
@@ -15,14 +15,7 @@ extern "C" {
extern const char mrb_digitmap[];
-/* (sizeof(mrb_int)*2+sizeof(char*))/sizeof(char)-1 */
-#if defined(MRB_INT16)
-# define RSTRING_EMBED_LEN_MAX 9
-#elif defined(MRB_INT64)
-# define RSTRING_EMBED_LEN_MAX 15
-#else
-# define RSTRING_EMBED_LEN_MAX 11
-#endif
+#define RSTRING_EMBED_LEN_MAX ((mrb_int)(sizeof(void*) * 3 - 1))
struct RString {
MRB_OBJECT_HEADER;
@@ -54,11 +47,12 @@ struct RString {
RSTRING_EMBED_LEN_MAX :\
RSTRING(s)->as.heap.aux.capa)
#define RSTRING_END(s) (RSTRING_PTR(s) + RSTRING_LEN(s))
+mrb_int mrb_str_strlen(mrb_state*, struct RString*);
#define MRB_STR_SHARED 1
#define MRB_STR_NOFREE 2
#define MRB_STR_EMBED 4
-#define MRB_STR_EMBED_LEN_MASK 120
+#define MRB_STR_EMBED_LEN_MASK 0xf8
#define MRB_STR_EMBED_LEN_SHIFT 3
void mrb_gc_free_str(mrb_state*, struct RString*);
diff --git a/include/mruby/value.h b/include/mruby/value.h
index d51fbb7bc..a940aabb7 100644
--- a/include/mruby/value.h
+++ b/include/mruby/value.h
@@ -72,6 +72,8 @@ typedef short mrb_sym;
# define PRIo64 "I64o"
# define PRIx64 "I64x"
# define PRIX64 "I64X"
+# define INFINITY ((float)(DBL_MAX * DBL_MAX))
+# define NAN ((float)(INFINITY - INFINITY))
# else
# include <inttypes.h>
# endif
diff --git a/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c b/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c
index a42577a57..320bc30fb 100644
--- a/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c
+++ b/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c
@@ -15,15 +15,29 @@
#include "mruby/string.h"
#ifdef ENABLE_READLINE
-#include <limits.h>
#include <readline/readline.h>
#include <readline/history.h>
-
+#define MIRB_ADD_HISTORY(line) add_history(line)
+#define MIRB_READLINE(ch) readline(ch)
+#define MIRB_WRITE_HISTORY(path) write_history(path)
+#define MIRB_READ_HISTORY(path) read_history(path)
+#define MIRB_USING_HISTORY() using_history()
+#elif ENABLE_LINENOISE
+#define ENABLE_READLINE
+#include <linenoise.h>
+#define MIRB_ADD_HISTORY(line) linenoiseHistoryAdd(line)
+#define MIRB_READLINE(ch) linenoise(ch)
+#define MIRB_WRITE_HISTORY(path) linenoiseHistorySave(path)
+#define MIRB_READ_HISTORY(path) linenoiseHistoryLoad(history_path)
+#define MIRB_USING_HISTORY()
+#endif
+
+#ifdef ENABLE_READLINE
+#include <limits.h>
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)
{
@@ -281,7 +295,7 @@ main(int argc, char **argv)
ai = mrb_gc_arena_save(mrb);
#ifdef ENABLE_READLINE
- using_history();
+ MIRB_USING_HISTORY();
home = getenv("HOME");
#ifdef _WIN32
if (!home)
@@ -291,7 +305,7 @@ main(int argc, char **argv)
strcpy(history_path, home);
strcat(history_path, "/");
strcat(history_path, history_file_name);
- read_history(history_path);
+ MIRB_READ_HISTORY(history_path);
}
#endif
@@ -312,13 +326,13 @@ main(int argc, char **argv)
last_code_line[char_index] = '\0';
#else
- char* line = readline(code_block_open ? "* " : "> ");
+ char* line = MIRB_READLINE(code_block_open ? "* " : "> ");
if (line == NULL) {
printf("\n");
break;
}
strncpy(last_code_line, line, sizeof(last_code_line)-1);
- add_history(line);
+ MIRB_ADD_HISTORY(line);
free(line);
#endif
@@ -387,7 +401,7 @@ main(int argc, char **argv)
mrb_close(mrb);
#ifdef ENABLE_READLINE
- write_history(history_path);
+ MIRB_WRITE_HISTORY(history_path);
#endif
return 0;
diff --git a/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c b/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c
index 92bf15c5f..01e38ef84 100644
--- a/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c
+++ b/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c
@@ -193,7 +193,7 @@ main(int argc, char **argv)
ARGV = mrb_ary_new_capa(mrb, args.argc);
for (i = 0; i < args.argc; i++) {
- mrb_ary_push(mrb, ARGV, mrb_str_new(mrb, args.argv[i], strlen(args.argv[i])));
+ mrb_ary_push(mrb, ARGV, mrb_str_new_cstr(mrb, args.argv[i]));
}
mrb_define_global_const(mrb, "ARGV", ARGV);
diff --git a/mrbgems/mruby-proc-ext/src/proc.c b/mrbgems/mruby-proc-ext/src/proc.c
index 0bf1204f5..4e41891a4 100644
--- a/mrbgems/mruby-proc-ext/src/proc.c
+++ b/mrbgems/mruby-proc-ext/src/proc.c
@@ -21,7 +21,7 @@ mrb_proc_source_location(mrb_state *mrb, mrb_value self)
}
else {
mrb_irep *irep = p->body.irep;
- uint32_t line;
+ int32_t line;
const char *filename;
filename = mrb_debug_get_filename(irep, 0);
diff --git a/mrbgems/mruby-random/src/mt19937ar.c b/mrbgems/mruby-random/src/mt19937ar.c
index 3de935232..a27aee311 100644
--- a/mrbgems/mruby-random/src/mt19937ar.c
+++ b/mrbgems/mruby-random/src/mt19937ar.c
@@ -63,7 +63,7 @@ unsigned long mrb_random_genrand_int32(mt_state *t)
y ^= (y << 15) & 0xefc60000UL;
y ^= (y >> 18);
- t->gen_int = y;
+ t->gen.int_ = y;
return y;
}
@@ -71,8 +71,8 @@ unsigned long mrb_random_genrand_int32(mt_state *t)
double mrb_random_genrand_real1(mt_state *t)
{
mrb_random_genrand_int32(t);
- t->gen_dbl = t->gen_int*(1.0/4294967295.0);
- return t->gen_dbl;
+ t->gen.double_ = t->gen.int_*(1.0/4294967295.0);
+ return t->gen.double_;
/* divided by 2^32-1 */
}
diff --git a/mrbgems/mruby-random/src/mt19937ar.h b/mrbgems/mruby-random/src/mt19937ar.h
index 504355193..59027c624 100644
--- a/mrbgems/mruby-random/src/mt19937ar.h
+++ b/mrbgems/mruby-random/src/mt19937ar.h
@@ -10,12 +10,12 @@ typedef struct {
unsigned long mt[N];
int mti;
union {
- unsigned long gen_int;
- double gen_dbl;
- };
+ unsigned long int_;
+ double double_;
+ } gen;
mrb_int seed;
- mrb_bool has_seed;
+ mrb_bool has_seed : 1;
} mt_state;
void mrb_random_init_genrand(mt_state *, unsigned long);
diff --git a/mrbgems/mruby-random/src/random.c b/mrbgems/mruby-random/src/random.c
index 4ef009c54..8f983ea0f 100644
--- a/mrbgems/mruby-random/src/random.c
+++ b/mrbgems/mruby-random/src/random.c
@@ -90,21 +90,31 @@ get_opt(mrb_state* mrb)
return arg;
}
+static mrb_value
+get_random(mrb_state *mrb) {
+ return mrb_const_get(mrb,
+ mrb_obj_value(mrb_class_get(mrb, "Random")),
+ mrb_intern_lit(mrb, "DEFAULT"));
+}
+
+static mt_state *
+get_random_state(mrb_state *mrb)
+{
+ mrb_value random_val = get_random(mrb);
+ return DATA_GET_PTR(mrb, random_val, &mt_state_type, mt_state);
+}
+
static mrb_value
mrb_random_g_rand(mrb_state *mrb, mrb_value self)
{
- mrb_value random = mrb_const_get(mrb,
- mrb_obj_value(mrb_class_get(mrb, "Random")),
- mrb_intern_lit(mrb, "DEFAULT"));
+ mrb_value random = get_random(mrb);
return mrb_random_rand(mrb, random);
}
static mrb_value
mrb_random_g_srand(mrb_state *mrb, mrb_value self)
{
- mrb_value random = mrb_const_get(mrb,
- mrb_obj_value(mrb_class_get(mrb, "Random")),
- mrb_intern_lit(mrb, "DEFAULT"));
+ mrb_value random = get_random(mrb);
return mrb_random_srand(mrb, random);
}
@@ -154,7 +164,7 @@ static mrb_value
mrb_random_rand(mrb_state *mrb, mrb_value self)
{
mrb_value max;
- mt_state *t = DATA_PTR(self);
+ mt_state *t = DATA_GET_PTR(mrb, self, &mt_state_type, mt_state);
max = get_opt(mrb);
mrb_random_rand_seed(mrb, t);
@@ -166,7 +176,7 @@ mrb_random_srand(mrb_state *mrb, mrb_value self)
{
mrb_value seed;
mrb_value old_seed;
- mt_state *t = DATA_PTR(self);
+ mt_state *t = DATA_GET_PTR(mrb, self, &mt_state_type, mt_state);
seed = get_opt(mrb);
seed = mrb_random_mt_srand(mrb, t, seed);
@@ -200,10 +210,7 @@ mrb_ary_shuffle_bang(mrb_state *mrb, mrb_value ary)
mrb_get_args(mrb, "|d", &random, &mt_state_type);
if (random == NULL) {
- mrb_value random_val = mrb_const_get(mrb,
- mrb_obj_value(mrb_class_get(mrb, "Random")),
- mrb_intern_lit(mrb, "DEFAULT"));
- random = (mt_state *)DATA_PTR(random_val);
+ random = get_random_state(mrb);
}
mrb_random_rand_seed(mrb, random);
@@ -240,6 +247,77 @@ mrb_ary_shuffle(mrb_state *mrb, mrb_value ary)
return new_ary;
}
+/*
+ * call-seq:
+ * ary.sample -> obj
+ * ary.sample(n) -> new_ary
+ *
+ * Choose a random element or +n+ random elements from the array.
+ *
+ * The elements are chosen by using random and unique indices into the array
+ * in order to ensure that an element doesn't repeat itself unless the array
+ * already contained duplicate elements.
+ *
+ * If the array is empty the first form returns +nil+ and the second form
+ * returns an empty array.
+ */
+
+static mrb_value
+mrb_ary_sample(mrb_state *mrb, mrb_value ary)
+{
+ mrb_int n = 0;
+ mrb_bool given;
+ mt_state *random = NULL;
+ mrb_int len = RARRAY_LEN(ary);
+
+ mrb_get_args(mrb, "|i?d", &n, &given, &random, &mt_state_type);
+ if (random == NULL) {
+ random = get_random_state(mrb);
+ }
+ mrb_random_rand_seed(mrb, random);
+ mt_rand(random);
+ if (!given) { /* pick one element */
+ switch (len) {
+ case 0:
+ return mrb_nil_value();
+ case 1:
+ return RARRAY_PTR(ary)[0];
+ default:
+ return RARRAY_PTR(ary)[mt_rand(random) % len];
+ }
+ }
+ else {
+ mrb_value result;
+ mrb_int i, j;
+
+ if (n < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "negative sample number");
+ if (n > len) n = len;
+ result = mrb_ary_new_capa(mrb, n);
+ for (i=0; i<n; i++) {
+ mrb_int r;
+
+ for (;;) {
+ retry:
+ r = mt_rand(random) % len;
+
+ for (j=0; j<i; j++) {
+ if (mrb_fixnum(RARRAY_PTR(result)[j]) == r) {
+ goto retry; /* retry if duplicate */
+ }
+ }
+ break;
+ }
+ RARRAY_PTR(result)[i] = mrb_fixnum_value(r);
+ RARRAY_LEN(result)++;
+ }
+ for (i=0; i<n; i++) {
+ RARRAY_PTR(result)[i] = RARRAY_PTR(ary)[mrb_fixnum(RARRAY_PTR(result)[i])];
+ }
+ return result;
+ }
+}
+
+
void mrb_mruby_random_gem_init(mrb_state *mrb)
{
struct RClass *random;
@@ -259,6 +337,7 @@ void mrb_mruby_random_gem_init(mrb_state *mrb)
mrb_define_method(mrb, array, "shuffle", mrb_ary_shuffle, MRB_ARGS_OPT(1));
mrb_define_method(mrb, array, "shuffle!", mrb_ary_shuffle_bang, MRB_ARGS_OPT(1));
+ mrb_define_method(mrb, array, "sample", mrb_ary_sample, MRB_ARGS_OPT(2));
mrb_const_set(mrb, mrb_obj_value(random), mrb_intern_lit(mrb, "DEFAULT"),
mrb_obj_new(mrb, random, 0, NULL));
diff --git a/mrbgems/mruby-random/test/random.rb b/mrbgems/mruby-random/test/random.rb
index c4e4082ad..fa31b782b 100644
--- a/mrbgems/mruby-random/test/random.rb
+++ b/mrbgems/mruby-random/test/random.rb
@@ -73,4 +73,4 @@ assert('Array#shuffle!(random)') do
ary2.shuffle! Random.new 345
ary1 != [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and 10.times { |x| ary1.include? x } and ary1 == ary2
-end \ No newline at end of file
+end
diff --git a/mrbgems/mruby-struct/src/struct.c b/mrbgems/mruby-struct/src/struct.c
index 02b842e53..646414f0c 100644
--- a/mrbgems/mruby-struct/src/struct.c
+++ b/mrbgems/mruby-struct/src/struct.c
@@ -381,7 +381,7 @@ mrb_struct_s_def(mrb_state *mrb, mrb_value klass)
}
st = make_struct(mrb, name, rest, struct_class(mrb));
if (!mrb_nil_p(b)) {
- mrb_funcall(mrb, b, "call", 1, &st);
+ mrb_funcall(mrb, b, "call", 1, st);
}
return st;
diff --git a/src/class.c b/src/class.c
index 9880a82fa..72e96ece8 100644
--- a/src/class.c
+++ b/src/class.c
@@ -411,6 +411,7 @@ to_hash(mrb_state *mrb, mrb_value val)
&: 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.
+ ?: optional given [mrb_bool] true if preceding argument (optional) is given.
*/
int
mrb_get_args(mrb_state *mrb, const char *format, ...)
@@ -420,7 +421,8 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
mrb_value *sp = mrb->c->stack + 1;
va_list ap;
int argc = mrb->c->ci->argc;
- int opt = 0;
+ mrb_bool opt = 0;
+ mrb_bool given = 1;
va_start(ap, format);
if (argc < 0) {
@@ -431,11 +433,16 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
}
while ((c = *format++)) {
switch (c) {
- case '|': case '*': case '&':
+ case '|': case '*': case '&': case '?':
break;
default:
- if (argc <= i && !opt) {
- mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments");
+ if (argc <= i) {
+ if (opt) {
+ given = 0;
+ }
+ else {
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments");
+ }
}
break;
}
@@ -527,22 +534,12 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
case 'z':
{
mrb_value ss;
- struct RString *s;
char **ps;
- mrb_int len;
ps = va_arg(ap, char**);
if (i < argc) {
ss = to_str(mrb, *sp++);
- s = mrb_str_ptr(ss);
- len = (mrb_int)strlen(RSTRING_PTR(ss));
- if (len < RSTRING_LEN(ss)) {
- mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte");
- }
- else if (len > RSTRING_LEN(ss)) {
- mrb_str_modify(mrb, s);
- }
- *ps = RSTRING_PTR(ss);
+ *ps = mrb_string_value_cstr(mrb, &ss);
i++;
}
}
@@ -689,6 +686,14 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
case '|':
opt = 1;
break;
+ case '?':
+ {
+ mrb_bool *p;
+
+ p = va_arg(ap, mrb_bool*);
+ *p = given;
+ }
+ break;
case '*':
{
diff --git a/src/codegen.c b/src/codegen.c
index 0b4d18bba..b0d7454dc 100644
--- a/src/codegen.c
+++ b/src/codegen.c
@@ -5,6 +5,7 @@
*/
#include <ctype.h>
+#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include "mruby.h"
@@ -1914,7 +1915,7 @@ codegen(codegen_scope *s, node *tree, int val)
mrb_value fix = mrb_fixnum_value((intptr_t)tree);
mrb_value str = mrb_str_buf_new(mrb, 4);
- mrb_str_buf_cat(mrb, str, "$", 1);
+ mrb_str_cat_lit(mrb, str, "$");
mrb_str_buf_append(mrb, str, mrb_fixnum_to_str(mrb, fix, 10));
sym = new_sym(s, mrb_intern_str(mrb, str));
genop(s, MKOP_ABx(OP_GETGLOBAL, cursp(), sym));
@@ -2106,7 +2107,7 @@ codegen(codegen_scope *s, node *tree, int val)
char *p2 = (char*)tree->cdr;
int ai = mrb_gc_arena_save(s->mrb);
int sym = new_sym(s, mrb_intern_lit(s->mrb, REGEXP_CLASS));
- int off = new_lit(s, mrb_str_new(s->mrb, p1, strlen(p1)));
+ int off = new_lit(s, mrb_str_new_cstr(s->mrb, p1));
int argc = 1;
genop(s, MKOP_A(OP_OCLASS, cursp()));
@@ -2115,7 +2116,7 @@ codegen(codegen_scope *s, node *tree, int val)
genop(s, MKOP_ABx(OP_STRING, cursp(), off));
if (p2) {
push();
- off = new_lit(s, mrb_str_new(s->mrb, p2, strlen(p2)));
+ off = new_lit(s, mrb_str_new_cstr(s->mrb, p2));
genop(s, MKOP_ABx(OP_STRING, cursp(), off));
argc++;
pop();
@@ -2152,7 +2153,7 @@ codegen(codegen_scope *s, node *tree, int val)
n = tree->cdr->cdr;
if (n->car) {
p = (char*)n->car;
- off = new_lit(s, mrb_str_new(s->mrb, p, strlen(p)));
+ off = new_lit(s, mrb_str_new_cstr(s->mrb, p));
codegen(s, tree->car, VAL);
genop(s, MKOP_ABx(OP_STRING, cursp(), off));
pop();
@@ -2163,7 +2164,7 @@ codegen(codegen_scope *s, node *tree, int val)
int off;
push();
- off = new_lit(s, mrb_str_new(s->mrb, p2, strlen(p2)));
+ off = new_lit(s, mrb_str_new_cstr(s->mrb, p2));
genop(s, MKOP_ABx(OP_STRING, cursp(), off));
argc++;
pop();
@@ -2582,14 +2583,16 @@ static void
codedump(mrb_state *mrb, mrb_irep *irep)
{
#ifdef ENABLE_STDIO
- uint32_t i;
+ int i;
int ai;
mrb_code c;
if (!irep) return;
printf("irep %p nregs=%d nlocals=%d pools=%d syms=%d reps=%d\n", irep,
irep->nregs, irep->nlocals, (int)irep->plen, (int)irep->slen, (int)irep->rlen);
- for (i=0; i<irep->ilen; i++) {
+
+ mrb_assert(irep->ilen <= INT_MAX);
+ for (i = 0; i < (int)(irep->ilen); i++) {
ai = mrb_gc_arena_save(mrb);
printf("%03d ", i);
c = irep->iseq[i];
diff --git a/src/debug.c b/src/debug.c
index cdb0aa9e8..1a3dc275d 100644
--- a/src/debug.c
+++ b/src/debug.c
@@ -74,11 +74,11 @@ mrb_debug_get_line(mrb_irep *irep, uint32_t pc)
switch(f->line_type) {
case mrb_debug_line_ary:
mrb_assert(f->start_pos <= pc && pc < (f->start_pos + f->line_entry_count));
- return f->line_ary[pc - f->start_pos];
+ return f->lines.ary[pc - f->start_pos];
case mrb_debug_line_flat_map: {
/* get upper bound */
- mrb_irep_debug_info_line *ret = f->line_flat_map;
+ mrb_irep_debug_info_line *ret = f->lines.flat_map;
uint32_t count = f->line_entry_count;
while (count > 0) {
int32_t step = count / 2;
@@ -92,10 +92,10 @@ mrb_debug_get_line(mrb_irep *irep, uint32_t pc)
--ret;
/* check line entry pointer range */
- mrb_assert(f->line_flat_map <= ret && ret < (f->line_flat_map + f->line_entry_count));
+ mrb_assert(f->lines.flat_map <= ret && ret < (f->lines.flat_map + f->line_entry_count));
/* check pc range */
mrb_assert(ret->start_pos <= pc &&
- pc < (((ret + 1 - f->line_flat_map) < f->line_entry_count)
+ pc < (((ret + 1 - f->lines.flat_map) < f->line_entry_count)
? (ret+1)->start_pos : irep->debug_info->pc_count));
return ret->line;
@@ -160,31 +160,31 @@ mrb_debug_info_append_file(mrb_state *mrb, mrb_irep *irep,
ret->filename = mrb_sym2name_len(mrb, ret->filename_sym, &len);
ret->line_type = select_line_type(irep->lines + start_pos, end_pos - start_pos);
- ret->line_ptr = NULL;
+ ret->lines.ptr = NULL;
switch(ret->line_type) {
case mrb_debug_line_ary:
ret->line_entry_count = file_pc_count;
- ret->line_ary = (uint16_t*)mrb_malloc(mrb, sizeof(uint16_t) * file_pc_count);
+ ret->lines.ary = (uint16_t*)mrb_malloc(mrb, sizeof(uint16_t) * file_pc_count);
for(i = 0; i < file_pc_count; ++i) {
- ret->line_ary[i] = irep->lines[start_pos + i];
+ ret->lines.ary[i] = irep->lines[start_pos + i];
}
break;
case mrb_debug_line_flat_map: {
uint16_t prev_line = 0;
mrb_irep_debug_info_line m;
- ret->line_flat_map = (mrb_irep_debug_info_line*)mrb_malloc(mrb, sizeof(mrb_irep_debug_info_line) * 1);
+ ret->lines.flat_map = (mrb_irep_debug_info_line*)mrb_malloc(mrb, sizeof(mrb_irep_debug_info_line) * 1);
ret->line_entry_count = 0;
for(i = 0; i < file_pc_count; ++i) {
if(irep->lines[start_pos + i] == prev_line) { continue; }
- ret->line_flat_map = (mrb_irep_debug_info_line*)mrb_realloc(
- mrb, ret->line_flat_map,
+ ret->lines.flat_map = (mrb_irep_debug_info_line*)mrb_realloc(
+ mrb, ret->lines.flat_map,
sizeof(mrb_irep_debug_info_line) * (ret->line_entry_count + 1));
m.start_pos = start_pos + i;
m.line = irep->lines[start_pos + i];
- ret->line_flat_map[ret->line_entry_count] = m;
+ ret->lines.flat_map[ret->line_entry_count] = m;
/* update */
++ret->line_entry_count;
@@ -207,7 +207,7 @@ mrb_debug_info_free(mrb_state *mrb, mrb_irep_debug_info *d)
for(i = 0; i < d->flen; ++i) {
mrb_assert(d->files[i]);
- mrb_free(mrb, d->files[i]->line_ptr);
+ mrb_free(mrb, d->files[i]->lines.ptr);
mrb_free(mrb, d->files[i]);
}
mrb_free(mrb, d->files);
diff --git a/src/dump.c b/src/dump.c
index 4c843f8d7..393918b45 100644
--- a/src/dump.c
+++ b/src/dump.c
@@ -12,12 +12,16 @@
#include "mruby/numeric.h"
#include "mruby/debug.h"
-static uint32_t get_irep_record_size_1(mrb_state *mrb, mrb_irep *irep);
+static size_t get_irep_record_size_1(mrb_state *mrb, mrb_irep *irep);
-static uint32_t
+#if UINT32_MAX > SIZE_MAX
+# error This code cannot be built on your environment.
+#endif
+
+static size_t
get_irep_header_size(mrb_state *mrb)
{
- uint32_t size = 0;
+ size_t size = 0;
size += sizeof(uint32_t) * 1;
size += sizeof(uint16_t) * 3;
@@ -25,7 +29,7 @@ get_irep_header_size(mrb_state *mrb)
return size;
}
-static uint32_t
+static ptrdiff_t
write_irep_header(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
{
uint8_t *cur = buf;
@@ -35,20 +39,22 @@ write_irep_header(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
cur += uint16_to_bin((uint16_t)irep->nregs, cur); /* number of register variable */
cur += uint16_to_bin((uint16_t)irep->rlen, cur); /* number of child irep */
- return (cur - buf);
+ return cur - buf;
}
-static uint32_t
+static size_t
get_iseq_block_size(mrb_state *mrb, mrb_irep *irep)
{
- uint32_t size = 0;
+ size_t size = 0;
+
size += sizeof(uint32_t); /* ilen */
size += sizeof(uint32_t) * irep->ilen; /* iseq(n) */
+
return size;
}
-static uint32_t
+static ptrdiff_t
write_iseq_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
{
uint8_t *cur = buf;
@@ -59,16 +65,15 @@ write_iseq_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
cur += uint32_to_bin(irep->iseq[iseq_no], cur); /* opcode */
}
- return (cur - buf);
+ return cur - buf;
}
-static uint32_t
+static size_t
get_pool_block_size(mrb_state *mrb, mrb_irep *irep)
{
- uint32_t size = 0;
- uint32_t pool_no;
- int len;
+ size_t size = 0;
+ size_t pool_no;
mrb_value str;
char buf[32];
@@ -81,16 +86,31 @@ get_pool_block_size(mrb_state *mrb, mrb_irep *irep)
switch (mrb_type(irep->pool[pool_no])) {
case MRB_TT_FIXNUM:
str = mrb_fixnum_to_str(mrb, irep->pool[pool_no], 10);
- size += RSTRING_LEN(str);
+ {
+ mrb_int len = RSTRING_LEN(str);
+ mrb_assert(len >= 0);
+ mrb_assert((size_t)len <= SIZE_MAX);
+ size += (size_t)len;
+ }
break;
case MRB_TT_FLOAT:
- len = mrb_float_to_str(buf, mrb_float(irep->pool[pool_no]));
- size += len;
+ {
+ int len;
+ len = mrb_float_to_str(buf, mrb_float(irep->pool[pool_no]));
+ mrb_assert(len >= 0);
+ mrb_assert((size_t)len <= SIZE_MAX);
+ size += (size_t)len;
+ }
break;
case MRB_TT_STRING:
- size += RSTRING_LEN(irep->pool[pool_no]);
+ {
+ mrb_int len = RSTRING_LEN(irep->pool[pool_no]);
+ mrb_assert(len >= 0);
+ mrb_assert((size_t)len <= SIZE_MAX);
+ size += (size_t)len;
+ }
break;
default:
@@ -102,12 +122,12 @@ get_pool_block_size(mrb_state *mrb, mrb_irep *irep)
return size;
}
-static uint32_t
+static ptrdiff_t
write_pool_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
{
- uint32_t pool_no;
+ size_t pool_no;
uint8_t *cur = buf;
- uint32_t len;
+ uint16_t len;
mrb_value str;
const char *char_ptr;
char char_buf[30];
@@ -122,19 +142,37 @@ write_pool_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
cur += uint8_to_bin(IREP_TT_FIXNUM, cur); /* data type */
str = mrb_fixnum_to_str(mrb, irep->pool[pool_no], 10);
char_ptr = RSTRING_PTR(str);
- len = RSTRING_LEN(str);
+ {
+ mrb_int tlen;
+ tlen = RSTRING_LEN(str);
+ mrb_assert(tlen >= 0);
+ mrb_assert(tlen <= INT16_MAX);
+ len = (uint16_t)tlen;
+ }
break;
case MRB_TT_FLOAT:
cur += uint8_to_bin(IREP_TT_FLOAT, cur); /* data type */
- len = mrb_float_to_str(char_buf, mrb_float(irep->pool[pool_no]));
+ {
+ int tlen;
+ tlen = mrb_float_to_str(char_buf, mrb_float(irep->pool[pool_no]));
+ mrb_assert(tlen >= 0);
+ mrb_assert(tlen <= INT16_MAX);
+ len = (uint16_t)tlen;
+ }
char_ptr = &char_buf[0];
break;
case MRB_TT_STRING:
cur += uint8_to_bin(IREP_TT_STRING, cur); /* data type */
char_ptr = RSTRING_PTR(irep->pool[pool_no]);
- len = RSTRING_LEN(irep->pool[pool_no]);
+ {
+ mrb_int tlen;
+ tlen = RSTRING_LEN(irep->pool[pool_no]);
+ mrb_assert(tlen >= 0);
+ mrb_assert(tlen <= INT16_MAX);
+ len = (uint16_t)tlen;
+ }
break;
default:
@@ -142,22 +180,22 @@ write_pool_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
}
cur += uint16_to_bin(len, cur); /* data length */
- memcpy(cur, char_ptr, len);
+ memcpy(cur, char_ptr, (size_t)len);
cur += len;
mrb_gc_arena_restore(mrb, ai);
}
- return (uint32_t)(cur - buf);
+ return cur - buf;
}
-static uint32_t
+static size_t
get_syms_block_size(mrb_state *mrb, mrb_irep *irep)
{
- uint32_t size = 0;
+ size_t size = 0;
uint32_t sym_no;
- uint32_t len;
+ size_t len;
size += sizeof(uint32_t); /* slen */
for (sym_no = 0; sym_no < irep->slen; sym_no++) {
@@ -171,7 +209,7 @@ get_syms_block_size(mrb_state *mrb, mrb_irep *irep)
return size;
}
-static uint32_t
+static ptrdiff_t
write_syms_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
{
uint32_t sym_no;
@@ -182,13 +220,11 @@ write_syms_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
for (sym_no = 0; sym_no < irep->slen; sym_no++) {
if (irep->syms[sym_no] != 0) {
- uint32_t len;
+ size_t len;
name = mrb_sym2name_len(mrb, irep->syms[sym_no], &len);
- if (len > UINT16_MAX) {
- return MRB_DUMP_GENERAL_FAILURE;
- }
+ mrb_assert(len <= UINT16_MAX);
cur += uint16_to_bin((uint16_t)len, cur); /* length of symbol name */
memcpy(cur, name, len); /* symbol name */
cur += (uint16_t)len;
@@ -199,13 +235,13 @@ write_syms_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
}
}
- return (uint32_t)(cur - buf);
+ return cur - buf;
}
-static uint32_t
+static size_t
get_irep_record_size_1(mrb_state *mrb, mrb_irep *irep)
{
- uint32_t size = 0;
+ size_t size = 0;
size += get_irep_header_size(mrb);
size += get_iseq_block_size(mrb, irep);
@@ -214,11 +250,11 @@ get_irep_record_size_1(mrb_state *mrb, mrb_irep *irep)
return size;
}
-static uint32_t
+static size_t
get_irep_record_size(mrb_state *mrb, mrb_irep *irep)
{
- uint32_t size = 0;
- uint32_t irep_no;
+ size_t size = 0;
+ size_t irep_no;
size = get_irep_record_size_1(mrb, irep);
for (irep_no = 0; irep_no < irep->rlen; irep_no++) {
@@ -228,7 +264,7 @@ get_irep_record_size(mrb_state *mrb, mrb_irep *irep)
}
static int
-write_irep_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin, uint32_t *irep_record_size)
+write_irep_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin, size_t *irep_record_size)
{
uint32_t i;
@@ -250,14 +286,14 @@ write_irep_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin, uint32_t *irep_r
for (i = 0; i < irep->rlen; i++) {
int result;
- uint32_t rlen;
+ size_t rsize;
- result = write_irep_record(mrb, irep->reps[i], bin, &rlen);
+ result = write_irep_record(mrb, irep->reps[i], bin, &rsize);
if (result != MRB_DUMP_OK) {
return result;
}
- *irep_record_size += rlen;
- bin += rlen;
+ *irep_record_size += rsize;
+ bin += rsize;
}
return MRB_DUMP_OK;
}
@@ -276,12 +312,13 @@ write_footer(mrb_state *mrb, uint8_t *bin)
static int
-write_section_irep_header(mrb_state *mrb, uint32_t section_size, uint8_t *bin)
+write_section_irep_header(mrb_state *mrb, size_t section_size, uint8_t *bin)
{
struct rite_section_irep_header *header = (struct rite_section_irep_header*)bin;
memcpy(header->section_identify, RITE_SECTION_IREP_IDENTIFIER, sizeof(header->section_identify));
- uint32_to_bin(section_size, header->section_size);
+ mrb_assert(section_size <= UINT32_MAX);
+ uint32_to_bin((uint32_t)section_size, header->section_size);
memcpy(header->rite_version, RITE_VM_VER, sizeof(header->rite_version));
return MRB_DUMP_OK;
@@ -291,7 +328,8 @@ static int
write_section_irep(mrb_state *mrb, mrb_irep *irep, uint8_t *bin)
{
int result;
- uint32_t section_size = 0, rlen = 0; /* size of irep record */
+ size_t section_size = 0; /* size of irep record */
+ size_t rsize = 0;
uint8_t *cur = bin;
if (mrb == NULL || bin == NULL) {
@@ -301,33 +339,32 @@ write_section_irep(mrb_state *mrb, mrb_irep *irep, uint8_t *bin)
cur += sizeof(struct rite_section_irep_header);
section_size += sizeof(struct rite_section_irep_header);
- result = write_irep_record(mrb, irep, cur, &rlen);
+ result = write_irep_record(mrb, irep, cur, &rsize);
if (result != MRB_DUMP_OK) {
return result;
}
- cur += rlen;
- section_size += rlen;
+ cur += rsize;
+ section_size += rsize;
write_section_irep_header(mrb, section_size, bin);
return MRB_DUMP_OK;
}
static int
-write_section_lineno_header(mrb_state *mrb, uint32_t section_size, uint8_t *bin)
+write_section_lineno_header(mrb_state *mrb, size_t section_size, uint8_t *bin)
{
struct rite_section_lineno_header *header = (struct rite_section_lineno_header*)bin;
- /* TODO */
memcpy(header->section_identify, RITE_SECTION_LINENO_IDENTIFIER, sizeof(header->section_identify));
- uint32_to_bin(section_size, header->section_size);
+ uint32_to_bin((uint32_t)section_size, header->section_size);
return MRB_DUMP_OK;
}
-static uint32_t
+static size_t
get_lineno_record_size(mrb_state *mrb, mrb_irep *irep)
{
- uint32_t size = 0;
+ size_t size = 0;
size += sizeof(uint32_t); /* record size */
size += sizeof(uint16_t); /* filename size */
@@ -338,21 +375,27 @@ get_lineno_record_size(mrb_state *mrb, mrb_irep *irep)
if (irep->lines) {
size += sizeof(uint16_t) * irep->ilen; /* lineno */
}
+
return size;
}
-static int
+static size_t
write_lineno_record_1(mrb_state *mrb, mrb_irep *irep, uint8_t* bin)
{
uint8_t *cur = bin;
- uint32_t filename_len = 0, iseq_no;
+ size_t iseq_no;
+ size_t filename_len;
+ ptrdiff_t diff;
cur += sizeof(uint32_t); /* record size */
if (irep->filename) {
filename_len = strlen(irep->filename);
+ } else {
+ filename_len = 0;
}
- cur += uint16_to_bin(filename_len, cur); /* filename size */
+ mrb_assert(filename_len <= UINT16_MAX);
+ cur += uint16_to_bin((uint16_t)filename_len, cur); /* filename size */
if (filename_len) {
memcpy(cur, irep->filename, filename_len);
@@ -360,7 +403,8 @@ write_lineno_record_1(mrb_state *mrb, mrb_irep *irep, uint8_t* bin)
}
if (irep->lines) {
- cur += uint32_to_bin(irep->ilen, cur); /* niseq */
+ mrb_assert(irep->ilen <= UINT32_MAX);
+ cur += uint32_to_bin((uint32_t)(irep->ilen), cur); /* niseq */
for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) {
cur += uint16_to_bin(irep->lines[iseq_no], cur); /* opcode */
}
@@ -369,16 +413,21 @@ write_lineno_record_1(mrb_state *mrb, mrb_irep *irep, uint8_t* bin)
cur += uint32_to_bin(0, cur); /* niseq */
}
- uint32_to_bin(cur - bin, bin); /* record size */
+ diff = cur - bin;
+ mrb_assert(diff >= 0);
+ mrb_assert(diff <= UINT32_MAX);
+
+ uint32_to_bin((uint32_t)diff, bin); /* record size */
- return (cur - bin);
+ mrb_assert((size_t)diff <= SIZE_MAX);
+ return (size_t)diff;
}
-static int
+static size_t
write_lineno_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin)
{
- uint32_t i;
- uint32_t rlen, size = 0;
+ size_t i;
+ size_t rlen, size = 0;
rlen = write_lineno_record_1(mrb, irep, bin);
bin += rlen;
@@ -394,7 +443,8 @@ write_lineno_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin)
static int
write_section_lineno(mrb_state *mrb, mrb_irep *irep, uint8_t *bin)
{
- uint32_t section_size = 0, rlen = 0; /* size of irep record */
+ size_t section_size = 0;
+ size_t rlen = 0; /* size of irep record */
uint8_t *cur = bin;
if (mrb == NULL || bin == NULL) {
@@ -412,11 +462,12 @@ write_section_lineno(mrb_state *mrb, mrb_irep *irep, uint8_t *bin)
return MRB_DUMP_OK;
}
-static uint32_t
+static size_t
get_debug_record_size(mrb_state *mrb, mrb_irep *irep)
{
- uint32_t ret = 0, f_idx;
- uint32_t i;
+ size_t ret = 0;
+ uint16_t f_idx;
+ size_t i;
ret += sizeof(uint32_t); /* record size */
ret += sizeof(uint16_t); /* file count */
@@ -432,11 +483,11 @@ get_debug_record_size(mrb_state *mrb, mrb_irep *irep)
ret += sizeof(uint8_t); /* line type */
switch(file->line_type) {
case mrb_debug_line_ary:
- ret += sizeof(uint16_t) * file->line_entry_count;
+ ret += sizeof(uint16_t) * (size_t)(file->line_entry_count);
break;
case mrb_debug_line_flat_map:
- ret += (sizeof(uint32_t) + sizeof(uint16_t)) * file->line_entry_count;
+ ret += (sizeof(uint32_t) + sizeof(uint16_t)) * (size_t)(file->line_entry_count);
break;
default: mrb_assert(0); break;
@@ -450,9 +501,9 @@ get_debug_record_size(mrb_state *mrb, mrb_irep *irep)
}
static int
-find_filename_index(const mrb_sym *ary, uint32_t ary_len, mrb_sym s)
+find_filename_index(const mrb_sym *ary, uint16_t ary_len, mrb_sym s)
{
- uint32_t i;
+ int i;
for (i = 0; i < ary_len; ++i) {
if (ary[i] == s) { return i; }
@@ -460,13 +511,13 @@ find_filename_index(const mrb_sym *ary, uint32_t ary_len, mrb_sym s)
return -1;
}
-static uint32_t
-get_filename_table_size(mrb_state *mrb, mrb_irep *irep, mrb_sym **fp, uint32_t *lp)
+static size_t
+get_filename_table_size(mrb_state *mrb, mrb_irep *irep, mrb_sym **fp, uint16_t *lp)
{
mrb_sym *filenames = *fp;
- uint32_t tsize = 0;
+ uint16_t tsize = 0;
uint32_t file_i;
- uint32_t size = 0;
+ size_t size = 0;
mrb_irep_debug_info *di = irep->debug_info;
if (lp == NULL) {
@@ -474,8 +525,8 @@ get_filename_table_size(mrb_state *mrb, mrb_irep *irep, mrb_sym **fp, uint32_t *
}
for (file_i = 0; file_i < di->flen; ++file_i) {
mrb_irep_debug_info_file *file;
- uint32_t filename_len;
- uint32_t i;
+ size_t filename_len;
+ size_t i;
file = di->files[file_i];
if (find_filename_index(filenames, *lp, file->filename_sym) == -1) {
@@ -496,12 +547,12 @@ get_filename_table_size(mrb_state *mrb, mrb_irep *irep, mrb_sym **fp, uint32_t *
return size;
}
-static int
-write_debug_record_1(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const* filenames, uint32_t filenames_len)
+static size_t
+write_debug_record_1(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const* filenames, uint16_t filenames_len)
{
uint8_t *cur;
- uint32_t f_idx;
- uint32_t ret;
+ uint16_t f_idx;
+ ptrdiff_t ret;
cur = bin + sizeof(uint32_t); /* skip record size */
cur += uint16_to_bin(irep->debug_info->flen, cur); /* file count */
@@ -516,8 +567,9 @@ write_debug_record_1(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const
/* filename index */
filename_idx = find_filename_index(filenames, filenames_len,
file->filename_sym);
- mrb_assert(filename_idx != -1);
- cur += uint16_to_bin(filename_idx, cur);
+ mrb_assert(filename_idx >= 0);
+ mrb_assert(filename_idx <= UINT16_MAX);
+ cur += uint16_to_bin((uint16_t)filename_idx, cur);
/* lines */
cur += uint32_to_bin(file->line_entry_count, cur);
@@ -526,15 +578,15 @@ write_debug_record_1(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const
case mrb_debug_line_ary: {
uint32_t l;
for (l = 0; l < file->line_entry_count; ++l) {
- cur += uint16_to_bin(file->line_ary[l], cur);
+ cur += uint16_to_bin(file->lines.ary[l], cur);
}
} break;
case mrb_debug_line_flat_map: {
uint32_t line;
for (line = 0; line < file->line_entry_count; ++line) {
- cur += uint32_to_bin(file->line_flat_map[line].start_pos, cur);
- cur += uint16_to_bin(file->line_flat_map[line].line, cur);
+ cur += uint32_to_bin(file->lines.flat_map[line].start_pos, cur);
+ cur += uint16_to_bin(file->lines.flat_map[line].line, cur);
}
} break;
@@ -543,16 +595,19 @@ write_debug_record_1(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const
}
ret = cur - bin;
+ mrb_assert(ret >= 0);
+ mrb_assert(ret <= UINT32_MAX);
uint32_to_bin(ret, bin);
- return ret;
+ mrb_assert((size_t)ret <= SIZE_MAX);
+ return (size_t)ret;
}
-static uint32_t
-write_debug_record(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const* filenames, uint32_t filenames_len)
+static size_t
+write_debug_record(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const* filenames, uint16_t filenames_len)
{
- uint32_t size, len;
- uint32_t irep_no;
+ size_t size, len;
+ size_t irep_no;
size = len = write_debug_record_1(mrb, irep, bin, filenames, filenames_len);
bin += len;
@@ -566,14 +621,14 @@ write_debug_record(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const*
return size;
}
-static uint32_t
-write_filename_table(mrb_state *mrb, mrb_irep *irep, uint8_t **cp, mrb_sym **fp, uint32_t *lp)
+static size_t
+write_filename_table(mrb_state *mrb, mrb_irep *irep, uint8_t **cp, mrb_sym **fp, uint16_t *lp)
{
uint8_t *cur = *cp;
mrb_sym *filenames = *fp;
uint32_t file_i;
uint16_t fn_len;
- uint32_t size = 0;
+ size_t size = 0;
mrb_irep_debug_info *debug_info = irep->debug_info;
for (file_i = 0; file_i < debug_info->flen; ++file_i) {
@@ -603,13 +658,13 @@ write_filename_table(mrb_state *mrb, mrb_irep *irep, uint8_t **cp, mrb_sym **fp,
static int
write_section_debug(mrb_state *mrb, mrb_irep *irep, uint8_t *cur)
{
- uint32_t section_size = 0;
+ size_t section_size = 0;
const uint8_t *bin = cur;
struct rite_section_debug_header *header;
mrb_sym *filenames;
- uint32_t filenames_len = 0;
+ uint16_t filenames_len = 0;
uint8_t *filenames_len_out;
- uint32_t dlen;
+ size_t dlen;
if (mrb == NULL || cur == NULL) {
return MRB_DUMP_INVALID_ARGUMENT;
@@ -632,6 +687,7 @@ write_section_debug(mrb_state *mrb, mrb_irep *irep, uint8_t *cur)
section_size += dlen;
memcpy(header->section_identify, RITE_SECTION_DEBUG_IDENTIFIER, sizeof(header->section_identify));
+ mrb_assert(section_size <= INT32_MAX);
uint32_to_bin(section_size, header->section_size);
mrb_free(mrb, filenames);
@@ -640,7 +696,7 @@ write_section_debug(mrb_state *mrb, mrb_irep *irep, uint8_t *cur)
}
static int
-write_rite_binary_header(mrb_state *mrb, uint32_t binary_size, uint8_t *bin)
+write_rite_binary_header(mrb_state *mrb, size_t binary_size, uint8_t *bin)
{
struct rite_binary_header *header = (struct rite_binary_header *)bin;
uint16_t crc;
@@ -650,7 +706,8 @@ write_rite_binary_header(mrb_state *mrb, uint32_t binary_size, uint8_t *bin)
memcpy(header->binary_version, RITE_BINARY_FORMAT_VER, sizeof(header->binary_version));
memcpy(header->compiler_name, RITE_COMPILER_NAME, sizeof(header->compiler_name));
memcpy(header->compiler_version, RITE_COMPILER_VERSION, sizeof(header->compiler_version));
- uint32_to_bin(binary_size, header->binary_size);
+ mrb_assert(binary_size <= UINT32_MAX);
+ uint32_to_bin((uint32_t)binary_size, header->binary_size);
offset = (&(header->binary_crc[0]) - bin) + sizeof(uint16_t);
crc = calc_crc_16_ccitt(bin + offset, binary_size - offset, 0);
@@ -662,7 +719,7 @@ write_rite_binary_header(mrb_state *mrb, uint32_t binary_size, uint8_t *bin)
static mrb_bool
is_debug_info_defined(mrb_irep *irep)
{
- uint32_t i;
+ size_t i;
if (!irep->debug_info) return 0;
for (i=0; i<irep->rlen; i++) {
@@ -672,11 +729,11 @@ is_debug_info_defined(mrb_irep *irep)
}
static int
-dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, uint32_t *bin_size)
+dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, size_t *bin_size)
{
int result = MRB_DUMP_GENERAL_FAILURE;
- uint32_t section_irep_size;
- uint32_t section_lineno_size = 0;
+ size_t section_irep_size;
+ size_t section_lineno_size = 0;
uint8_t *cur = NULL;
mrb_bool const debug_info_defined = is_debug_info_defined(irep);
@@ -757,7 +814,7 @@ int
mrb_dump_irep_binary(mrb_state *mrb, mrb_irep *irep, int debug_info, FILE* fp)
{
uint8_t *bin = NULL;
- uint32_t bin_size = 0;
+ size_t bin_size = 0;
int result;
if (fp == NULL) {
@@ -793,7 +850,7 @@ int
mrb_dump_irep_cfunc(mrb_state *mrb, mrb_irep *irep, int debug_info, FILE *fp, const char *initname)
{
uint8_t *bin = NULL;
- uint32_t bin_size = 0, bin_idx = 0;
+ size_t bin_size = 0, bin_idx = 0;
int result;
if (fp == NULL || initname == NULL || !is_valid_c_symbol_name(initname)) {
diff --git a/src/gc.c b/src/gc.c
index 8eda76b26..e87ed3f06 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -1589,5 +1589,5 @@ gc_test(mrb_state *mrb, mrb_value self)
test_incremental_sweep_phase();
return mrb_nil_value();
}
-#endif
-#endif
+#endif /* GC_DEBUG */
+#endif /* GC_TEST */
diff --git a/src/hash.c b/src/hash.c
index af3571eaf..86ad4c63d 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -18,7 +18,7 @@ mrb_hash_ht_hash_func(mrb_state *mrb, mrb_value key)
khint_t h = (khint_t)mrb_type(key) << 24;
mrb_value h2;
- h2 = mrb_funcall(mrb, key, "hash", 0, 0);
+ h2 = mrb_funcall(mrb, key, "hash", 0);
h ^= h2.value.i;
return h;
}
@@ -676,14 +676,14 @@ inspect_hash(mrb_state *mrb, mrb_value hash, int recur)
str2 = mrb_inspect(mrb, kh_key(h,k));
mrb_str_append(mrb, str, str2);
- mrb_str_buf_cat(mrb, str, "=>", 2);
+ mrb_str_cat_lit(mrb, str, "=>");
str2 = mrb_inspect(mrb, kh_value(h,k));
mrb_str_append(mrb, str, str2);
mrb_gc_arena_restore(mrb, ai);
}
}
- mrb_str_buf_cat(mrb, str, "}", 1);
+ mrb_str_cat_lit(mrb, str, "}");
return str;
}
@@ -874,6 +874,7 @@ static mrb_value
hash_equal(mrb_state *mrb, mrb_value hash1, mrb_value hash2, mrb_bool eql)
{
khash_t(ht) *h1, *h2;
+ mrb_bool eq;
if (mrb_obj_equal(mrb, hash1, hash2)) return mrb_true_value();
if (!mrb_hash_p(hash2)) {
@@ -881,8 +882,6 @@ hash_equal(mrb_state *mrb, mrb_value hash1, mrb_value hash2, mrb_bool eql)
return mrb_false_value();
}
else {
- mrb_bool eq;
-
if (eql) {
eq = mrb_eql(mrb, hash2, hash1);
}
@@ -908,7 +907,11 @@ hash_equal(mrb_state *mrb, mrb_value hash1, mrb_value hash2, mrb_bool eql)
key = kh_key(h1,k1);
k2 = kh_get(ht, mrb, h2, key);
if (k2 != kh_end(h2)) {
- if (mrb_eql(mrb, kh_value(h1,k1), kh_value(h2,k2))) {
+ if (eql)
+ eq = mrb_eql(mrb, kh_value(h1,k1), kh_value(h2,k2));
+ else
+ eq = mrb_equal(mrb, kh_value(h1,k1), kh_value(h2,k2));
+ if (eq) {
continue; /* next key */
}
}
diff --git a/src/load.c b/src/load.c
index de517f89f..5762cf2a2 100644
--- a/src/load.c
+++ b/src/load.c
@@ -26,6 +26,10 @@
# error This code assumes CHAR_BIT == 8
#endif
+#if UINT32_MAX > SIZE_MAX
+# error This code cannot be built on your environment.
+#endif
+
static size_t
offset_crc_body(void)
{
@@ -34,10 +38,11 @@ offset_crc_body(void)
}
static mrb_irep*
-read_irep_record_1(mrb_state *mrb, const uint8_t *bin, uint32_t *len, mrb_bool alloc)
+read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool alloc)
{
size_t i;
const uint8_t *src = bin;
+ ptrdiff_t diff;
uint16_t tt, pool_data_len, snl;
size_t plen;
int ai = mrb_gc_arena_save(mrb);
@@ -55,12 +60,12 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, uint32_t *len, mrb_bool a
src += sizeof(uint16_t);
/* number of child irep */
- irep->rlen = bin_to_uint16(src);
+ irep->rlen = (size_t)bin_to_uint16(src);
src += sizeof(uint16_t);
/* Binary Data Section */
/* ISEQ BLOCK */
- irep->ilen = bin_to_uint32(src);
+ irep->ilen = (size_t)bin_to_uint32(src);
src += sizeof(uint32_t);
if (irep->ilen > 0) {
if (SIZE_ERROR_MUL(sizeof(mrb_code), irep->ilen)) {
@@ -71,13 +76,13 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, uint32_t *len, mrb_bool a
return NULL;
}
for (i = 0; i < irep->ilen; i++) {
- irep->iseq[i] = bin_to_uint32(src); /* iseq */
+ irep->iseq[i] = (size_t)bin_to_uint32(src); /* iseq */
src += sizeof(uint32_t);
}
}
/* POOL BLOCK */
- plen = bin_to_uint32(src); /* number of pool */
+ plen = (size_t)bin_to_uint32(src); /* number of pool */
src += sizeof(uint32_t);
if (plen > 0) {
if (SIZE_ERROR_MUL(sizeof(mrb_value), plen)) {
@@ -125,7 +130,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, uint32_t *len, mrb_bool a
}
/* SYMS BLOCK */
- irep->slen = bin_to_uint32(src); /* syms length */
+ irep->slen = (size_t)bin_to_uint32(src); /* syms length */
src += sizeof(uint32_t);
if (irep->slen > 0) {
if (SIZE_ERROR_MUL(sizeof(mrb_sym), irep->slen)) {
@@ -158,20 +163,24 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, uint32_t *len, mrb_bool a
}
irep->reps = (mrb_irep**)mrb_malloc(mrb, sizeof(mrb_irep*)*irep->rlen);
- *len = src - bin;
+
+ diff = src - bin;
+ mrb_assert(diff >= 0);
+ mrb_assert((size_t)diff <= SIZE_MAX);
+ *len = (size_t)diff;
return irep;
}
static mrb_irep*
-read_irep_record(mrb_state *mrb, const uint8_t *bin, uint32_t *len, mrb_bool alloc)
+read_irep_record(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool alloc)
{
mrb_irep *irep = read_irep_record_1(mrb, bin, len, alloc);
size_t i;
bin += *len;
for (i=0; i<irep->rlen; i++) {
- uint32_t rlen;
+ size_t rlen;
irep->reps[i] = read_irep_record(mrb, bin, &rlen, alloc);
bin += rlen;
@@ -183,14 +192,14 @@ read_irep_record(mrb_state *mrb, const uint8_t *bin, uint32_t *len, mrb_bool all
static mrb_irep*
read_section_irep(mrb_state *mrb, const uint8_t *bin, mrb_bool alloc)
{
- uint32_t len;
+ size_t len;
bin += sizeof(struct rite_section_irep_header);
return read_irep_record(mrb, bin, &len, alloc);
}
static int
-read_lineno_record_1(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep, uint32_t *len)
+read_lineno_record_1(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep, size_t *len)
{
int ret;
size_t i, fname_len, niseq;
@@ -216,7 +225,7 @@ read_lineno_record_1(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep, uint32_
bin += fname_len;
*len += fname_len;
- niseq = bin_to_uint32(bin);
+ niseq = (size_t)bin_to_uint32(bin);
bin += sizeof(uint32_t); /* niseq */
*len += sizeof(uint32_t);
@@ -239,14 +248,14 @@ read_lineno_record_1(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep, uint32_
}
static int
-read_lineno_record(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep, uint32_t *lenp)
+read_lineno_record(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep, size_t *lenp)
{
int result = read_lineno_record_1(mrb, bin, irep, lenp);
size_t i;
if (result != MRB_DUMP_OK) return result;
for (i = 0; i < irep->rlen; i++) {
- uint32_t len;
+ size_t len;
result = read_lineno_record(mrb, bin, irep->reps[i], &len);
if (result != MRB_DUMP_OK) break;
@@ -259,7 +268,7 @@ read_lineno_record(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep, uint32_t
static int
read_section_lineno(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep)
{
- uint32_t len;
+ size_t len;
len = 0;
bin += sizeof(struct rite_section_lineno_header);
@@ -269,9 +278,10 @@ read_section_lineno(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep)
}
static int
-read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, uint32_t *len, const mrb_sym *filenames, size_t filenames_len)
+read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t *record_len, const mrb_sym *filenames, size_t filenames_len)
{
const uint8_t *bin = start;
+ ptrdiff_t diff;
size_t record_size, i;
uint16_t f_idx;
@@ -280,7 +290,7 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, uint32_t
irep->debug_info = (mrb_irep_debug_info*)mrb_malloc(mrb, sizeof(mrb_irep_debug_info));
irep->debug_info->pc_count = irep->ilen;
- record_size = bin_to_uint32(bin);
+ record_size = (size_t)bin_to_uint32(bin);
bin += sizeof(uint32_t);
irep->debug_info->flen = bin_to_uint16(bin);
@@ -295,7 +305,8 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, uint32_t
file = (mrb_irep_debug_info_file *)mrb_malloc(mrb, sizeof(*file));
irep->debug_info->files[f_idx] = file;
- file->start_pos = bin_to_uint32(bin); bin += sizeof(uint32_t);
+ file->start_pos = bin_to_uint32(bin);
+ bin += sizeof(uint32_t);
/* filename */
filename_idx = bin_to_uint16(bin);
@@ -305,26 +316,31 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, uint32_t
len = 0;
file->filename = mrb_sym2name_len(mrb, file->filename_sym, &len);
- file->line_entry_count = bin_to_uint32(bin); bin += sizeof(uint32_t);
- file->line_type = (mrb_debug_line_type)bin_to_uint8(bin); bin += sizeof(uint8_t);
+ file->line_entry_count = bin_to_uint32(bin);
+ bin += sizeof(uint32_t);
+ file->line_type = (mrb_debug_line_type)bin_to_uint8(bin);
+ bin += sizeof(uint8_t);
switch(file->line_type) {
case mrb_debug_line_ary: {
- size_t l;
+ uint32_t l;
- file->line_ary = (uint16_t *)mrb_malloc(mrb, sizeof(uint16_t) * file->line_entry_count);
+ file->lines.ary = (uint16_t *)mrb_malloc(mrb, sizeof(uint16_t) * (size_t)(file->line_entry_count));
for(l = 0; l < file->line_entry_count; ++l) {
- file->line_ary[l] = bin_to_uint16(bin); bin += sizeof(uint16_t);
+ file->lines.ary[l] = bin_to_uint16(bin);
+ bin += sizeof(uint16_t);
}
} break;
case mrb_debug_line_flat_map: {
- size_t l;
+ uint32_t l;
- file->line_flat_map = (mrb_irep_debug_info_line*)mrb_malloc(
- mrb, sizeof(mrb_irep_debug_info_line) * file->line_entry_count);
+ file->lines.flat_map = (mrb_irep_debug_info_line*)mrb_malloc(
+ mrb, sizeof(mrb_irep_debug_info_line) * (size_t)(file->line_entry_count));
for(l = 0; l < file->line_entry_count; ++l) {
- file->line_flat_map[l].start_pos = bin_to_uint32(bin); bin += sizeof(uint32_t);
- file->line_flat_map[l].line = bin_to_uint16(bin); bin += sizeof(uint16_t);
+ file->lines.flat_map[l].start_pos = bin_to_uint32(bin);
+ bin += sizeof(uint32_t);
+ file->lines.flat_map[l].line = bin_to_uint16(bin);
+ bin += sizeof(uint16_t);
}
} break;
@@ -332,12 +348,16 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, uint32_t
}
}
- if((long)record_size != (bin - start)) {
+ diff = bin - start;
+ mrb_assert(diff >= 0);
+ mrb_assert((size_t)diff <= SIZE_MAX);
+
+ if(record_size != (size_t)diff) {
return MRB_DUMP_GENERAL_FAILURE;
}
for (i = 0; i < irep->rlen; i++) {
- uint32_t len;
+ size_t len;
int ret;
ret =read_debug_record(mrb, bin, irep->reps[i], &len, filenames, filenames_len);
@@ -345,7 +365,10 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, uint32_t
bin += len;
}
- *len = bin - start;
+ diff = bin - start;
+ mrb_assert(diff >= 0);
+ mrb_assert((size_t)diff <= SIZE_MAX);
+ *record_len = (size_t)diff;
return MRB_DUMP_OK;
}
@@ -354,11 +377,12 @@ static int
read_section_debug(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, mrb_bool alloc)
{
const uint8_t *bin;
+ ptrdiff_t diff;
struct rite_section_debug_header *header;
uint16_t i;
- uint32_t len = 0;
+ size_t len = 0;
int result;
- size_t filenames_len;
+ uint16_t filenames_len;
mrb_sym *filenames;
bin = start;
@@ -367,15 +391,15 @@ read_section_debug(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, mrb_boo
filenames_len = bin_to_uint16(bin);
bin += sizeof(uint16_t);
- filenames = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym) * filenames_len);
+ filenames = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym) * (size_t)filenames_len);
for(i = 0; i < filenames_len; ++i) {
uint16_t f_len = bin_to_uint16(bin);
bin += sizeof(uint16_t);
if (alloc) {
- filenames[i] = mrb_intern(mrb, (const char *)bin, f_len);
+ filenames[i] = mrb_intern(mrb, (const char *)bin, (size_t)f_len);
}
else {
- filenames[i] = mrb_intern_static(mrb, (const char *)bin, f_len);
+ filenames[i] = mrb_intern_static(mrb, (const char *)bin, (size_t)f_len);
}
bin += f_len;
}
@@ -384,7 +408,10 @@ read_section_debug(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, mrb_boo
if (result != MRB_DUMP_OK) goto debug_exit;
bin += len;
- if ((bin - start) != bin_to_uint32(header->section_size)) {
+ diff = bin - start;
+ mrb_assert(diff >= 0);
+ mrb_assert(diff <= UINT32_MAX);
+ if ((uint32_t)diff != bin_to_uint32(header->section_size)) {
result = MRB_DUMP_GENERAL_FAILURE;
}
@@ -408,7 +435,7 @@ read_binary_header(const uint8_t *bin, size_t *bin_size, uint16_t *crc)
*crc = bin_to_uint16(header->binary_crc);
if (bin_size) {
- *bin_size = bin_to_uint32(header->binary_size);
+ *bin_size = (size_t)bin_to_uint32(header->binary_size);
}
return MRB_DUMP_OK;
@@ -504,14 +531,14 @@ read_lineno_record_file(mrb_state *mrb, FILE *fp, mrb_irep *irep)
const size_t record_header_size = sizeof(header);
int result;
size_t i, buf_size;
- uint32_t len;
+ size_t len;
void *ptr;
uint8_t *buf;
if (fread(header, record_header_size, 1, fp) == 0) {
return MRB_DUMP_READ_FAULT;
}
- buf_size = bin_to_uint32(&header[0]);
+ buf_size = (size_t)bin_to_uint32(&header[0]);
if (SIZE_ERROR(buf_size)) {
return MRB_DUMP_GENERAL_FAILURE;
}
@@ -553,7 +580,7 @@ read_irep_record_file(mrb_state *mrb, FILE *fp)
uint8_t header[1 + 4];
const size_t record_header_size = sizeof(header);
size_t buf_size, i;
- uint32_t len;
+ size_t len;
mrb_irep *irep = NULL;
void *ptr;
uint8_t *buf;
@@ -561,7 +588,7 @@ read_irep_record_file(mrb_state *mrb, FILE *fp)
if (fread(header, record_header_size, 1, fp) == 0) {
return NULL;
}
- buf_size = bin_to_uint32(&header[0]);
+ buf_size = (size_t)bin_to_uint32(&header[0]);
if (SIZE_ERROR(buf_size)) {
return NULL;
}
@@ -600,7 +627,7 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp)
int result;
uint8_t *buf;
uint16_t crc, crcwk = 0;
- uint32_t section_size = 0;
+ size_t section_size = 0;
size_t nbytes;
struct rite_section_header section_header;
long fpos;
@@ -657,7 +684,7 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp)
if (fread(&section_header, sizeof(struct rite_section_header), 1, fp) == 0) {
return NULL;
}
- section_size = bin_to_uint32(section_header.section_size);
+ section_size = (size_t)bin_to_uint32(section_header.section_size);
if (memcmp(section_header.section_identify, RITE_SECTION_IREP_IDENTIFIER, sizeof(section_header.section_identify)) == 0) {
fseek(fp, fpos, SEEK_SET);
diff --git a/src/mrb_throw.h b/src/mrb_throw.h
index 859729be6..3c7407a8d 100644
--- a/src/mrb_throw.h
+++ b/src/mrb_throw.h
@@ -38,4 +38,4 @@ struct mrb_jmpbuf {
#endif
};
-#endif
+#endif /* MRB_THROW_H */
diff --git a/src/numeric.c b/src/numeric.c
index 5f23b2461..5d0269e00 100644
--- a/src/numeric.c
+++ b/src/numeric.c
@@ -304,8 +304,8 @@ flodivmod(mrb_state *mrb, mrb_float x, mrb_float y, mrb_float *divp, mrb_float *
mrb_float mod;
if (y == 0.0) {
- div = str_to_mrb_float("inf");
- mod = str_to_mrb_float("nan");
+ div = INFINITY;
+ mod = NAN;
}
else {
mod = fmod(x, y);
@@ -775,7 +775,7 @@ fix_mod(mrb_state *mrb, mrb_value x)
mrb_int mod;
if (mrb_fixnum(y) == 0) {
- return mrb_float_value(mrb, str_to_mrb_float("nan"));
+ return mrb_float_value(mrb, NAN);
}
fixdivmod(mrb, a, mrb_fixnum(y), 0, &mod);
return mrb_fixnum_value(mod);
@@ -805,8 +805,8 @@ fix_divmod(mrb_state *mrb, mrb_value x)
mrb_int div, mod;
if (mrb_fixnum(y) == 0) {
- return mrb_assoc_new(mrb, mrb_float_value(mrb, str_to_mrb_float("inf")),
- mrb_float_value(mrb, str_to_mrb_float("nan")));
+ return mrb_assoc_new(mrb, mrb_float_value(mrb, INFINITY),
+ mrb_float_value(mrb, NAN));
}
fixdivmod(mrb, mrb_fixnum(x), mrb_fixnum(y), &div, &mod);
return mrb_assoc_new(mrb, mrb_fixnum_value(div), mrb_fixnum_value(mod));
diff --git a/src/object.c b/src/object.c
index 2f14c5698..5090e38cf 100644
--- a/src/object.c
+++ b/src/object.c
@@ -440,11 +440,11 @@ mrb_any_to_s(mrb_state *mrb, mrb_value obj)
mrb_value str = mrb_str_buf_new(mrb, 20);
const char *cname = mrb_obj_classname(mrb, obj);
- mrb_str_buf_cat(mrb, str, "#<", 2);
+ mrb_str_cat_lit(mrb, str, "#<");
mrb_str_cat_cstr(mrb, str, cname);
mrb_str_cat_lit(mrb, str, ":");
mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, mrb_cptr(obj)));
- mrb_str_buf_cat(mrb, str, ">", 1);
+ mrb_str_cat_lit(mrb, str, ">");
return str;
}
@@ -588,7 +588,7 @@ mrb_Float(mrb_state *mrb, mrb_value val)
mrb_value
mrb_inspect(mrb_state *mrb, mrb_value obj)
{
- return mrb_obj_as_string(mrb, mrb_funcall(mrb, obj, "inspect", 0, 0));
+ return mrb_obj_as_string(mrb, mrb_funcall(mrb, obj, "inspect", 0));
}
mrb_bool
diff --git a/src/parse.y b/src/parse.y
index b82b3e271..c3460555d 100644
--- a/src/parse.y
+++ b/src/parse.y
@@ -3526,8 +3526,8 @@ static int
scan_hex(const int *start, int len, int *retlen)
{
static const char hexdigit[] = "0123456789abcdef0123456789ABCDEF";
- register const int *s = start;
- register int retval = 0;
+ const int *s = start;
+ int retval = 0;
char *tmp;
/* mrb_assert(len <= 2) */
@@ -3932,7 +3932,7 @@ arg_ambiguous(parser_state *p)
static int
parser_yylex(parser_state *p)
{
- register int c;
+ int c;
int space_seen = 0;
int cmd_state;
enum mrb_lex_state_enum last_state;
diff --git a/src/pool.c b/src/pool.c
index f09df92c5..4d8c42dd1 100644
--- a/src/pool.c
+++ b/src/pool.c
@@ -5,6 +5,7 @@
*/
#include <stddef.h>
+#include <stdint.h>
#include <string.h>
#include "mruby.h"
@@ -36,12 +37,12 @@ struct mrb_pool {
#undef TEST_POOL
#ifdef TEST_POOL
-#define mrb_malloc(m,s) malloc(s)
+#define mrb_malloc_simple(m,s) malloc(s)
#define mrb_free(m,p) free(p)
#endif
#ifdef POOL_ALIGNMENT
-# define ALIGN_PADDING(x) ((-x) & (POOL_ALIGNMENT - 1))
+# define ALIGN_PADDING(x) ((SIZE_MAX - (x) + 1) & (POOL_ALIGNMENT - 1))
#else
# define ALIGN_PADDING(x) (0)
#endif
@@ -49,7 +50,7 @@ struct mrb_pool {
mrb_pool*
mrb_pool_open(mrb_state *mrb)
{
- mrb_pool *pool = (mrb_pool *)mrb_malloc(mrb, sizeof(mrb_pool));
+ mrb_pool *pool = (mrb_pool *)mrb_malloc_simple(mrb, sizeof(mrb_pool));
if (pool) {
pool->mrb = mrb;
@@ -81,7 +82,7 @@ page_alloc(mrb_pool *pool, size_t len)
if (len < POOL_PAGE_SIZE)
len = POOL_PAGE_SIZE;
- page = (struct mrb_pool_page *)mrb_malloc(pool->mrb, sizeof(struct mrb_pool_page)+len);
+ page = (struct mrb_pool_page *)mrb_malloc_simple(pool->mrb, sizeof(struct mrb_pool_page)+len);
if (page) {
page->offset = 0;
page->len = len;
diff --git a/src/re.h b/src/re.h
index a1fe75aab..ee2638b22 100644
--- a/src/re.h
+++ b/src/re.h
@@ -9,4 +9,4 @@
#define REGEXP_CLASS "Regexp"
-#endif
+#endif /* RE_H */
diff --git a/src/string.c b/src/string.c
index 85a3cc2a7..dff8de90f 100644
--- a/src/string.c
+++ b/src/string.c
@@ -41,7 +41,7 @@
const char mrb_digitmap[] = "0123456789abcdefghijklmnopqrstuvwxyz";
typedef struct mrb_shared_string {
- mrb_bool nofree;
+ mrb_bool nofree : 1;
int refcnt;
char *ptr;
mrb_int len;
@@ -54,6 +54,21 @@ typedef struct mrb_shared_string {
static mrb_value str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2);
static mrb_value mrb_str_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len);
+mrb_int
+mrb_str_strlen(mrb_state *mrb, struct RString *s)
+{
+ mrb_int i, max = STR_LEN(s);
+ char *p = STR_PTR(s);
+
+ if (!p) return 0;
+ for (i=0; i<max; i++) {
+ if (p[i] == '\0') {
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte");
+ }
+ }
+ return max;
+}
+
#define RESIZE_CAPA(s,capacity) do {\
if (STR_EMBED_P(s)) {\
if (RSTRING_EMBED_LEN_MAX < (capacity)) {\
@@ -2066,12 +2081,14 @@ char *
mrb_string_value_cstr(mrb_state *mrb, mrb_value *ptr)
{
struct RString *ps = mrb_str_ptr(*ptr);
- char *s = STR_PTR(ps);
+ mrb_int len = mrb_str_strlen(mrb, ps);
+ char *p = STR_PTR(ps);
- if (!s || STR_LEN(ps) != strlen(s)) {
- mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte");
+ if (!p || p[len] != '\0') {
+ mrb_str_modify(mrb, ps);
+ return STR_PTR(ps);
}
- return s;
+ return p;
}
mrb_value
@@ -2518,7 +2535,7 @@ mrb_str_inspect(mrb_state *mrb, mrb_value str)
continue;
}
}
- mrb_str_buf_cat(mrb, result, "\"", 1);
+ mrb_str_cat_lit(mrb, result, "\"");
return result;
}
diff --git a/src/symbol.c b/src/symbol.c
index 95e8ed290..2a7dfa795 100644
--- a/src/symbol.c
+++ b/src/symbol.c
@@ -12,7 +12,7 @@
/* ------------------------------------------------------ */
typedef struct symbol_name {
- mrb_bool lit;
+ mrb_bool lit : 1;
uint16_t len;
const char *name;
} symbol_name;
@@ -35,7 +35,7 @@ KHASH_DECLARE(n2s, symbol_name, mrb_sym, 1)
KHASH_DEFINE (n2s, symbol_name, mrb_sym, 1, sym_hash_func, sym_hash_equal)
/* ------------------------------------------------------ */
static mrb_sym
-sym_intern(mrb_state *mrb, const char *name, size_t len, int lit)
+sym_intern(mrb_state *mrb, const char *name, size_t len, mrb_bool lit)
{
khash_t(n2s) *h = mrb->name2sym;
symbol_name sname;
@@ -72,13 +72,13 @@ sym_intern(mrb_state *mrb, const char *name, size_t len, int lit)
mrb_sym
mrb_intern(mrb_state *mrb, const char *name, size_t len)
{
- return sym_intern(mrb, name, len, 0);
+ return sym_intern(mrb, name, len, FALSE);
}
mrb_sym
mrb_intern_static(mrb_state *mrb, const char *name, size_t len)
{
- return sym_intern(mrb, name, len, 1);
+ return sym_intern(mrb, name, len, TRUE);
}
mrb_sym
diff --git a/src/variable.c b/src/variable.c
index c313a8f14..bfffb727f 100644
--- a/src/variable.c
+++ b/src/variable.c
@@ -596,7 +596,7 @@ mrb_obj_iv_inspect(mrb_state *mrb, struct RObject *obj)
const char *cn = mrb_obj_classname(mrb, mrb_obj_value(obj));
mrb_value str = mrb_str_buf_new(mrb, 30);
- mrb_str_buf_cat(mrb, str, "-<", 2);
+ mrb_str_cat_lit(mrb, str, "-<");
mrb_str_cat_cstr(mrb, str, cn);
mrb_str_cat_lit(mrb, str, ":");
mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, obj));
diff --git a/tasks/mrbgem_spec.rake b/tasks/mrbgem_spec.rake
index daf0bec3a..60d6672f0 100644
--- a/tasks/mrbgem_spec.rake
+++ b/tasks/mrbgem_spec.rake
@@ -43,6 +43,10 @@ module MRuby
MRuby::Gem.current = self
end
+ def run_test_in_other_mrb_state?
+ not test_preload.nil? or not test_objs.empty?
+ end
+
def cxx_abi_enabled?
@cxx_abi_enabled
end
diff --git a/tasks/mrbgems_test.rake b/tasks/mrbgems_test.rake
index 33f1fdb48..4c27686f2 100644
--- a/tasks/mrbgems_test.rake
+++ b/tasks/mrbgems_test.rake
@@ -1,5 +1,12 @@
MRuby.each_target do
+ no_mrb_open_test_gem = []
+
gems.each do |g|
+ unless g.run_test_in_other_mrb_state?
+ no_mrb_open_test_gem << g
+ next
+ end
+
test_rbobj = g.test_rbireps.ext(exts.object)
file test_rbobj => g.test_rbireps
@@ -10,6 +17,13 @@ MRuby.each_target do
File.expand_path(g.test_preload, dir)
}.find {|file| File.exist?(file) }
+ f.puts %Q[/*]
+ f.puts %Q[ * This file contains a test code for #{g.name} gem.]
+ f.puts %Q[ *]
+ f.puts %Q[ * IMPORTANT:]
+ f.puts %Q[ * This file was generated!]
+ f.puts %Q[ * All manual changes will get lost.]
+ f.puts %Q[ */]
if test_preload.nil?
f.puts %Q[extern const uint8_t mrbtest_assert_irep[];]
else
@@ -79,8 +93,7 @@ MRuby.each_target do
f.puts %Q[ val2 = mrb_ary_shift(mrb2, ary2);]
f.puts %Q[ ]
f.puts %Q[ while (mrb_test(val2)) {]
- f.puts %Q[ char *str = mrb_string_value_cstr(mrb2, &val2);]
- f.puts %Q[ mrb_ary_push(mrb, ary1, mrb_str_new_cstr(mrb, str));]
+ f.puts %Q[ mrb_ary_push(mrb, ary1, mrb_str_new(mrb, RSTRING_PTR(val2), RSTRING_LEN(val2)));]
f.puts %Q[ val2 = mrb_ary_shift(mrb2, ary2);]
f.puts %Q[ }]
f.puts %Q[ }]
@@ -93,4 +106,37 @@ MRuby.each_target do
end
end
+
+ no_mrb_open_test = "#{build_dir}/test/no_mrb_open_test"
+ no_mrb_open_test_rbfiles = no_mrb_open_test_gem.reduce([]) { |res, v|
+ res += v.test_rbfiles
+ }
+ file "#{no_mrb_open_test}.o" => "#{no_mrb_open_test}.c"
+ file "#{no_mrb_open_test}.c" => no_mrb_open_test_rbfiles do |t|
+ open(t.name, 'w') do |f|
+ f.puts %Q[/*]
+ f.puts %Q[ * This file contains a test code for following gems:]
+ no_mrb_open_test_gem.each { |g| f.puts %Q[ * #{g.name}] }
+ f.puts %Q[ *]
+ f.puts %Q[ * IMPORTANT:]
+ f.puts %Q[ * This file was generated!]
+ f.puts %Q[ * All manual changes will get lost.]
+ f.puts %Q[ */]
+
+ f.puts %Q[]
+
+ f.puts %Q[\#include "mruby.h"]
+ f.puts %Q[\#include "mruby/irep.h"]
+
+ f.puts %Q[]
+
+ mrbc.run f, no_mrb_open_test_rbfiles, "no_mrb_open_gem_test_irep"
+
+ f.puts %Q[]
+
+ f.puts %Q[void no_mrb_open_mrbgem_test(mrb_state *mrb) {]
+ f.puts %Q[ mrb_load_irep(mrb, no_mrb_open_gem_test_irep);]
+ f.puts %Q[}]
+ end
+ end
end
diff --git a/test/assert.rb b/test/assert.rb
index d2d865649..1e9a781d6 100644
--- a/test/assert.rb
+++ b/test/assert.rb
@@ -174,6 +174,24 @@ def assert_raise(*exp)
ret
end
+def assert_nothing_raised(*exp)
+ ret = true
+ if $mrbtest_assert
+ $mrbtest_assert_idx += 1
+ msg = exp.last.class == String ? exp.pop : ""
+ begin
+ yield
+ rescue Exception => e
+ msg = "#{msg} exception raised."
+ diff = " Class: <#{e.class}>\n" +
+ " Message: #{e.message}"
+ $mrbtest_assert.push([$mrbtest_assert_idx, msg, diff])
+ ret = false
+ end
+ end
+ ret
+end
+
##
# Fails unless +obj+ is a kind of +cls+.
def assert_kind_of(cls, obj, msg = nil)
diff --git a/test/mrbtest.rake b/test/mrbtest.rake
index 35495889e..1c52eafbd 100644
--- a/test/mrbtest.rake
+++ b/test/mrbtest.rake
@@ -12,9 +12,11 @@ MRuby.each_target do
ass_lib = ass_c.ext(exts.object)
mrbtest_lib = libfile("#{current_build_dir}/mrbtest")
- file mrbtest_lib => [mlib, ass_lib, gems.map(&:test_objs), gems.map { |g| g.test_rbireps.ext(exts.object) }].flatten do |t|
+ gem_test_files = gems.select { |g| g.run_test_in_other_mrb_state? }.map { |g| g.test_rbireps.ext(exts.object) }
+ file mrbtest_lib => [mlib, ass_lib, gems.map(&:test_objs), gem_test_files].flatten do |t|
archiver.run t.name, t.prerequisites
end
+ file mrbtest_lib => "#{build_dir}/test/no_mrb_open_test.o"
unless build_mrbtest_lib_only?
driver_obj = objfile("#{current_build_dir}/driver")
@@ -41,15 +43,28 @@ MRuby.each_target do
_pp "GEN", "*.rb", "#{clib.relative_path}"
FileUtils.mkdir_p File.dirname(clib)
open(clib, 'w') do |f|
+ f.puts %Q[/*]
+ f.puts %Q[ * This file contains a list of all]
+ f.puts %Q[ * test functions.]
+ f.puts %Q[ *]
+ f.puts %Q[ * IMPORTANT:]
+ f.puts %Q[ * This file was generated!]
+ f.puts %Q[ * All manual changes will get lost.]
+ f.puts %Q[ */]
+ f.puts %Q[]
f.puts IO.read(init)
mrbc.run f, mrbs, 'mrbtest_irep'
gems.each do |g|
+ next unless g.run_test_in_other_mrb_state?
f.puts %Q[void GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb_state *mrb);]
end
+ f.puts %Q[void no_mrb_open_mrbgem_test(mrb_state *mrb);]
f.puts %Q[void mrbgemtest_init(mrb_state* mrb) {]
gems.each do |g|
+ next unless g.run_test_in_other_mrb_state?
f.puts %Q[ GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb);]
end
+ f.puts %Q[ no_mrb_open_mrbgem_test(mrb);]
f.puts %Q[}]
end
end
diff --git a/test/t/hash.rb b/test/t/hash.rb
index 92bc223b6..e7d5e8f74 100644
--- a/test/t/hash.rb
+++ b/test/t/hash.rb
@@ -12,6 +12,7 @@ end
assert('Hash#==', '15.2.13.4.1') do
assert_true({ 'abc' => 'abc' } == { 'abc' => 'abc' })
assert_false({ 'abc' => 'abc' } == { 'cba' => 'cba' })
+ assert_true({ :equal => 1 } == { :equal => 1.0 })
end
assert('Hash#[]', '15.2.13.4.2') do