summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/class.c52
-rw-r--r--src/codegen.c141
-rw-r--r--src/debug.c26
-rw-r--r--src/dump.c237
-rw-r--r--src/etc.c8
-rw-r--r--src/gc.c4
-rw-r--r--src/hash.c61
-rw-r--r--src/kernel.c34
-rw-r--r--src/load.c121
-rw-r--r--src/mrb_throw.h2
-rw-r--r--src/node.h208
-rw-r--r--src/numeric.c33
-rw-r--r--src/object.c14
-rw-r--r--src/parse.y19
-rw-r--r--src/pool.c9
-rw-r--r--src/print.c9
-rw-r--r--src/re.h2
-rw-r--r--src/state.c23
-rw-r--r--src/string.c465
-rw-r--r--src/symbol.c44
-rw-r--r--src/variable.c10
-rw-r--r--src/vm.c16
22 files changed, 874 insertions, 664 deletions
diff --git a/src/class.c b/src/class.c
index 8188db131..1a55009e4 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;
}
@@ -511,7 +518,6 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
case 's':
{
mrb_value ss;
- struct RString *s;
char **ps = 0;
int *pl = 0;
@@ -519,9 +525,8 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
pl = va_arg(ap, int*);
if (i < argc) {
ss = to_str(mrb, *sp++);
- s = mrb_str_ptr(ss);
- *ps = s->ptr;
- *pl = s->len;
+ *ps = RSTRING_PTR(ss);
+ *pl = RSTRING_LEN(ss);
i++;
}
}
@@ -529,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(s->ptr);
- if (len < s->len) {
- mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte");
- }
- else if (len > s->len) {
- mrb_str_modify(mrb, s);
- }
- *ps = s->ptr;
+ *ps = mrb_string_value_cstr(mrb, &ss);
i++;
}
}
@@ -691,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 '*':
{
@@ -1255,7 +1258,7 @@ mrb_class_path(mrb_state *mrb, struct RClass *c)
{
mrb_value path;
const char *name;
- size_t len;
+ mrb_int len;
mrb_sym classpath = mrb_intern_lit(mrb, "__classpath__");
path = mrb_obj_iv_get(mrb, (struct RObject*)c, classpath);
@@ -1298,7 +1301,7 @@ mrb_class_name(mrb_state *mrb, struct RClass* c)
mrb_str_concat(mrb, path, mrb_ptr_to_str(mrb, c));
mrb_str_cat_lit(mrb, path, ">");
}
- return mrb_str_ptr(path)->ptr;
+ return RSTRING_PTR(path);
}
const char*
@@ -1542,7 +1545,7 @@ static void
check_cv_name_sym(mrb_state *mrb, mrb_sym id)
{
const char *s;
- size_t len;
+ mrb_int len;
s = mrb_sym2name_len(mrb, id, &len);
if (len < 3 || !(s[0] == '@' && s[1] == '@')) {
@@ -1554,7 +1557,8 @@ static void
check_cv_name_str(mrb_state *mrb, mrb_value str)
{
const char *s = RSTRING_PTR(str);
- size_t const len = RSTRING_LEN(str);
+ mrb_int len = RSTRING_LEN(str);
+
if (len < 3 || !(s[0] == '@' && s[1] == '@')) {
mrb_name_error(mrb, mrb_intern_str(mrb, str), "`%S' is not allowed as a class variable name", str);
}
@@ -1814,7 +1818,7 @@ static void
check_const_name_sym(mrb_state *mrb, mrb_sym id)
{
const char *s;
- size_t len;
+ mrb_int len;
s = mrb_sym2name_len(mrb, id, &len);
if (len < 1 || !ISUPPER(*s)) {
diff --git a/src/codegen.c b/src/codegen.c
index 77bc5e34e..60da17f2b 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"
@@ -139,7 +140,7 @@ new_label(codegen_scope *s)
return s->pc;
}
-static inline void
+static inline int
genop(codegen_scope *s, mrb_code i)
{
if (s->pc == s->icapa) {
@@ -154,13 +155,13 @@ genop(codegen_scope *s, mrb_code i)
if (s->lines) {
s->lines[s->pc] = s->lineno;
}
- s->pc++;
+ return s->pc++;
}
#define NOVAL 0
#define VAL 1
-static void
+static int
genop_peep(codegen_scope *s, mrb_code i, int val)
{
/* peephole optimization */
@@ -173,24 +174,24 @@ genop_peep(codegen_scope *s, mrb_code i, int val)
case OP_MOVE:
if (GETARG_A(i) == GETARG_B(i)) {
/* skip useless OP_MOVE */
- return;
+ return 0;
}
if (val) break;
switch (c0) {
case OP_MOVE:
if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i) == GETARG_B(i0) && GETARG_A(i) >= s->nlocals) {
/* skip swapping OP_MOVE */
- return;
+ return 0;
}
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;
+ return 0;
}
break;
case OP_LOADI:
if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
s->iseq[s->pc-1] = MKOP_AsBx(OP_LOADI, GETARG_A(i), GETARG_sBx(i0));
- return;
+ return 0;
}
break;
case OP_ARRAY:
@@ -200,7 +201,7 @@ genop_peep(codegen_scope *s, mrb_code i, int val)
case OP_GETUPVAR:
if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
s->iseq[s->pc-1] = MKOP_ABC(c0, GETARG_A(i), GETARG_B(i0), GETARG_C(i0));
- return;
+ return 0;
}
break;
case OP_LOADSYM:
@@ -213,13 +214,13 @@ genop_peep(codegen_scope *s, mrb_code i, int val)
case OP_STRING:
if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
s->iseq[s->pc-1] = MKOP_ABx(c0, GETARG_A(i), GETARG_Bx(i0));
- return;
+ return 0;
}
break;
case OP_SCLASS:
if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
s->iseq[s->pc-1] = MKOP_AB(c0, GETARG_A(i), GETARG_B(i0));
- return;
+ return 0;
}
break;
case OP_LOADNIL:
@@ -229,7 +230,7 @@ genop_peep(codegen_scope *s, mrb_code i, int val)
case OP_OCLASS:
if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
s->iseq[s->pc-1] = MKOP_A(c0, GETARG_A(i));
- return;
+ return 0;
}
break;
default:
@@ -245,7 +246,7 @@ genop_peep(codegen_scope *s, mrb_code i, int val)
if (c0 == OP_MOVE) {
if (GETARG_A(i) == GETARG_A(i0)) {
s->iseq[s->pc-1] = MKOP_ABx(c1, GETARG_B(i0), GETARG_Bx(i));
- return;
+ return 0;
}
}
break;
@@ -254,29 +255,29 @@ genop_peep(codegen_scope *s, mrb_code i, int val)
if (c0 == OP_MOVE) {
if (GETARG_A(i) == GETARG_A(i0)) {
s->iseq[s->pc-1] = MKOP_ABC(c1, GETARG_B(i0), GETARG_B(i), GETARG_C(i));
- return;
+ return 0;
}
}
break;
case OP_EPOP:
if (c0 == OP_EPOP) {
s->iseq[s->pc-1] = MKOP_A(OP_EPOP, GETARG_A(i0)+GETARG_A(i));
- return;
+ return 0;
}
break;
case OP_POPERR:
if (c0 == OP_POPERR) {
s->iseq[s->pc-1] = MKOP_A(OP_POPERR, GETARG_A(i0)+GETARG_A(i));
- return;
+ return 0;
}
break;
case OP_RETURN:
switch (c0) {
case OP_RETURN:
- return;
+ return 0;
case OP_MOVE:
s->iseq[s->pc-1] = MKOP_AB(OP_RETURN, GETARG_B(i0), OP_R_NORMAL);
- return;
+ return 0;
case OP_SETIV:
case OP_SETCV:
case OP_SETCONST:
@@ -286,8 +287,7 @@ genop_peep(codegen_scope *s, mrb_code i, int val)
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;
+ return genop(s, MKOP_AB(OP_RETURN, GETARG_A(i0), OP_R_NORMAL));
#if 0
case OP_SEND:
if (GETARG_B(i) == OP_R_NORMAL && GETARG_A(i) == GETARG_A(i0)) {
@@ -311,7 +311,7 @@ genop_peep(codegen_scope *s, mrb_code i, int val)
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;
+ return 0;
}
case OP_STRCAT:
if (c0 == OP_STRING) {
@@ -320,15 +320,22 @@ genop_peep(codegen_scope *s, mrb_code i, int val)
if (mrb_type(s->irep->pool[i]) == MRB_TT_STRING &&
RSTRING_LEN(s->irep->pool[i]) == 0) {
s->pc--;
- return;
+ return 0;
}
}
break;
+ case OP_JMPIF:
+ case OP_JMPNOT:
+ if (c0 == OP_MOVE && GETARG_A(i) == GETARG_A(i0)) {
+ s->iseq[s->pc-1] = MKOP_AsBx(c1, GETARG_B(i0), GETARG_sBx(i));
+ return s->pc-1;
+ }
+ break;
default:
break;
}
}
- genop(s, i);
+ return genop(s, i);
}
static void
@@ -700,12 +707,16 @@ static mrb_sym
attrsym(codegen_scope *s, mrb_sym a)
{
const char *name;
- size_t len;
+ mrb_int len;
char *name2;
name = mrb_sym2name_len(s->mrb, a, &len);
- name2 = (char *)codegen_palloc(s, len+1);
- memcpy(name2, name, len);
+ name2 = (char *)codegen_palloc(s,
+ (size_t)len
+ + 1 /* '=' */
+ + 1 /* '\0' */
+ );
+ memcpy(name2, name, (size_t)len);
name2[len] = '=';
name2[len+1] = '\0';
@@ -806,7 +817,7 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val)
}
pop_n(n+1);
{
- size_t len;
+ mrb_int len;
const char *name = mrb_sym2name_len(s->mrb, sym, &len);
if (!noop && len == 1 && name[0] == '+') {
@@ -1146,8 +1157,7 @@ codegen(codegen_scope *s, node *tree, int val)
int onerr, noexc, exend, pos1, pos2, tmp;
struct loopinfo *lp;
- onerr = new_label(s);
- genop(s, MKOP_Bx(OP_ONERR, 0));
+ onerr = genop(s, MKOP_Bx(OP_ONERR, 0));
lp = loop_push(s, LOOP_BEGIN);
lp->pc1 = onerr;
if (tree->car) {
@@ -1155,8 +1165,7 @@ codegen(codegen_scope *s, node *tree, int val)
if (val) pop();
}
lp->type = LOOP_RESCUE;
- noexc = new_label(s);
- genop(s, MKOP_Bx(OP_JMP, 0));
+ noexc = genop(s, MKOP_Bx(OP_JMP, 0));
dispatch(s, onerr);
tree = tree->cdr;
exend = 0;
@@ -1183,16 +1192,19 @@ codegen(codegen_scope *s, node *tree, int val)
}
genop(s, MKOP_AB(OP_MOVE, cursp(), exc));
pop();
- genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "===")), 1));
- tmp = new_label(s);
- genop(s, MKOP_AsBx(OP_JMPIF, cursp(), pos2));
+ if (n4 && n4->car && (intptr_t)n4->car->car == NODE_SPLAT) {
+ genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "__case_eqq")), 1));
+ }
+ else {
+ genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "===")), 1));
+ }
+ tmp = genop(s, MKOP_AsBx(OP_JMPIF, cursp(), pos2));
pos2 = tmp;
if (n4) {
n4 = n4->cdr;
}
} while (n4);
- pos1 = new_label(s);
- genop(s, MKOP_sBx(OP_JMP, 0));
+ pos1 = genop(s, MKOP_sBx(OP_JMP, 0));
dispatch_linked(s, pos2);
pop();
@@ -1203,8 +1215,7 @@ codegen(codegen_scope *s, node *tree, int val)
codegen(s, n3->cdr->cdr->car, val);
if (val) pop();
}
- tmp = new_label(s);
- genop(s, MKOP_sBx(OP_JMP, exend));
+ tmp = genop(s, MKOP_sBx(OP_JMP, exend));
exend = tmp;
n2 = n2->cdr;
push();
@@ -1269,8 +1280,7 @@ codegen(codegen_scope *s, node *tree, int val)
codegen(s, tree->car, VAL);
pop();
- pos1 = new_label(s);
- genop(s, MKOP_AsBx(OP_JMPNOT, cursp(), 0));
+ pos1 = genop_peep(s, MKOP_AsBx(OP_JMPNOT, cursp(), 0), NOVAL);
codegen(s, tree->cdr->car, val);
if (val && !(tree->cdr->car)) {
@@ -1279,17 +1289,15 @@ codegen(codegen_scope *s, node *tree, int val)
}
if (e) {
if (val) pop();
- pos2 = new_label(s);
- genop(s, MKOP_sBx(OP_JMP, 0));
- dispatch(s, pos1);
+ pos2 = genop(s, MKOP_sBx(OP_JMP, 0));
+ dispatch(s, pos1);
codegen(s, e, val);
dispatch(s, pos2);
}
else {
if (val) {
pop();
- pos2 = new_label(s);
- genop(s, MKOP_sBx(OP_JMP, 0));
+ pos2 = genop(s, MKOP_sBx(OP_JMP, 0));
dispatch(s, pos1);
genop(s, MKOP_A(OP_LOADNIL, cursp()));
dispatch(s, pos2);
@@ -1307,9 +1315,8 @@ codegen(codegen_scope *s, node *tree, int val)
int pos;
codegen(s, tree->car, VAL);
- pos = new_label(s);
pop();
- genop(s, MKOP_AsBx(OP_JMPNOT, cursp(), 0));
+ pos = genop(s, MKOP_AsBx(OP_JMPNOT, cursp(), 0));
codegen(s, tree->cdr, val);
dispatch(s, pos);
}
@@ -1320,9 +1327,8 @@ codegen(codegen_scope *s, node *tree, int val)
int pos;
codegen(s, tree->car, VAL);
- pos = new_label(s);
pop();
- genop(s, MKOP_AsBx(OP_JMPIF, cursp(), 0));
+ pos = genop(s, MKOP_AsBx(OP_JMPIF, cursp(), 0));
codegen(s, tree->cdr, val);
dispatch(s, pos);
}
@@ -1332,8 +1338,7 @@ codegen(codegen_scope *s, node *tree, int val)
{
struct loopinfo *lp = loop_push(s, LOOP_NORMAL);
- lp->pc1 = new_label(s);
- genop(s, MKOP_sBx(OP_JMP, 0));
+ lp->pc1 = genop(s, MKOP_sBx(OP_JMP, 0));
lp->pc2 = new_label(s);
codegen(s, tree->cdr, NOVAL);
dispatch(s, lp->pc1);
@@ -1349,8 +1354,7 @@ codegen(codegen_scope *s, node *tree, int val)
{
struct loopinfo *lp = loop_push(s, LOOP_NORMAL);
- lp->pc1 = new_label(s);
- genop(s, MKOP_sBx(OP_JMP, 0));
+ lp->pc1 = genop(s, MKOP_sBx(OP_JMP, 0));
lp->pc2 = new_label(s);
codegen(s, tree->cdr, NOVAL);
dispatch(s, lp->pc1);
@@ -1397,20 +1401,17 @@ codegen(codegen_scope *s, node *tree, int val)
else {
pop();
}
- tmp = new_label(s);
- genop(s, MKOP_AsBx(OP_JMPIF, cursp(), pos2));
+ tmp = genop(s, MKOP_AsBx(OP_JMPIF, cursp(), pos2));
pos2 = tmp;
n = n->cdr;
}
if (tree->car->car) {
- pos1 = new_label(s);
- genop(s, MKOP_sBx(OP_JMP, 0));
+ pos1 = genop(s, MKOP_sBx(OP_JMP, 0));
dispatch_linked(s, pos2);
}
codegen(s, tree->car->cdr, val);
if (val) pop();
- tmp = new_label(s);
- genop(s, MKOP_sBx(OP_JMP, pos3));
+ tmp = genop(s, MKOP_sBx(OP_JMP, pos3));
pos3 = tmp;
if (pos1) dispatch(s, pos1);
tree = tree->cdr;
@@ -1591,7 +1592,7 @@ codegen(codegen_scope *s, node *tree, int val)
case NODE_OP_ASGN:
{
mrb_sym sym = sym(tree->cdr->car);
- size_t len;
+ mrb_int len;
const char *name = mrb_sym2name_len(s->mrb, sym, &len);
int idx;
@@ -1602,8 +1603,7 @@ codegen(codegen_scope *s, node *tree, int val)
int pos;
pop();
- pos = new_label(s);
- genop(s, MKOP_AsBx(name[0] == '|' ? OP_JMPIF : OP_JMPNOT, cursp(), 0));
+ pos = genop_peep(s, MKOP_AsBx(name[0] == '|' ? OP_JMPIF : OP_JMPNOT, cursp(), 0), NOVAL);
codegen(s, tree->cdr->cdr->car, VAL);
pop();
gen_assignment(s, tree->car, cursp(), val);
@@ -1905,7 +1905,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));
@@ -2097,7 +2097,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()));
@@ -2106,7 +2106,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();
@@ -2143,7 +2143,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();
@@ -2154,7 +2154,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();
@@ -2548,8 +2548,7 @@ loop_break(codegen_scope *s, node *tree)
if (tree) {
genop_peep(s, MKOP_AB(OP_MOVE, loop->acc, cursp()), NOVAL);
}
- tmp = new_label(s);
- genop(s, MKOP_sBx(OP_JMP, loop->pc3));
+ tmp = genop(s, MKOP_sBx(OP_JMP, loop->pc3));
loop->pc3 = tmp;
}
else {
@@ -2573,14 +2572,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..ae7705610 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;
@@ -127,7 +127,7 @@ mrb_debug_info_append_file(mrb_state *mrb, mrb_irep *irep,
mrb_irep_debug_info_file *ret;
uint32_t file_pc_count;
size_t fn_len;
- size_t len;
+ mrb_int len;
uint32_t i;
if (!irep->debug_info) { return NULL; }
@@ -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 ca53abe3d..559d26030 100644
--- a/src/dump.c
+++ b/src/dump.c
@@ -6,6 +6,7 @@
#include <ctype.h>
#include <string.h>
+#include <limits.h>
#include "mruby/dump.h"
#include "mruby/string.h"
#include "mruby/irep.h"
@@ -14,10 +15,14 @@
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 +30,7 @@ get_irep_header_size(mrb_state *mrb)
return size;
}
-static size_t
+static ptrdiff_t
write_irep_header(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
{
uint8_t *cur = buf;
@@ -35,31 +40,33 @@ 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 int
+static ptrdiff_t
write_iseq_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
{
uint8_t *cur = buf;
- size_t iseq_no;
+ uint32_t iseq_no;
cur += uint32_to_bin(irep->ilen, cur); /* number of opcode */
for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) {
cur += uint32_to_bin(irep->iseq[iseq_no], cur); /* opcode */
}
- return (cur - buf);
+ return cur - buf;
}
@@ -68,7 +75,6 @@ get_pool_block_size(mrb_state *mrb, mrb_irep *irep)
{
size_t size = 0;
size_t pool_no;
- int len;
mrb_value str;
char buf[32];
@@ -81,16 +87,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 +123,12 @@ get_pool_block_size(mrb_state *mrb, mrb_irep *irep)
return size;
}
-static int
+static ptrdiff_t
write_pool_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
{
size_t pool_no;
uint8_t *cur = buf;
- size_t len;
+ uint16_t len;
mrb_value str;
const char *char_ptr;
char char_buf[30];
@@ -122,19 +143,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,13 +181,13 @@ 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 (int)(cur - buf);
+ return cur - buf;
}
@@ -156,8 +195,8 @@ static size_t
get_syms_block_size(mrb_state *mrb, mrb_irep *irep)
{
size_t size = 0;
- size_t sym_no;
- size_t len;
+ uint32_t sym_no;
+ mrb_int len;
size += sizeof(uint32_t); /* slen */
for (sym_no = 0; sym_no < irep->slen; sym_no++) {
@@ -171,10 +210,10 @@ get_syms_block_size(mrb_state *mrb, mrb_irep *irep)
return size;
}
-static int
+static ptrdiff_t
write_syms_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
{
- size_t sym_no;
+ uint32_t sym_no;
uint8_t *cur = buf;
const char *name;
@@ -182,13 +221,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) {
- size_t len;
+ mrb_int 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 +236,13 @@ write_syms_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
}
}
- return (int)(cur - buf);
+ return cur - buf;
}
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);
@@ -217,7 +254,7 @@ get_irep_record_size_1(mrb_state *mrb, mrb_irep *irep)
static size_t
get_irep_record_size(mrb_state *mrb, mrb_irep *irep)
{
- uint32_t size = 0;
+ size_t size = 0;
size_t irep_no;
size = get_irep_record_size_1(mrb, irep);
@@ -228,9 +265,9 @@ 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)
{
- size_t i;
+ uint32_t i;
if (irep == NULL) {
return MRB_DUMP_INVALID_IREP;
@@ -250,19 +287,19 @@ 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;
}
-static size_t
+static uint32_t
write_footer(mrb_state *mrb, uint8_t *bin)
{
struct rite_binary_footer footer;
@@ -276,12 +313,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 +329,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,25 +340,24 @@ 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;
}
@@ -338,21 +376,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;
- size_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 +404,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 +414,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);
- return (cur - bin);
+ uint32_to_bin((uint32_t)diff, bin); /* record size */
+
+ 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)
{
size_t i;
- uint32_t rlen, size = 0;
+ size_t rlen, size = 0;
rlen = write_lineno_record_1(mrb, irep, bin);
bin += rlen;
@@ -394,7 +444,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) {
@@ -416,7 +467,7 @@ static size_t
get_debug_record_size(mrb_state *mrb, mrb_irep *irep)
{
size_t ret = 0;
- uint32_t f_idx;
+ uint16_t f_idx;
size_t i;
ret += sizeof(uint32_t); /* record size */
@@ -433,11 +484,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;
@@ -451,9 +502,9 @@ get_debug_record_size(mrb_state *mrb, mrb_irep *irep)
}
static int
-find_filename_index(const mrb_sym *ary, size_t ary_len, mrb_sym s)
+find_filename_index(const mrb_sym *ary, uint16_t ary_len, mrb_sym s)
{
- size_t i;
+ int i;
for (i = 0; i < ary_len; ++i) {
if (ary[i] == s) { return i; }
@@ -462,11 +513,11 @@ find_filename_index(const mrb_sym *ary, size_t ary_len, mrb_sym s)
}
static size_t
-get_filename_table_size(mrb_state *mrb, mrb_irep *irep, mrb_sym **fp, size_t *lp)
+get_filename_table_size(mrb_state *mrb, mrb_irep *irep, mrb_sym **fp, uint16_t *lp)
{
mrb_sym *filenames = *fp;
- size_t tsize = 0;
- size_t file_i;
+ uint16_t tsize = 0;
+ uint32_t file_i;
size_t size = 0;
mrb_irep_debug_info *di = irep->debug_info;
@@ -475,7 +526,7 @@ get_filename_table_size(mrb_state *mrb, mrb_irep *irep, mrb_sym **fp, size_t *lp
}
for (file_i = 0; file_i < di->flen; ++file_i) {
mrb_irep_debug_info_file *file;
- size_t filename_len;
+ mrb_int filename_len;
size_t i;
file = di->files[file_i];
@@ -487,7 +538,7 @@ get_filename_table_size(mrb_state *mrb, mrb_irep *irep, mrb_sym **fp, size_t *lp
/* filename */
mrb_sym2name_len(mrb, file->filename_sym, &filename_len);
- size += sizeof(uint16_t) + filename_len;
+ size += sizeof(uint16_t) + (size_t)filename_len;
}
for (i=0; i<irep->rlen; i++) {
size += get_filename_table_size(mrb, irep->reps[i], fp, lp);
@@ -497,12 +548,12 @@ get_filename_table_size(mrb_state *mrb, mrb_irep *irep, mrb_sym **fp, size_t *lp
return size;
}
-static int
-write_debug_record_1(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const* filenames, size_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;
- size_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 */
@@ -517,25 +568,26 @@ 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);
cur += uint8_to_bin(file->line_type, cur);
switch(file->line_type) {
case mrb_debug_line_ary: {
- size_t l;
+ 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;
@@ -544,15 +596,18 @@ 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 int
-write_debug_record(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const* filenames, size_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;
+ size_t size, len;
size_t irep_no;
size = len = write_debug_record_1(mrb, irep, bin, filenames, filenames_len);
@@ -563,16 +618,16 @@ write_debug_record(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const*
size += len;
}
- mrb_assert(size == (int)get_debug_record_size(mrb, irep));
+ mrb_assert(size == get_debug_record_size(mrb, irep));
return size;
}
-static int
-write_filename_table(mrb_state *mrb, mrb_irep *irep, uint8_t **cp, mrb_sym **fp, size_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;
- size_t file_i;
+ uint32_t file_i;
uint16_t fn_len;
size_t size = 0;
mrb_irep_debug_info *debug_info = irep->debug_info;
@@ -604,13 +659,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;
- size_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;
@@ -633,6 +688,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);
@@ -645,13 +701,14 @@ 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;
- size_t offset;
+ uint32_t offset;
memcpy(header->binary_identify, RITE_BINARY_IDENTIFIER, sizeof(header->binary_identify));
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);
diff --git a/src/etc.c b/src/etc.c
index cf7547c2d..8398aeebd 100644
--- a/src/etc.c
+++ b/src/etc.c
@@ -86,8 +86,8 @@ mrb_obj_to_sym(mrb_state *mrb, mrb_value name)
return id;
}
-static mrb_int
-float_id(mrb_float f)
+mrb_int
+mrb_float_id(mrb_float f)
{
const char *p = (const char*)&f;
int len = sizeof(f);
@@ -123,9 +123,9 @@ mrb_obj_id(mrb_value obj)
case MRB_TT_SYMBOL:
return MakeID(mrb_symbol(obj));
case MRB_TT_FIXNUM:
- return MakeID2(float_id((mrb_float)mrb_fixnum(obj)), MRB_TT_FLOAT);
+ return MakeID2(mrb_float_id((mrb_float)mrb_fixnum(obj)), MRB_TT_FLOAT);
case MRB_TT_FLOAT:
- return MakeID(float_id(mrb_float(obj)));
+ return MakeID(mrb_float_id(mrb_float(obj)));
case MRB_TT_STRING:
case MRB_TT_OBJECT:
case MRB_TT_CLASS:
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 9d7927bb9..ed71d6ee2 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -12,14 +12,43 @@
#include "mruby/string.h"
#include "mruby/variable.h"
+/* a function to get hash value of a float number */
+mrb_int mrb_float_id(mrb_float f);
+
static inline khint_t
mrb_hash_ht_hash_func(mrb_state *mrb, mrb_value key)
{
- khint_t h = (khint_t)mrb_type(key) << 24;
- mrb_value h2;
+ enum mrb_vtype t = mrb_type(key);
+ mrb_value hv;
+ const char *p;
+ mrb_int i, len;
+ khint_t h;
+
+ switch (t) {
+ case MRB_TT_STRING:
+ p = RSTRING_PTR(key);
+ len = RSTRING_LEN(key);
+ break;
+
+ case MRB_TT_SYMBOL:
+ p = mrb_sym2name_len(mrb, mrb_symbol(key), &len);
+ break;
+
+ case MRB_TT_FIXNUM:
+ return (khint_t)mrb_float_id((mrb_float)mrb_fixnum(key));
+
+ case MRB_TT_FLOAT:
+ return (khint_t)mrb_float_id(mrb_float(key));
+
+ default:
+ hv = mrb_funcall(mrb, key, "hash", 0);
+ return (khint_t)t ^ mrb_fixnum(hv);
+ }
- h2 = mrb_funcall(mrb, key, "hash", 0, 0);
- h ^= h2.value.i;
+ h = 0;
+ for (i=0; i<len; i++) {
+ h = (h << 5) - h + *p++;
+ }
return h;
}
@@ -676,14 +705,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,16 +903,22 @@ 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)) {
if (!mrb_respond_to(mrb, hash2, mrb_intern_lit(mrb, "to_hash"))) {
return mrb_false_value();
}
- if (eql)
- return mrb_fixnum_value(mrb_eql(mrb, hash2, hash1));
- else
- return mrb_fixnum_value(mrb_equal(mrb, hash2, hash1));
+ else {
+ if (eql) {
+ eq = mrb_eql(mrb, hash2, hash1);
+ }
+ else {
+ eq = mrb_equal(mrb, hash2, hash1);
+ }
+ return mrb_bool_value(eq);
+ }
}
h1 = RHASH_TBL(hash1);
h2 = RHASH_TBL(hash2);
@@ -901,7 +936,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_equal(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/kernel.c b/src/kernel.c
index 45cc299d2..b805c3c47 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -13,26 +13,26 @@
#include "mruby/error.h"
typedef enum {
- NOEX_PUBLIC = 0x00,
- NOEX_NOSUPER = 0x01,
- NOEX_PRIVATE = 0x02,
- NOEX_PROTECTED = 0x04,
- NOEX_MASK = 0x06,
- NOEX_BASIC = 0x08,
- NOEX_UNDEF = NOEX_NOSUPER,
- NOEX_MODFUNC = 0x12,
- NOEX_SUPER = 0x20,
- NOEX_VCALL = 0x40,
- NOEX_RESPONDS = 0x80
+ NOEX_PUBLIC = 0x00,
+ NOEX_NOSUPER = 0x01,
+ NOEX_PRIVATE = 0x02,
+ NOEX_PROTECTED = 0x04,
+ NOEX_MASK = 0x06,
+ NOEX_BASIC = 0x08,
+ NOEX_UNDEF = NOEX_NOSUPER,
+ NOEX_MODFUNC = 0x12,
+ NOEX_SUPER = 0x20,
+ NOEX_VCALL = 0x40,
+ NOEX_RESPONDS = 0x80
} mrb_method_flag_t;
mrb_bool
mrb_obj_basic_to_s_p(mrb_state *mrb, mrb_value obj)
{
- struct RProc *me = mrb_method_search(mrb, mrb_class(mrb, obj), mrb_intern_lit(mrb, "to_s"));
- if (me && MRB_PROC_CFUNC_P(me) && (me->body.func == mrb_any_to_s))
- return TRUE;
- return FALSE;
+ struct RProc *me = mrb_method_search(mrb, mrb_class(mrb, obj), mrb_intern_lit(mrb, "to_s"));
+ if (me && MRB_PROC_CFUNC_P(me) && (me->body.func == mrb_any_to_s))
+ return TRUE;
+ return FALSE;
}
/* 15.3.1.3.17 */
@@ -530,7 +530,7 @@ obj_is_instance_of(mrb_state *mrb, mrb_value self)
}
static void
-valid_iv_name(mrb_state *mrb, mrb_sym iv_name_id, const char* s, size_t len)
+valid_iv_name(mrb_state *mrb, mrb_sym iv_name_id, const char* s, mrb_int len)
{
if (len < 2 || !(s[0] == '@' && s[1] != '@')) {
mrb_name_error(mrb, iv_name_id, "`%S' is not allowed as an instance variable name", mrb_sym2str(mrb, iv_name_id));
@@ -541,7 +541,7 @@ static void
check_iv_name(mrb_state *mrb, mrb_sym iv_name_id)
{
const char *s;
- size_t len;
+ mrb_int len;
s = mrb_sym2name_len(mrb, iv_name_id, &len);
valid_iv_name(mrb, iv_name_id, s, len);
diff --git a/src/load.c b/src/load.c
index 857dd7740..badd76a1c 100644
--- a/src/load.c
+++ b/src/load.c
@@ -12,6 +12,7 @@
#include "mruby/proc.h"
#include "mruby/string.h"
#include "mruby/debug.h"
+#include "mruby/error.h"
#if !defined(_WIN32) && SIZE_MAX < UINT32_MAX
# define SIZE_ERROR_MUL(x, y) ((x) > SIZE_MAX / (y))
@@ -25,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)
{
@@ -33,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);
@@ -54,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)) {
@@ -70,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)) {
@@ -124,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)) {
@@ -157,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;
@@ -182,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;
@@ -215,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);
@@ -238,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;
@@ -258,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);
@@ -268,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;
@@ -279,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);
@@ -289,12 +300,13 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, uint32_t
for (f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) {
mrb_irep_debug_info_file *file;
uint16_t filename_idx;
- size_t len;
+ mrb_int len;
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);
@@ -304,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;
@@ -331,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);
@@ -344,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;
}
@@ -353,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;
@@ -366,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;
}
@@ -383,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;
}
@@ -407,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;
@@ -467,8 +495,7 @@ mrb_read_irep(mrb_state *mrb, const uint8_t *bin)
static void
irep_error(mrb_state *mrb)
{
- static const char msg[] = "irep load error";
- mrb->exc = mrb_obj_ptr(mrb_exc_new(mrb, E_SCRIPT_ERROR, msg, sizeof(msg) - 1));
+ mrb->exc = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, E_SCRIPT_ERROR, "irep load error"));
}
mrb_value
@@ -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/node.h b/src/node.h
index df27c431f..532a8323a 100644
--- a/src/node.h
+++ b/src/node.h
@@ -8,110 +8,110 @@
#define NODE_H
enum node_type {
- NODE_METHOD,
- NODE_FBODY,
- NODE_CFUNC,
- NODE_SCOPE,
- NODE_BLOCK,
- NODE_IF,
- NODE_CASE,
- NODE_WHEN,
- NODE_OPT_N,
- NODE_WHILE,
- NODE_UNTIL,
- NODE_ITER,
- NODE_FOR,
- NODE_BREAK,
- NODE_NEXT,
- NODE_REDO,
- NODE_RETRY,
- NODE_BEGIN,
- NODE_RESCUE,
- NODE_ENSURE,
- NODE_AND,
- NODE_OR,
- NODE_NOT,
- NODE_MASGN,
- NODE_ASGN,
- NODE_CDECL,
- NODE_CVASGN,
- NODE_CVDECL,
- NODE_OP_ASGN,
- NODE_CALL,
- NODE_FCALL,
- NODE_VCALL,
- NODE_SUPER,
- NODE_ZSUPER,
- NODE_ARRAY,
- NODE_ZARRAY,
- NODE_HASH,
- NODE_RETURN,
- NODE_YIELD,
- NODE_LVAR,
- NODE_DVAR,
- NODE_GVAR,
- NODE_IVAR,
- NODE_CONST,
- NODE_CVAR,
- NODE_NTH_REF,
- NODE_BACK_REF,
- NODE_MATCH,
- NODE_MATCH2,
- NODE_MATCH3,
- NODE_INT,
- NODE_FLOAT,
- NODE_NEGATE,
- NODE_LAMBDA,
- NODE_SYM,
- NODE_STR,
- NODE_DSTR,
- NODE_XSTR,
- NODE_DXSTR,
- NODE_REGX,
- NODE_DREGX,
- NODE_DREGX_ONCE,
- NODE_LIST,
- NODE_ARG,
- NODE_ARGSCAT,
- NODE_ARGSPUSH,
- NODE_SPLAT,
- NODE_TO_ARY,
- NODE_SVALUE,
- NODE_BLOCK_ARG,
- NODE_DEF,
- NODE_SDEF,
- NODE_ALIAS,
- NODE_UNDEF,
- NODE_CLASS,
- NODE_MODULE,
- NODE_SCLASS,
- NODE_COLON2,
- NODE_COLON3,
- NODE_CREF,
- NODE_DOT2,
- NODE_DOT3,
- NODE_FLIP2,
- NODE_FLIP3,
- NODE_ATTRSET,
- NODE_SELF,
- NODE_NIL,
- NODE_TRUE,
- NODE_FALSE,
- NODE_DEFINED,
- NODE_NEWLINE,
- NODE_POSTEXE,
- NODE_ALLOCA,
- NODE_DMETHOD,
- NODE_BMETHOD,
- NODE_MEMO,
- NODE_IFUNC,
- NODE_DSYM,
- NODE_ATTRASGN,
- NODE_HEREDOC,
- NODE_LITERAL_DELIM,
- NODE_WORDS,
- NODE_SYMBOLS,
- NODE_LAST
+ NODE_METHOD,
+ NODE_FBODY,
+ NODE_CFUNC,
+ NODE_SCOPE,
+ NODE_BLOCK,
+ NODE_IF,
+ NODE_CASE,
+ NODE_WHEN,
+ NODE_OPT_N,
+ NODE_WHILE,
+ NODE_UNTIL,
+ NODE_ITER,
+ NODE_FOR,
+ NODE_BREAK,
+ NODE_NEXT,
+ NODE_REDO,
+ NODE_RETRY,
+ NODE_BEGIN,
+ NODE_RESCUE,
+ NODE_ENSURE,
+ NODE_AND,
+ NODE_OR,
+ NODE_NOT,
+ NODE_MASGN,
+ NODE_ASGN,
+ NODE_CDECL,
+ NODE_CVASGN,
+ NODE_CVDECL,
+ NODE_OP_ASGN,
+ NODE_CALL,
+ NODE_FCALL,
+ NODE_VCALL,
+ NODE_SUPER,
+ NODE_ZSUPER,
+ NODE_ARRAY,
+ NODE_ZARRAY,
+ NODE_HASH,
+ NODE_RETURN,
+ NODE_YIELD,
+ NODE_LVAR,
+ NODE_DVAR,
+ NODE_GVAR,
+ NODE_IVAR,
+ NODE_CONST,
+ NODE_CVAR,
+ NODE_NTH_REF,
+ NODE_BACK_REF,
+ NODE_MATCH,
+ NODE_MATCH2,
+ NODE_MATCH3,
+ NODE_INT,
+ NODE_FLOAT,
+ NODE_NEGATE,
+ NODE_LAMBDA,
+ NODE_SYM,
+ NODE_STR,
+ NODE_DSTR,
+ NODE_XSTR,
+ NODE_DXSTR,
+ NODE_REGX,
+ NODE_DREGX,
+ NODE_DREGX_ONCE,
+ NODE_LIST,
+ NODE_ARG,
+ NODE_ARGSCAT,
+ NODE_ARGSPUSH,
+ NODE_SPLAT,
+ NODE_TO_ARY,
+ NODE_SVALUE,
+ NODE_BLOCK_ARG,
+ NODE_DEF,
+ NODE_SDEF,
+ NODE_ALIAS,
+ NODE_UNDEF,
+ NODE_CLASS,
+ NODE_MODULE,
+ NODE_SCLASS,
+ NODE_COLON2,
+ NODE_COLON3,
+ NODE_CREF,
+ NODE_DOT2,
+ NODE_DOT3,
+ NODE_FLIP2,
+ NODE_FLIP3,
+ NODE_ATTRSET,
+ NODE_SELF,
+ NODE_NIL,
+ NODE_TRUE,
+ NODE_FALSE,
+ NODE_DEFINED,
+ NODE_NEWLINE,
+ NODE_POSTEXE,
+ NODE_ALLOCA,
+ NODE_DMETHOD,
+ NODE_BMETHOD,
+ NODE_MEMO,
+ NODE_IFUNC,
+ NODE_DSYM,
+ NODE_ATTRASGN,
+ NODE_HEREDOC,
+ NODE_LITERAL_DELIM,
+ NODE_WORDS,
+ NODE_SYMBOLS,
+ NODE_LAST
};
#endif /* NODE_H */
diff --git a/src/numeric.c b/src/numeric.c
index 5f23b2461..b0b80c523 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);
@@ -680,7 +680,7 @@ int_to_i(mrb_state *mrb, mrb_value num)
return num;
}
-#define SQRT_INT_MAX ((mrb_int)1<<((sizeof(mrb_int)*CHAR_BIT-1)/2))
+#define SQRT_INT_MAX ((mrb_int)1<<((MRB_INT_BIT-1)/2))
/*tests if N*N would overflow*/
#define FIT_SQRT_INT(n) (((n)<SQRT_INT_MAX)&&((n)>=-SQRT_INT_MAX))
@@ -690,10 +690,10 @@ mrb_fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y)
mrb_int a;
a = mrb_fixnum(x);
- if (a == 0) return x;
if (mrb_fixnum_p(y)) {
mrb_int b, c;
+ if (a == 0) return x;
b = mrb_fixnum(y);
if (FIT_SQRT_INT(a) && FIT_SQRT_INT(b))
return mrb_fixnum_value(a*b);
@@ -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));
@@ -959,13 +959,13 @@ fix_xor(mrb_state *mrb, mrb_value x)
return mrb_fixnum_value(val);
}
-#define NUMERIC_SHIFT_WIDTH_MAX (sizeof(mrb_int)*CHAR_BIT-1)
+#define NUMERIC_SHIFT_WIDTH_MAX (MRB_INT_BIT-1)
static mrb_value
lshift(mrb_state *mrb, mrb_int val, size_t width)
{
if (width > NUMERIC_SHIFT_WIDTH_MAX) {
- mrb_raisef(mrb, E_RANGE_ERROR, "width(%S) > (%S:sizeof(mrb_int)*CHAR_BIT-1)",
+ mrb_raisef(mrb, E_RANGE_ERROR, "width(%S) > (%S:MRB_INT_BIT-1)",
mrb_fixnum_value(width),
mrb_fixnum_value(NUMERIC_SHIFT_WIDTH_MAX));
}
@@ -1131,10 +1131,10 @@ mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y)
mrb_int a;
a = mrb_fixnum(x);
- if (a == 0) return y;
if (mrb_fixnum_p(y)) {
mrb_int b, c;
+ if (a == 0) return y;
b = mrb_fixnum(y);
c = a + b;
if (((a < 0) ^ (b < 0)) == 0 && (a < 0) != (c < 0)) {
@@ -1207,7 +1207,7 @@ fix_minus(mrb_state *mrb, mrb_value self)
mrb_value
mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, int base)
{
- char buf[sizeof(mrb_int)*CHAR_BIT+1];
+ char buf[MRB_INT_BIT+1];
char *b = buf + sizeof buf;
mrb_int val = mrb_fixnum(x);
@@ -1306,15 +1306,14 @@ num_cmp(mrb_state *mrb, mrb_value self)
* and <code>other</code>.
*/
static mrb_value
-flo_plus(mrb_state *mrb, mrb_value self)
+flo_plus(mrb_state *mrb, mrb_value x)
{
- mrb_float x, y;
-
- x = mrb_float(self);
- mrb_get_args(mrb, "f", &y);
+ mrb_value y;
- return mrb_float_value(mrb, x + y);
+ mrb_get_args(mrb, "o", &y);
+ return mrb_float_value(mrb, mrb_float(x) + mrb_to_flo(mrb, y));
}
+
/* ------------------------------------------------------------------------*/
void
mrb_init_numeric(mrb_state *mrb)
diff --git a/src/object.c b/src/object.c
index 1f0d903f2..6d39254dd 100644
--- a/src/object.c
+++ b/src/object.c
@@ -338,7 +338,7 @@ mrb_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const char
mrb_value v;
if (mrb_type(val) == type) return val;
- v = convert_type(mrb, val, tname, method, 1/*Qtrue*/);
+ v = convert_type(mrb, val, tname, method, TRUE);
if (mrb_type(v) != type) {
mrb_raisef(mrb, E_TYPE_ERROR, "%S cannot be converted to %S by #%S", val,
mrb_str_new_cstr(mrb, tname), mrb_str_new_cstr(mrb, method));
@@ -352,7 +352,7 @@ mrb_check_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const
mrb_value v;
if (mrb_type(val) == type && type != MRB_TT_DATA) return val;
- v = convert_type(mrb, val, tname, method, 0/*Qfalse*/);
+ v = convert_type(mrb, val, tname, method, FALSE);
if (mrb_nil_p(v) || mrb_type(v) != type) return mrb_nil_value();
return v;
}
@@ -390,7 +390,6 @@ void
mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t)
{
const struct types *type = builtin_types;
- struct RString *s;
enum mrb_vtype xt;
xt = mrb_type(x);
@@ -409,8 +408,7 @@ mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t)
etype = "Symbol";
}
else if (mrb_special_const_p(x)) {
- s = mrb_str_ptr(mrb_obj_as_string(mrb, x));
- etype = s->ptr;
+ etype = RSTRING_PTR(mrb_obj_as_string(mrb, x));
}
else {
etype = mrb_obj_classname(mrb, x);
@@ -442,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;
}
@@ -590,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 5e81e5536..52bb06e73 100644
--- a/src/parse.y
+++ b/src/parse.y
@@ -24,6 +24,7 @@
#include "mruby.h"
#include "mruby/compile.h"
#include "mruby/proc.h"
+#include "mruby/error.h"
#include "node.h"
#include "mrb_throw.h"
@@ -3525,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) */
@@ -3931,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;
@@ -5307,12 +5308,11 @@ void
mrb_parser_set_filename(struct mrb_parser_state *p, const char *f)
{
mrb_sym sym;
- size_t len;
size_t i;
mrb_sym* new_table;
sym = mrb_intern_cstr(p->mrb, f);
- p->filename = mrb_sym2name_len(p->mrb, sym, &len);
+ p->filename = mrb_sym2name_len(p->mrb, sym, NULL);
p->lineno = (p->filename_table_length > 0)? 0 : 1;
for(i = 0; i < p->filename_table_length; ++i) {
@@ -5335,8 +5335,7 @@ mrb_parser_set_filename(struct mrb_parser_state *p, const char *f)
char const* mrb_parser_get_filename(struct mrb_parser_state* p, uint16_t idx) {
if (idx >= p->filename_table_length) { return NULL; }
else {
- size_t len;
- return mrb_sym2name_len(p->mrb, p->filename_table[idx], &len);
+ return mrb_sym2name_len(p->mrb, p->filename_table[idx], NULL);
}
}
@@ -5398,8 +5397,7 @@ load_exec(mrb_state *mrb, parser_state *p, mrbc_context *c)
return mrb_undef_value();
}
else {
- static const char msg[] = "syntax error";
- mrb->exc = mrb_obj_ptr(mrb_exc_new(mrb, E_SYNTAX_ERROR, msg, sizeof(msg) - 1));
+ mrb->exc = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, E_SYNTAX_ERROR, "syntax error"));
mrb_parser_free(p);
return mrb_undef_value();
}
@@ -5407,8 +5405,7 @@ load_exec(mrb_state *mrb, parser_state *p, mrbc_context *c)
proc = mrb_generate_code(mrb, p);
mrb_parser_free(p);
if (proc == NULL) {
- static const char msg[] = "codegen error";
- mrb->exc = mrb_obj_ptr(mrb_exc_new(mrb, E_SCRIPT_ERROR, msg, sizeof(msg) - 1));
+ mrb->exc = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, E_SCRIPT_ERROR, "codegen error"));
return mrb_undef_value();
}
if (c) {
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/print.c b/src/print.c
index 9d59aa4ff..6472a4675 100644
--- a/src/print.c
+++ b/src/print.c
@@ -12,14 +12,12 @@ static void
printstr(mrb_state *mrb, mrb_value obj)
{
#ifdef ENABLE_STDIO
- struct RString *str;
char *s;
int len;
if (mrb_string_p(obj)) {
- str = mrb_str_ptr(obj);
- s = str->ptr;
- len = str->len;
+ s = RSTRING_PTR(obj);
+ len = RSTRING_LEN(obj);
fwrite(s, len, 1, stdout);
}
#endif
@@ -44,8 +42,7 @@ mrb_print_error(mrb_state *mrb)
mrb_print_backtrace(mrb);
s = mrb_funcall(mrb, mrb_obj_value(mrb->exc), "inspect", 0);
if (mrb_string_p(s)) {
- struct RString *str = mrb_str_ptr(s);
- fwrite(str->ptr, str->len, 1, stderr);
+ fwrite(RSTRING_PTR(s), RSTRING_LEN(s), 1, stderr);
putc('\n', stderr);
}
#endif
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/state.c b/src/state.c
index 9b7ad1c5a..f05dbda34 100644
--- a/src/state.c
+++ b/src/state.c
@@ -135,8 +135,8 @@ mrb_irep_free(mrb_state *mrb, mrb_irep *irep)
mrb_free(mrb, irep->iseq);
for (i=0; i<irep->plen; i++) {
if (mrb_type(irep->pool[i]) == MRB_TT_STRING) {
- if ((mrb_str_ptr(irep->pool[i])->flags & MRB_STR_NOFREE) == 0) {
- mrb_free(mrb, mrb_str_ptr(irep->pool[i])->ptr);
+ if ((mrb_str_ptr(irep->pool[i])->flags & (MRB_STR_NOFREE|MRB_STR_EMBED)) == 0) {
+ mrb_free(mrb, RSTRING_PTR(irep->pool[i]));
}
mrb_free(mrb, mrb_obj_ptr(irep->pool[i]));
}
@@ -163,25 +163,30 @@ mrb_str_pool(mrb_state *mrb, mrb_value str)
{
struct RString *s = mrb_str_ptr(str);
struct RString *ns;
+ char *ptr;
mrb_int len;
ns = (struct RString *)mrb_malloc(mrb, sizeof(struct RString));
ns->tt = MRB_TT_STRING;
ns->c = mrb->string_class;
- len = s->len;
- ns->len = len;
+ if (s->flags & MRB_STR_EMBED)
+ len = (mrb_int)((s->flags & MRB_STR_EMBED_LEN_MASK) >> MRB_STR_EMBED_LEN_SHIFT);
+ else
+ len = s->as.heap.len;
+ ns->as.heap.len = len;
if (s->flags & MRB_STR_NOFREE) {
- ns->ptr = s->ptr;
+ ns->as.heap.ptr = s->as.heap.ptr;
ns->flags = MRB_STR_NOFREE;
}
else {
ns->flags = 0;
- ns->ptr = (char *)mrb_malloc(mrb, (size_t)len+1);
- if (s->ptr) {
- memcpy(ns->ptr, s->ptr, len);
+ ns->as.heap.ptr = (char *)mrb_malloc(mrb, (size_t)len+1);
+ ptr = (s->flags & MRB_STR_EMBED) ? s->as.ary : s->as.heap.ptr;
+ if (ptr) {
+ memcpy(ns->as.heap.ptr, ptr, len);
}
- ns->ptr[len] = '\0';
+ ns->as.heap.ptr[len] = '\0';
}
return mrb_obj_value(ns);
}
diff --git a/src/string.c b/src/string.c
index aa1afec47..0f057ef24 100644
--- a/src/string.c
+++ b/src/string.c
@@ -16,21 +16,74 @@
#include "mruby/string.h"
#include "re.h"
+#define STR_EMBED_P(s) ((s)->flags & MRB_STR_EMBED)
+#define STR_SET_EMBED_FLAG(s) ((s)->flags |= MRB_STR_EMBED)
+#define STR_UNSET_EMBED_FLAG(s) ((s)->flags &= ~(MRB_STR_EMBED|MRB_STR_EMBED_LEN_MASK))
+#define STR_SET_EMBED_LEN(s, n) do {\
+ mrb_int tmp_n = (n);\
+ s->flags &= ~MRB_STR_EMBED_LEN_MASK;\
+ s->flags |= (tmp_n) << MRB_STR_EMBED_LEN_SHIFT;\
+} while (0)
+#define STR_SET_LEN(s, n) do {\
+ if (STR_EMBED_P(s)) {\
+ STR_SET_EMBED_LEN((s),(n));\
+ } else {\
+ s->as.heap.len = (n);\
+ }\
+} while (0)
+#define RSTRING_EMBED_LEN(s) \
+ (mrb_int)((RSTRING(s)->flags & MRB_STR_EMBED_LEN_MASK) >> MRB_STR_EMBED_LEN_SHIFT)
+#define STR_EMBED_LEN(s)\
+ (mrb_int)(((s)->flags & MRB_STR_EMBED_LEN_MASK) >> MRB_STR_EMBED_LEN_SHIFT)
+#define STR_PTR(s) ((STR_EMBED_P(s)) ? (s)->as.ary : (s)->as.heap.ptr)
+#define STR_LEN(s) ((STR_EMBED_P(s)) ? STR_EMBED_LEN(s) : (s)->as.heap.len)
+
const char mrb_digitmap[] = "0123456789abcdefghijklmnopqrstuvwxyz";
typedef struct mrb_shared_string {
- mrb_bool nofree;
+ mrb_bool nofree : 1;
int refcnt;
char *ptr;
mrb_int len;
} mrb_shared_string;
+#define STR_SHARED_P(s) ((s)->flags & MRB_STR_SHARED)
+#define STR_SET_SHARED_FLAG(s) ((s)->flags |= MRB_STR_SHARED)
+#define STR_UNSET_SHARED_FLAG(s) ((s)->flags &= ~MRB_STR_SHARED)
+
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 {\
- s->ptr = (char *)mrb_realloc(mrb, s->ptr, (capacity)+1);\
- s->aux.capa = capacity;\
+ if (STR_EMBED_P(s)) {\
+ if (RSTRING_EMBED_LEN_MAX < (capacity)) {\
+ char *const tmp = (char *)mrb_malloc(mrb, (capacity)+1);\
+ const mrb_int len = STR_EMBED_LEN(s);\
+ memcpy(tmp, s->as.ary, len);\
+ STR_UNSET_EMBED_FLAG(s);\
+ s->as.heap.ptr = tmp;\
+ s->as.heap.len = len;\
+ s->as.heap.aux.capa = (capacity);\
+ }\
+ } else {\
+ s->as.heap.ptr = (char *)mrb_realloc(mrb, STR_PTR(s), (capacity)+1);\
+ s->as.heap.aux.capa = capacity;\
+ }\
} while(0)
static void
@@ -48,42 +101,42 @@ str_decref(mrb_state *mrb, mrb_shared_string *shared)
void
mrb_str_modify(mrb_state *mrb, struct RString *s)
{
- if (s->flags & MRB_STR_SHARED) {
- mrb_shared_string *shared = s->aux.shared;
+ if (STR_SHARED_P(s)) {
+ mrb_shared_string *shared = s->as.heap.aux.shared;
- if (shared->refcnt == 1 && s->ptr == shared->ptr) {
- s->ptr = shared->ptr;
- s->aux.capa = shared->len;
- s->ptr[s->len] = '\0';
+ if (shared->refcnt == 1 && s->as.heap.ptr == shared->ptr) {
+ s->as.heap.ptr = shared->ptr;
+ s->as.heap.aux.capa = shared->len;
+ STR_PTR(s)[s->as.heap.len] = '\0';
mrb_free(mrb, shared);
}
else {
char *ptr, *p;
mrb_int len;
- p = s->ptr;
- len = s->len;
+ p = STR_PTR(s);
+ len = s->as.heap.len;
ptr = (char *)mrb_malloc(mrb, (size_t)len + 1);
if (p) {
memcpy(ptr, p, len);
}
- ptr[len] = '\0';
- s->ptr = ptr;
- s->aux.capa = len;
+ ptr[len] = '\0';
+ s->as.heap.ptr = ptr;
+ s->as.heap.aux.capa = len;
str_decref(mrb, shared);
}
- s->flags &= ~MRB_STR_SHARED;
+ STR_UNSET_SHARED_FLAG(s);
return;
}
if (s->flags & MRB_STR_NOFREE) {
- char *p = s->ptr;
+ char *p = STR_PTR(s);
- s->ptr = (char *)mrb_malloc(mrb, (size_t)s->len+1);
+ s->as.heap.ptr = (char *)mrb_malloc(mrb, (size_t)s->as.heap.len+1);
if (p) {
- memcpy(s->ptr, p, s->len);
+ memcpy(STR_PTR(s), p, s->as.heap.len);
}
- s->ptr[s->len] = '\0';
- s->aux.capa = s->len;
+ STR_PTR(s)[s->as.heap.len] = '\0';
+ s->as.heap.aux.capa = s->as.heap.len;
s->flags &= ~MRB_STR_NOFREE;
return;
}
@@ -96,13 +149,13 @@ mrb_str_resize(mrb_state *mrb, mrb_value str, mrb_int len)
struct RString *s = mrb_str_ptr(str);
mrb_str_modify(mrb, s);
- slen = s->len;
+ slen = STR_LEN(s);
if (len != slen) {
if (slen < len || slen - len > 256) {
RESIZE_CAPA(s, len);
}
- s->len = len;
- s->ptr[len] = '\0'; /* sentinel */
+ STR_SET_LEN(s, len);
+ STR_PTR(s)[len] = '\0'; /* sentinel */
}
return str;
}
@@ -122,13 +175,21 @@ str_new(mrb_state *mrb, const char *p, mrb_int len)
struct RString *s;
s = mrb_obj_alloc_string(mrb);
- s->len = len;
- s->aux.capa = len;
- s->ptr = (char *)mrb_malloc(mrb, (size_t)len+1);
- if (p) {
- memcpy(s->ptr, p, len);
+ if (len < RSTRING_EMBED_LEN_MAX) {
+ STR_SET_EMBED_FLAG(s);
+ STR_SET_EMBED_LEN(s,len);
+ if (p) {
+ memcpy(s->as.ary, p, len);
+ }
+ } else {
+ s->as.heap.len = len;
+ s->as.heap.aux.capa = len;
+ s->as.heap.ptr = (char *)mrb_malloc(mrb, (size_t)len+1);
+ if (p) {
+ memcpy(s->as.heap.ptr, p, len);
+ }
}
- s->ptr[len] = '\0';
+ STR_PTR(s)[len] = '\0';
return s;
}
@@ -161,31 +222,36 @@ mrb_str_buf_new(mrb_state *mrb, mrb_int capa)
if (capa < MRB_STR_BUF_MIN_SIZE) {
capa = MRB_STR_BUF_MIN_SIZE;
}
- s->len = 0;
- s->aux.capa = capa;
- s->ptr = (char *)mrb_malloc(mrb, capa+1);
- s->ptr[0] = '\0';
+ s->as.heap.len = 0;
+ s->as.heap.aux.capa = capa;
+ s->as.heap.ptr = (char *)mrb_malloc(mrb, capa+1);
+ STR_PTR(s)[0] = '\0';
return mrb_obj_value(s);
}
static void
-str_buf_cat(mrb_state *mrb, struct RString *s, const char *ptr, size_t len)
+str_buf_cat(mrb_state *mrb, struct RString *s, const char *ptr, mrb_int len)
{
mrb_int capa;
mrb_int total;
ptrdiff_t off = -1;
mrb_str_modify(mrb, s);
- if (ptr >= s->ptr && ptr <= s->ptr + s->len) {
- off = ptr - s->ptr;
+ if (ptr >= STR_PTR(s) && ptr <= STR_PTR(s) + STR_LEN(s)) {
+ off = ptr - STR_PTR(s);
}
if (len == 0) return;
- capa = s->aux.capa;
- if (s->len >= MRB_INT_MAX - (mrb_int)len) {
+
+ if (STR_EMBED_P(s))
+ capa = RSTRING_EMBED_LEN_MAX;
+ else
+ capa = s->as.heap.aux.capa;
+
+ if (STR_LEN(s) >= MRB_INT_MAX - (mrb_int)len) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "string sizes too big");
}
- total = s->len+len;
+ total = STR_LEN(s)+len;
if (capa <= total) {
while (total > capa) {
if (capa + 1 >= MRB_INT_MAX / 2) {
@@ -197,15 +263,15 @@ str_buf_cat(mrb_state *mrb, struct RString *s, const char *ptr, size_t len)
RESIZE_CAPA(s, capa);
}
if (off != -1) {
- ptr = s->ptr + off;
+ ptr = STR_PTR(s) + off;
}
- memcpy(s->ptr + s->len, ptr, len);
- s->len = total;
- s->ptr[total] = '\0'; /* sentinel */
+ memcpy(STR_PTR(s) + STR_LEN(s), ptr, len);
+ STR_SET_LEN(s, total);
+ STR_PTR(s)[total] = '\0'; /* sentinel */
}
mrb_value
-mrb_str_buf_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len)
+mrb_str_buf_cat(mrb_state *mrb, mrb_value str, const char *ptr, mrb_int len)
{
if (len == 0) return str;
str_buf_cat(mrb, mrb_str_ptr(str), ptr, len);
@@ -213,10 +279,10 @@ mrb_str_buf_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len)
}
mrb_value
-mrb_str_new(mrb_state *mrb, const char *p, size_t len)
+mrb_str_new(mrb_state *mrb, const char *p, mrb_int len)
{
struct RString *s;
- if ((mrb_int)len < 0) {
+ if (len < 0) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "negative string size (or size too big)");
}
@@ -247,23 +313,24 @@ mrb_str_new_cstr(mrb_state *mrb, const char *p)
len = 0;
}
- s = str_new(mrb, p, len);
+ s = str_new(mrb, p, (mrb_int)len);
return mrb_obj_value(s);
}
mrb_value
-mrb_str_new_static(mrb_state *mrb, const char *p, size_t len)
+mrb_str_new_static(mrb_state *mrb, const char *p, mrb_int len)
{
struct RString *s;
- if ((mrb_int)len < 0) {
+
+ if (len < 0) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "negative string size (or size too big)");
}
s = mrb_obj_alloc_string(mrb);
- s->len = len;
- s->aux.capa = 0; /* nofree */
- s->ptr = (char *)p;
+ s->as.heap.len = len;
+ s->as.heap.aux.capa = 0; /* nofree */
+ s->as.heap.ptr = (char *)p;
s->flags = MRB_STR_NOFREE;
return mrb_obj_value(s);
}
@@ -271,10 +338,12 @@ mrb_str_new_static(mrb_state *mrb, const char *p, size_t len)
void
mrb_gc_free_str(mrb_state *mrb, struct RString *str)
{
- if (str->flags & MRB_STR_SHARED)
- str_decref(mrb, str->aux.shared);
+ if (STR_EMBED_P(str))
+ /* no code */;
+ else if (STR_SHARED_P(str))
+ str_decref(mrb, str->as.heap.aux.shared);
else if ((str->flags & MRB_STR_NOFREE) == 0)
- mrb_free(mrb, str->ptr);
+ mrb_free(mrb, str->as.heap.ptr);
}
char *
@@ -287,36 +356,47 @@ mrb_str_to_cstr(mrb_state *mrb, mrb_value str0)
}
s = str_new(mrb, RSTRING_PTR(str0), RSTRING_LEN(str0));
- if ((strlen(s->ptr) ^ s->len) != 0) {
+ if ((strlen(STR_PTR(s)) ^ STR_LEN(s)) != 0) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte");
}
- return s->ptr;
+ return STR_PTR(s);
}
static void
str_make_shared(mrb_state *mrb, struct RString *s)
{
- if (!(s->flags & MRB_STR_SHARED)) {
+ if (!STR_SHARED_P(s)) {
mrb_shared_string *shared = (mrb_shared_string *)mrb_malloc(mrb, sizeof(mrb_shared_string));
shared->refcnt = 1;
- if (s->flags & MRB_STR_NOFREE) {
+ if (STR_EMBED_P(s)) {
+ const mrb_int len = STR_EMBED_LEN(s);
+ char *const tmp = (char *)mrb_malloc(mrb, len+1);
+ memcpy(tmp, s->as.ary, len);
+ tmp[len] = '\0';
+ STR_UNSET_EMBED_FLAG(s);
+ s->as.heap.ptr = tmp;
+ s->as.heap.len = len;
+ shared->nofree = FALSE;
+ shared->ptr = s->as.heap.ptr;
+ }
+ else if (s->flags & MRB_STR_NOFREE) {
shared->nofree = TRUE;
- shared->ptr = s->ptr;
+ shared->ptr = STR_PTR(s);
s->flags &= ~MRB_STR_NOFREE;
}
else {
shared->nofree = FALSE;
- if (s->aux.capa > s->len) {
- s->ptr = shared->ptr = (char *)mrb_realloc(mrb, s->ptr, s->len+1);
+ if (s->as.heap.aux.capa > s->as.heap.len) {
+ s->as.heap.ptr = shared->ptr = (char *)mrb_realloc(mrb, STR_PTR(s), s->as.heap.len+1);
}
else {
- shared->ptr = s->ptr;
+ shared->ptr = STR_PTR(s);
}
}
- shared->len = s->len;
- s->aux.shared = shared;
- s->flags |= MRB_STR_SHARED;
+ shared->len = s->as.heap.len;
+ s->as.heap.aux.shared = shared;
+ STR_SET_SHARED_FLAG(s);
}
}
@@ -331,8 +411,8 @@ mrb_str_body(mrb_value str, int *len_p)
{
struct RString *s = mrb_str_ptr(str);
- *len_p = s->len;
- return s->ptr;
+ *len_p = STR_LEN(s);
+ return STR_PTR(s);
}
/*
@@ -352,15 +432,14 @@ mrb_str_concat(mrb_state *mrb, mrb_value self, mrb_value other)
other = mrb_str_to_str(mrb, other);
}
s2 = mrb_str_ptr(other);
- len = s1->len + s2->len;
+ len = STR_LEN(s1) + STR_LEN(s2);
- if (s1->aux.capa < len) {
- s1->aux.capa = len;
- s1->ptr = (char *)mrb_realloc(mrb, s1->ptr, len+1);
+ if (RSTRING_CAPA(self) < len) {
+ RESIZE_CAPA(s1, len);
}
- memcpy(s1->ptr+s1->len, s2->ptr, s2->len);
- s1->len = len;
- s1->ptr[len] = '\0';
+ memcpy(STR_PTR(s1)+STR_LEN(s1), STR_PTR(s2), STR_LEN(s2));
+ STR_SET_LEN(s1, len);
+ STR_PTR(s1)[len] = '\0';
}
/*
@@ -376,9 +455,9 @@ mrb_str_plus(mrb_state *mrb, mrb_value a, mrb_value b)
struct RString *s2 = mrb_str_ptr(b);
struct RString *t;
- t = str_new(mrb, 0, s->len + s2->len);
- memcpy(t->ptr, s->ptr, s->len);
- memcpy(t->ptr + s->len, s2->ptr, s2->len);
+ t = str_new(mrb, 0, STR_LEN(s) + STR_LEN(s2));
+ memcpy(STR_PTR(t), STR_PTR(s), STR_LEN(s));
+ memcpy(STR_PTR(t) + STR_LEN(s), STR_PTR(s2), STR_LEN(s2));
return mrb_obj_value(t);
}
@@ -410,7 +489,7 @@ static mrb_value
mrb_str_bytesize(mrb_state *mrb, mrb_value self)
{
struct RString *s = mrb_str_ptr(self);
- return mrb_fixnum_value(s->len);
+ return mrb_fixnum_value(STR_LEN(s));
}
/* 15.2.10.5.26 */
@@ -425,7 +504,7 @@ mrb_value
mrb_str_size(mrb_state *mrb, mrb_value self)
{
struct RString *s = mrb_str_ptr(self);
- return mrb_fixnum_value(s->len);
+ return mrb_fixnum_value(STR_LEN(s));
}
/* 15.2.10.5.1 */
@@ -456,7 +535,7 @@ mrb_str_times(mrb_state *mrb, mrb_value self)
len = RSTRING_LEN(self)*times;
str2 = str_new(mrb, 0, len);
str_with_class(mrb, str2, self);
- p = str2->ptr;
+ p = STR_PTR(str2);
if (len > 0) {
n = RSTRING_LEN(self);
memcpy(p, RSTRING_PTR(self), n);
@@ -466,7 +545,7 @@ mrb_str_times(mrb_state *mrb, mrb_value self)
}
memcpy(p + n, p, len-n);
}
- p[str2->len] = '\0';
+ p[STR_LEN(str2)] = '\0';
return mrb_obj_value(str2);
}
@@ -490,11 +569,11 @@ mrb_str_cmp(mrb_state *mrb, mrb_value str1, mrb_value str2)
struct RString *s1 = mrb_str_ptr(str1);
struct RString *s2 = mrb_str_ptr(str2);
- len = lesser(s1->len, s2->len);
- retval = memcmp(s1->ptr, s2->ptr, len);
+ len = lesser(STR_LEN(s1), STR_LEN(s2));
+ retval = memcmp(STR_PTR(s1), STR_PTR(s2), len);
if (retval == 0) {
- if (s1->len == s2->len) return 0;
- if (s1->len > s2->len) return 1;
+ if (STR_LEN(s1) == STR_LEN(s2)) return 0;
+ if (STR_LEN(s1) > STR_LEN(s2)) return 1;
return -1;
}
if (retval > 0) return 1;
@@ -720,7 +799,7 @@ mrb_str_dup(mrb_state *mrb, mrb_value str)
/* should return shared string */
struct RString *s = mrb_str_ptr(str);
- return mrb_str_new(mrb, s->ptr, s->len);
+ return mrb_str_new(mrb, STR_PTR(s), STR_LEN(s));
}
static mrb_value
@@ -849,8 +928,8 @@ mrb_str_capitalize_bang(mrb_state *mrb, mrb_value str)
struct RString *s = mrb_str_ptr(str);
mrb_str_modify(mrb, s);
- if (s->len == 0 || !s->ptr) return mrb_nil_value();
- p = s->ptr; pend = s->ptr + s->len;
+ if (STR_LEN(s) == 0 || !STR_PTR(s)) return mrb_nil_value();
+ p = STR_PTR(s); pend = STR_PTR(s) + STR_LEN(s);
if (ISLOWER(*p)) {
*p = TOUPPER(*p);
modify = 1;
@@ -906,29 +985,29 @@ mrb_str_chomp_bang(mrb_state *mrb, mrb_value str)
struct RString *s = mrb_str_ptr(str);
mrb_str_modify(mrb, s);
- len = s->len;
+ len = STR_LEN(s);
if (mrb_get_args(mrb, "|S", &rs) == 0) {
if (len == 0) return mrb_nil_value();
smart_chomp:
- if (s->ptr[len-1] == '\n') {
- s->len--;
- if (s->len > 0 &&
- s->ptr[s->len-1] == '\r') {
- s->len--;
+ if (STR_PTR(s)[len-1] == '\n') {
+ STR_SET_LEN(s, STR_LEN(s) - 1);
+ if (STR_LEN(s) > 0 &&
+ STR_PTR(s)[STR_LEN(s)-1] == '\r') {
+ STR_SET_LEN(s, STR_LEN(s) - 1);
}
}
- else if (s->ptr[len-1] == '\r') {
- s->len--;
+ else if (STR_PTR(s)[len-1] == '\r') {
+ STR_SET_LEN(s, STR_LEN(s) - 1);
}
else {
return mrb_nil_value();
}
- s->ptr[s->len] = '\0';
+ STR_PTR(s)[STR_LEN(s)] = '\0';
return str;
}
if (len == 0 || mrb_nil_p(rs)) return mrb_nil_value();
- p = s->ptr;
+ p = STR_PTR(s);
rslen = RSTRING_LEN(rs);
if (rslen == 0) {
while (len>0 && p[len-1] == '\n') {
@@ -936,8 +1015,8 @@ mrb_str_chomp_bang(mrb_state *mrb, mrb_value str)
if (len>0 && p[len-1] == '\r')
len--;
}
- if (len < s->len) {
- s->len = len;
+ if (len < STR_LEN(s)) {
+ STR_SET_LEN(s, len);
p[len] = '\0';
return str;
}
@@ -954,8 +1033,8 @@ mrb_str_chomp_bang(mrb_state *mrb, mrb_value str)
if (p[len-1] == newline &&
(rslen <= 1 ||
memcmp(RSTRING_PTR(rs), pp, rslen) == 0)) {
- s->len = len - rslen;
- p[s->len] = '\0';
+ STR_SET_LEN(s, len - rslen);
+ p[STR_LEN(s)] = '\0';
return str;
}
return mrb_nil_value();
@@ -1005,17 +1084,17 @@ mrb_str_chop_bang(mrb_state *mrb, mrb_value str)
struct RString *s = mrb_str_ptr(str);
mrb_str_modify(mrb, s);
- if (s->len > 0) {
+ if (STR_LEN(s) > 0) {
int len;
- len = s->len - 1;
- if (s->ptr[len] == '\n') {
+ len = STR_LEN(s) - 1;
+ if (STR_PTR(s)[len] == '\n') {
if (len > 0 &&
- s->ptr[len-1] == '\r') {
+ STR_PTR(s)[len-1] == '\r') {
len--;
}
}
- s->len = len;
- s->ptr[len] = '\0';
+ STR_SET_LEN(s, len);
+ STR_PTR(s)[len] = '\0';
return str;
}
return mrb_nil_value();
@@ -1063,8 +1142,8 @@ mrb_str_downcase_bang(mrb_state *mrb, mrb_value str)
struct RString *s = mrb_str_ptr(str);
mrb_str_modify(mrb, s);
- p = s->ptr;
- pend = s->ptr + s->len;
+ p = STR_PTR(s);
+ pend = STR_PTR(s) + STR_LEN(s);
while (p < pend) {
if (ISUPPER(*p)) {
*p = TOLOWER(*p);
@@ -1113,7 +1192,7 @@ mrb_str_empty_p(mrb_state *mrb, mrb_value self)
{
struct RString *s = mrb_str_ptr(self);
- return mrb_bool_value(s->len == 0);
+ return mrb_bool_value(STR_LEN(s) == 0);
}
/* 15.2.10.5.17 */
@@ -1142,14 +1221,18 @@ mrb_str_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len)
mrb_shared_string *shared;
orig = mrb_str_ptr(str);
- str_make_shared(mrb, orig);
- shared = orig->aux.shared;
- s = mrb_obj_alloc_string(mrb);
- s->ptr = orig->ptr + beg;
- s->len = len;
- s->aux.shared = shared;
- s->flags |= MRB_STR_SHARED;
- shared->refcnt++;
+ if (STR_EMBED_P(orig)) {
+ s = str_new(mrb, orig->as.ary+beg, len);
+ } else {
+ str_make_shared(mrb, orig);
+ shared = orig->as.heap.aux.shared;
+ s = mrb_obj_alloc_string(mrb);
+ s->as.heap.ptr = orig->as.heap.ptr + beg;
+ s->as.heap.len = len;
+ s->as.heap.aux.shared = shared;
+ STR_SET_SHARED_FLAG(s);
+ shared->refcnt++;
+ }
return mrb_obj_value(s);
}
@@ -1190,8 +1273,8 @@ mrb_str_hash(mrb_state *mrb, mrb_value str)
{
/* 1-8-7 */
struct RString *s = mrb_str_ptr(str);
- mrb_int len = s->len;
- char *p = s->ptr;
+ mrb_int len = STR_LEN(s);
+ char *p = STR_PTR(s);
mrb_int key = 0;
while (len--) {
@@ -1337,38 +1420,36 @@ mrb_str_index_m(mrb_state *mrb, mrb_value str)
static mrb_value
str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2)
{
- if (s2->flags & MRB_STR_SHARED) {
+ long len;
+
+ len = STR_LEN(s2);
+ if (STR_SHARED_P(s2)) {
L_SHARE:
- if (s1->flags & MRB_STR_SHARED){
- str_decref(mrb, s1->aux.shared);
+ if (STR_SHARED_P(s1)) {
+ str_decref(mrb, s1->as.heap.aux.shared);
}
- else {
- mrb_free(mrb, s1->ptr);
+ else if (!STR_EMBED_P(s1) && !(s1->flags & MRB_STR_NOFREE)) {
+ mrb_free(mrb, s1->as.heap.ptr);
}
- s1->ptr = s2->ptr;
- s1->len = s2->len;
- s1->aux.shared = s2->aux.shared;
- s1->flags |= MRB_STR_SHARED;
- s1->aux.shared->refcnt++;
- }
- else if (s2->len > STR_REPLACE_SHARED_MIN) {
- str_make_shared(mrb, s2);
- goto L_SHARE;
+ STR_UNSET_EMBED_FLAG(s1);
+ s1->as.heap.ptr = s2->as.heap.ptr;
+ s1->as.heap.len = len;
+ s1->as.heap.aux.shared = s2->as.heap.aux.shared;
+ STR_SET_SHARED_FLAG(s1);
+ s1->as.heap.aux.shared->refcnt++;
}
else {
- if (s1->flags & MRB_STR_SHARED) {
- str_decref(mrb, s1->aux.shared);
- s1->flags &= ~MRB_STR_SHARED;
- s1->ptr = (char *)mrb_malloc(mrb, s2->len+1);
+ if (len <= RSTRING_EMBED_LEN_MAX) {
+ STR_SET_EMBED_FLAG(s1);
+ memcpy(STR_PTR(s1), STR_PTR(s2), len);
+ STR_SET_EMBED_LEN(s1, len);
}
else {
- s1->ptr = (char *)mrb_realloc(mrb, s1->ptr, s2->len+1);
+ str_make_shared(mrb, s2);
+ goto L_SHARE;
}
- memcpy(s1->ptr, s2->ptr, s2->len);
- s1->ptr[s2->len] = 0;
- s1->len = s2->len;
- s1->aux.capa = s2->len;
}
+
return mrb_obj_value(s1);
}
@@ -1462,7 +1543,7 @@ mrb_ptr_to_str(mrb_state *mrb, void *p)
uintptr_t n = (uintptr_t)p;
p_str = str_new(mrb, NULL, 2 + sizeof(uintptr_t) * CHAR_BIT / 4);
- p1 = p_str->ptr;
+ p1 = STR_PTR(p_str);
*p1++ = '0';
*p1++ = 'x';
p2 = p1;
@@ -1472,7 +1553,7 @@ mrb_ptr_to_str(mrb_state *mrb, void *p)
n /= 16;
} while (n > 0);
*p2 = '\0';
- p_str->len = (mrb_int)(p2 - p_str->ptr);
+ STR_SET_LEN(p_str, (mrb_int)(p2 - STR_PTR(p_str)));
while (p1 < p2) {
const char c = *p1;
@@ -1511,12 +1592,12 @@ mrb_str_reverse(mrb_state *mrb, mrb_value str)
struct RString *s2;
char *s, *e, *p;
- if (RSTRING(str)->len <= 1) return mrb_str_dup(mrb, str);
+ if (RSTRING_LEN(str) <= 1) return mrb_str_dup(mrb, str);
- s2 = str_new(mrb, 0, RSTRING(str)->len);
+ s2 = str_new(mrb, 0, RSTRING_LEN(str));
str_with_class(mrb, s2, str);
s = RSTRING_PTR(str); e = RSTRING_END(str) - 1;
- p = s2->ptr;
+ p = STR_PTR(s2);
while (e >= s) {
*p++ = *e--;
@@ -1539,9 +1620,9 @@ mrb_str_reverse_bang(mrb_state *mrb, mrb_value str)
char c;
mrb_str_modify(mrb, s);
- if (s->len > 1) {
- p = s->ptr;
- e = p + s->len - 1;
+ if (STR_LEN(s) > 1) {
+ p = STR_PTR(s);
+ e = p + STR_LEN(s) - 1;
while (p < e) {
c = *p;
*p++ = *e;
@@ -1574,21 +1655,20 @@ mrb_str_rindex(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos)
{
char *s, *sbeg, *t;
struct RString *ps = mrb_str_ptr(str);
- struct RString *psub = mrb_str_ptr(sub);
- mrb_int len = psub->len;
+ mrb_int len = RSTRING_LEN(sub);
/* substring longer than string */
- if (ps->len < len) return -1;
- if (ps->len - pos < len) {
- pos = ps->len - len;
+ if (STR_LEN(ps) < len) return -1;
+ if (STR_LEN(ps) - pos < len) {
+ pos = STR_LEN(ps) - len;
}
- sbeg = ps->ptr;
- s = ps->ptr + pos;
- t = psub->ptr;
+ sbeg = STR_PTR(ps);
+ s = STR_PTR(ps) + pos;
+ t = RSTRING_PTR(sub);
if (len) {
while (sbeg <= s) {
if (memcmp(s, t, len) == 0) {
- return s - ps->ptr;
+ return s - STR_PTR(ps);
}
s--;
}
@@ -1656,7 +1736,7 @@ mrb_str_rindex_m(mrb_state *mrb, mrb_value str)
mrb_int len = RSTRING_LEN(str);
unsigned char *p = (unsigned char*)RSTRING_PTR(str);
- for (pos=len;pos>=0;pos--) {
+ for (pos=len-1;pos>=0;pos--) {
if (p[pos] == c) return mrb_fixnum_value(pos);
}
return mrb_nil_value();
@@ -1682,22 +1762,22 @@ mrb_str_rindex_m(mrb_state *mrb, mrb_value str)
}
static const char isspacetable[256] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
#define ascii_isspace(c) isspacetable[(unsigned char)(c)]
@@ -1819,7 +1899,7 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str)
}
}
else if (split_type == string) {
- char *ptr = RSTRING_PTR(str);
+ char *ptr = RSTRING_PTR(str); // s->as.ary
char *temp = ptr;
char *eptr = RSTRING_END(str);
mrb_int slen = RSTRING_LEN(spat);
@@ -2002,12 +2082,14 @@ char *
mrb_string_value_cstr(mrb_state *mrb, mrb_value *ptr)
{
struct RString *ps = mrb_str_ptr(*ptr);
- char *s = ps->ptr;
+ mrb_int len = mrb_str_strlen(mrb, ps);
+ char *p = STR_PTR(ps);
- if (!s || ps->len != 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
@@ -2027,7 +2109,7 @@ mrb_str_to_inum(mrb_state *mrb, mrb_value str, int base, mrb_bool badcheck)
len = RSTRING_LEN(str);
if (s[len]) { /* no sentinel somehow */
struct RString *temp_str = str_new(mrb, s, len);
- s = temp_str->ptr;
+ s = STR_PTR(temp_str);
}
}
return mrb_cstr_to_inum(mrb, s, base, badcheck);
@@ -2157,7 +2239,7 @@ mrb_str_to_dbl(mrb_state *mrb, mrb_value str, mrb_bool badcheck)
}
if (s[len]) { /* no sentinel somehow */
struct RString *temp_str = str_new(mrb, s, len);
- s = temp_str->ptr;
+ s = STR_PTR(temp_str);
}
}
return mrb_cstr_to_dbl(mrb, s, badcheck);
@@ -2296,8 +2378,7 @@ mrb_str_dump(mrb_state *mrb, mrb_value str)
result = str_new(mrb, 0, len);
str_with_class(mrb, result, str);
p = RSTRING_PTR(str); pend = p + RSTRING_LEN(str);
- q = result->ptr;
-
+ q = STR_PTR(result);
*q++ = '"';
while (p < pend) {
unsigned char c = *p++;
@@ -2372,7 +2453,7 @@ mrb_str_dump(mrb_state *mrb, mrb_value str)
}
mrb_value
-mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len)
+mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, mrb_int len)
{
if ((mrb_int)len < 0) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "negative string size (or size too big)");
@@ -2455,7 +2536,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;
}
@@ -2473,8 +2554,8 @@ static mrb_value
mrb_str_bytes(mrb_state *mrb, mrb_value str)
{
struct RString *s = mrb_str_ptr(str);
- mrb_value a = mrb_ary_new_capa(mrb, s->len);
- unsigned char *p = (unsigned char *)(s->ptr), *pend = p + s->len;
+ mrb_value a = mrb_ary_new_capa(mrb, STR_LEN(s));
+ unsigned char *p = (unsigned char *)(STR_PTR(s)), *pend = p + STR_LEN(s);
while (p < pend) {
mrb_ary_push(mrb, a, mrb_fixnum_value(p[0]));
diff --git a/src/symbol.c b/src/symbol.c
index 7971f71ca..deb6155d0 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, mrb_int len, mrb_bool lit)
{
khash_t(n2s) *h = mrb->name2sym;
symbol_name sname;
@@ -70,21 +70,21 @@ 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)
+mrb_intern(mrb_state *mrb, const char *name, mrb_int 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)
+mrb_intern_static(mrb_state *mrb, const char *name, mrb_int len)
{
- return sym_intern(mrb, name, len, 1);
+ return sym_intern(mrb, name, len, TRUE);
}
mrb_sym
mrb_intern_cstr(mrb_state *mrb, const char *name)
{
- return mrb_intern(mrb, name, strlen(name));
+ return mrb_intern(mrb, name, (mrb_int)strlen(name));
}
mrb_sym
@@ -94,7 +94,7 @@ mrb_intern_str(mrb_state *mrb, mrb_value str)
}
mrb_value
-mrb_check_intern(mrb_state *mrb, const char *name, size_t len)
+mrb_check_intern(mrb_state *mrb, const char *name, mrb_int len)
{
khash_t(n2s) *h = mrb->name2sym;
symbol_name sname = { 0 };
@@ -116,7 +116,7 @@ mrb_check_intern(mrb_state *mrb, const char *name, size_t len)
mrb_value
mrb_check_intern_cstr(mrb_state *mrb, const char *name)
{
- return mrb_check_intern(mrb, name, strlen(name));
+ return mrb_check_intern(mrb, name, (mrb_int)strlen(name));
}
mrb_value
@@ -127,7 +127,7 @@ mrb_check_intern_str(mrb_state *mrb, mrb_value str)
/* lenp must be a pointer to a size_t variable */
const char*
-mrb_sym2name_len(mrb_state *mrb, mrb_sym sym, size_t *lenp)
+mrb_sym2name_len(mrb_state *mrb, mrb_sym sym, mrb_int *lenp)
{
khash_t(n2s) *h = mrb->name2sym;
khiter_t k;
@@ -137,12 +137,12 @@ mrb_sym2name_len(mrb_state *mrb, mrb_sym sym, size_t *lenp)
if (kh_exist(h, k)) {
if (kh_value(h, k) == sym) {
sname = kh_key(h, k);
- *lenp = sname.len;
+ if (lenp) *lenp = sname.len;
return sname.name;
}
}
}
- *lenp = 0;
+ if (lenp) *lenp = 0;
return NULL; /* missing */
}
@@ -240,7 +240,7 @@ mrb_sym_to_s(mrb_state *mrb, mrb_value sym)
{
mrb_sym id = mrb_symbol(sym);
const char *p;
- size_t len;
+ mrb_int len;
p = mrb_sym2name_len(mrb, id, &len);
return mrb_str_new_static(mrb, p, len);
@@ -392,16 +392,16 @@ sym_inspect(mrb_state *mrb, mrb_value sym)
{
mrb_value str;
const char *name;
- size_t len;
+ mrb_int len;
mrb_sym id = mrb_symbol(sym);
name = mrb_sym2name_len(mrb, id, &len);
str = mrb_str_new(mrb, 0, len+1);
- RSTRING(str)->ptr[0] = ':';
- memcpy(RSTRING(str)->ptr+1, name, len);
+ RSTRING_PTR(str)[0] = ':';
+ memcpy(RSTRING_PTR(str)+1, name, len);
if (!symname_p(name) || strlen(name) != len) {
str = mrb_str_dump(mrb, str);
- memcpy(RSTRING(str)->ptr, ":\"", 2);
+ memcpy(RSTRING_PTR(str), ":\"", 2);
}
return str;
}
@@ -409,7 +409,7 @@ sym_inspect(mrb_state *mrb, mrb_value sym)
mrb_value
mrb_sym2str(mrb_state *mrb, mrb_sym sym)
{
- size_t len;
+ mrb_int len;
const char *name = mrb_sym2name_len(mrb, sym, &len);
if (!name) return mrb_undef_value(); /* can't happen */
@@ -419,16 +419,16 @@ mrb_sym2str(mrb_state *mrb, mrb_sym sym)
const char*
mrb_sym2name(mrb_state *mrb, mrb_sym sym)
{
- size_t len;
+ mrb_int len;
const char *name = mrb_sym2name_len(mrb, sym, &len);
if (!name) return NULL;
- if (symname_p(name) && strlen(name) == len) {
+ if (symname_p(name) && strlen(name) == (size_t)len) {
return name;
}
else {
mrb_value str = mrb_str_dump(mrb, mrb_str_new_static(mrb, name, len));
- return RSTRING(str)->ptr;
+ return RSTRING_PTR(str);
}
}
@@ -448,7 +448,7 @@ sym_cmp(mrb_state *mrb, mrb_value s1)
else {
const char *p1, *p2;
int retval;
- size_t len, len1, len2;
+ mrb_int len, len1, len2;
p1 = mrb_sym2name_len(mrb, sym1, &len1);
p2 = mrb_sym2name_len(mrb, sym2, &len2);
diff --git a/src/variable.c b/src/variable.c
index c313a8f14..8e427829a 100644
--- a/src/variable.c
+++ b/src/variable.c
@@ -562,7 +562,7 @@ inspect_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p)
{
mrb_value str = *(mrb_value*)p;
const char *s;
- size_t len;
+ mrb_int len;
mrb_value ins;
/* need not to show internal data */
@@ -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));
@@ -641,7 +641,7 @@ iv_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p)
{
mrb_value ary;
const char* s;
- size_t len;
+ mrb_int len;
ary = *(mrb_value*)p;
s = mrb_sym2name_len(mrb, sym, &len);
@@ -685,7 +685,7 @@ cv_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p)
{
mrb_value ary;
const char* s;
- size_t len;
+ mrb_int len;
ary = *(mrb_value*)p;
s = mrb_sym2name_len(mrb, sym, &len);
@@ -949,7 +949,7 @@ const_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p)
{
mrb_value ary;
const char* s;
- size_t len;
+ mrb_int len;
ary = *(mrb_value*)p;
s = mrb_sym2name_len(mrb, sym, &len);
diff --git a/src/vm.c b/src/vm.c
index a99379e15..dc32ae7c8 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -451,7 +451,8 @@ mrb_f_send(mrb_state *mrb, mrb_value self)
c = mrb_class(mrb, self);
p = mrb_method_search_vm(mrb, &c, name);
- if (!p || MRB_PROC_CFUNC_P(p)) {
+
+ if (!p) { /* call method_mising */
return mrb_funcall_with_block(mrb, self, name, argc, argv, block);
}
@@ -470,6 +471,11 @@ mrb_f_send(mrb_state *mrb, mrb_value self)
else { /* variable length arguments */
mrb_ary_shift(mrb, regs[0]);
}
+
+ if (MRB_PROC_CFUNC_P(p)) {
+ return p->body.func(mrb, self);
+ }
+
cipush(mrb);
ci = mrb->c->ci;
ci->target_class = 0;
@@ -1203,8 +1209,7 @@ RETRY_TRY_BLOCK:
struct REnv *e = uvenv(mrb, lv-1);
if (!e) {
mrb_value exc;
- static const char m[] = "super called outside of method";
- exc = mrb_exc_new(mrb, E_NOMETHOD_ERROR, m, sizeof(m) - 1);
+ exc = mrb_exc_new_str_lit(mrb, E_NOMETHOD_ERROR, "super called outside of method");
mrb->exc = mrb_obj_ptr(exc);
goto L_RAISE;
}
@@ -1418,7 +1423,7 @@ RETRY_TRY_BLOCK:
goto L_RAISE;
}
if (mrb->c->prev->ci == mrb->c->prev->cibase) {
- mrb_value exc = mrb_exc_new_str(mrb, E_RUNTIME_ERROR, mrb_str_new_lit(mrb, "double resume"));
+ mrb_value exc = mrb_exc_new_str_lit(mrb, E_RUNTIME_ERROR, "double resume");
mrb->exc = mrb_obj_ptr(exc);
goto L_RAISE;
}
@@ -2186,8 +2191,7 @@ RETRY_TRY_BLOCK:
CASE(OP_TCLASS) {
/* A B R(A) := target_class */
if (!mrb->c->ci->target_class) {
- static const char msg[] = "no target class or module";
- mrb_value exc = mrb_exc_new(mrb, E_TYPE_ERROR, msg, sizeof(msg) - 1);
+ mrb_value exc = mrb_exc_new_str_lit(mrb, E_TYPE_ERROR, "no target class or module");
mrb->exc = mrb_obj_ptr(exc);
goto L_RAISE;
}