Merge upstream

This commit is contained in:
Daniel Bovensiepen
2013-06-15 03:53:50 +08:00
89 changed files with 1340 additions and 765 deletions
+23 -47
View File
@@ -19,7 +19,7 @@
#define ARY_DEFAULT_LEN 4
#define ARY_SHRINK_RATIO 5 /* must be larger than 2 */
#define ARY_C_MAX_SIZE (SIZE_MAX / sizeof(mrb_value))
#define ARY_MAX_SIZE ((ARY_C_MAX_SIZE < (size_t)MRB_INT_MAX) ? (mrb_int)ARY_C_MAX_SIZE : MRB_INT_MAX)
#define ARY_MAX_SIZE ((ARY_C_MAX_SIZE < (size_t)MRB_INT_MAX) ? (mrb_int)ARY_C_MAX_SIZE : MRB_INT_MAX-1)
static inline mrb_value
ary_elt(mrb_value ary, mrb_int offset)
@@ -40,7 +40,7 @@ ary_new_capa(mrb_state *mrb, mrb_int capa)
if (capa > ARY_MAX_SIZE) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");
}
blen = capa * sizeof(mrb_value) ;
blen = capa * sizeof(mrb_value);
if (blen < capa) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");
}
@@ -926,7 +926,8 @@ inspect_ary(mrb_state *mrb, mrb_value ary, mrb_value list)
}
if (mrb_array_p(RARRAY_PTR(ary)[i])) {
s = inspect_ary(mrb, RARRAY_PTR(ary)[i], list);
} else {
}
else {
s = mrb_inspect(mrb, RARRAY_PTR(ary)[i]);
}
mrb_str_buf_cat(mrb, arystr, RSTRING_PTR(s), RSTRING_LEN(s));
@@ -1056,39 +1057,26 @@ static mrb_value
mrb_ary_equal(mrb_state *mrb, mrb_value ary1)
{
mrb_value ary2;
mrb_bool equal_p;
mrb_int i;
mrb_get_args(mrb, "o", &ary2);
if (mrb_obj_equal(mrb, ary1, ary2)) {
equal_p = 1;
}
else if (mrb_special_const_p(ary2)) {
equal_p = 0;
}
else if (!mrb_array_p(ary2)) {
if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_true_value();
if (mrb_special_const_p(ary2)) return mrb_false_value();
if (!mrb_array_p(ary2)) {
if (!mrb_respond_to(mrb, ary2, mrb_intern2(mrb, "to_ary", 6))) {
equal_p = 0;
return mrb_false_value();
}
else {
equal_p = mrb_equal(mrb, ary2, ary1);
return mrb_bool_value(mrb_equal(mrb, ary2, ary1));
}
}
else if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) {
equal_p = 0;
}
else {
mrb_int i;
equal_p = 1;
for (i=0; i<RARRAY_LEN(ary1); i++) {
if (!mrb_equal(mrb, ary_elt(ary1, i), ary_elt(ary2, i))) {
equal_p = 0;
break;
}
if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return mrb_false_value();
for (i=0; i<RARRAY_LEN(ary1); i++) {
if (!mrb_equal(mrb, ary_elt(ary1, i), ary_elt(ary2, i))) {
return mrb_false_value();
}
}
return mrb_bool_value(equal_p);
return mrb_true_value();
}
/* 15.2.12.5.34 (x) */
@@ -1104,30 +1092,18 @@ static mrb_value
mrb_ary_eql(mrb_state *mrb, mrb_value ary1)
{
mrb_value ary2;
mrb_bool eql_p;
mrb_int i;
mrb_get_args(mrb, "o", &ary2);
if (mrb_obj_equal(mrb, ary1, ary2)) {
eql_p = 1;
}
else if (!mrb_array_p(ary2)) {
eql_p = 0;
}
else if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) {
eql_p = 0;
}
else {
mrb_int i;
eql_p = 1;
for (i=0; i<RARRAY_LEN(ary1); i++) {
if (!mrb_eql(mrb, ary_elt(ary1, i), ary_elt(ary2, i))) {
eql_p = 0;
break;
}
if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_true_value();
if (!mrb_array_p(ary2)) return mrb_false_value();
if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return mrb_false_value();
for (i=0; i<RARRAY_LEN(ary1); i++) {
if (!mrb_eql(mrb, ary_elt(ary1, i), ary_elt(ary2, i))) {
return mrb_false_value();
}
}
return mrb_bool_value(eql_p);
return mrb_true_value();
}
void
+2 -2
View File
@@ -18,7 +18,7 @@ mrb_print_backtrace(mrb_state *mrb)
int i, line;
fputs("trace:\n", stderr);
ciidx = mrb_fixnum(mrb_obj_iv_get(mrb, mrb->exc, mrb_intern(mrb, "ciidx")));
ciidx = mrb_fixnum(mrb_obj_iv_get(mrb, mrb->exc, mrb_intern2(mrb, "ciidx", 5)));
if (ciidx >= mrb->c->ciend - mrb->c->cibase)
ciidx = 10; /* ciidx is broken... */
@@ -41,7 +41,7 @@ mrb_print_backtrace(mrb_state *mrb)
pc = mrb->c->cibase[i+1].pc;
}
else {
pc = (mrb_code*)mrb_voidp(mrb_obj_iv_get(mrb, mrb->exc, mrb_intern(mrb, "lastpc")));
pc = (mrb_code*)mrb_voidp(mrb_obj_iv_get(mrb, mrb->exc, mrb_intern2(mrb, "lastpc", 6)));
}
if (irep->iseq <= pc && pc < irep->iseq + irep->ilen) {
line = irep->lines[pc - irep->iseq - 1];
+70 -49
View File
@@ -55,7 +55,7 @@ mrb_name_class(mrb_state *mrb, struct RClass *c, mrb_sym name)
mrb_obj_iv_set(mrb, (struct RObject*)c,
mrb_intern2(mrb, "__classid__", 11), mrb_symbol_value(name));
}
#define make_metaclass(mrb, c) prepare_singleton_class((mrb), (struct RBasic*)(c))
static void
@@ -78,6 +78,8 @@ prepare_singleton_class(mrb_state *mrb, struct RBasic *o)
}
else if (o->tt == MRB_TT_SCLASS) {
c = (struct RClass*)o;
while (c->super->tt == MRB_TT_ICLASS)
c = c->super;
make_metaclass(mrb, c->super);
sc->super = c->super->c;
}
@@ -105,7 +107,7 @@ mrb_define_module_id(mrb_state *mrb, mrb_sym name)
struct RClass*
mrb_define_module(mrb_state *mrb, const char *name)
{
return mrb_define_module_id(mrb, mrb_intern(mrb, name));
return mrb_define_module_id(mrb, mrb_intern_cstr(mrb, name));
}
static void
@@ -159,9 +161,7 @@ mrb_define_class_id(mrb_state *mrb, mrb_sym name, struct RClass *super)
struct RClass*
mrb_define_class(mrb_state *mrb, const char *name, struct RClass *super)
{
struct RClass *c;
c = mrb_define_class_id(mrb, mrb_intern(mrb, name), super);
return c;
return mrb_define_class_id(mrb, mrb_intern_cstr(mrb, name), super);
}
struct RClass*
@@ -203,7 +203,7 @@ mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id
return c;
}
int
mrb_bool
mrb_class_defined(mrb_state *mrb, const char *name)
{
mrb_value sym = mrb_check_intern_cstr(mrb, name);
@@ -227,7 +227,13 @@ class_from_sym(mrb_state *mrb, struct RClass *klass, mrb_sym id)
struct RClass *
mrb_class_get(mrb_state *mrb, const char *name)
{
return class_from_sym(mrb, mrb->object_class, mrb_intern(mrb, name));
return mrb_class_get_under(mrb, mrb->object_class, name);
}
struct RClass *
mrb_class_get_under(mrb_state *mrb, struct RClass *outer, const char *name)
{
return class_from_sym(mrb, outer, mrb_intern_cstr(mrb, name));
}
/*!
@@ -250,7 +256,7 @@ struct RClass *
mrb_define_class_under(mrb_state *mrb, struct RClass *outer, const char *name, struct RClass *super)
{
struct RClass * c;
mrb_sym id = mrb_intern(mrb, name);
mrb_sym id = mrb_intern_cstr(mrb, name);
if (mrb_const_defined_at(mrb, outer, id)) {
c = class_from_sym(mrb, outer, id);
@@ -272,7 +278,7 @@ struct RClass *
mrb_define_module_under(mrb_state *mrb, struct RClass *outer, const char *name)
{
struct RClass * c;
mrb_sym id = mrb_intern(mrb, name);
mrb_sym id = mrb_intern_cstr(mrb, name);
if (mrb_const_defined_at(mrb, outer, id)) {
c = class_from_sym(mrb, outer, id);
@@ -313,7 +319,7 @@ mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t f
void
mrb_define_method(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec)
{
mrb_define_method_id(mrb, c, mrb_intern(mrb, name), func, aspec);
mrb_define_method_id(mrb, c, mrb_intern_cstr(mrb, name), func, aspec);
}
void
@@ -371,20 +377,22 @@ to_hash(mrb_state *mrb, mrb_value val)
format specifiers:
o: Object [mrb_value]
S: String [mrb_value]
A: Array [mrb_value]
H: Hash [mrb_value]
s: String [char*,int]
z: String [char*]
a: Array [mrb_value*,mrb_int]
f: Float [mrb_float]
i: Integer [mrb_int]
b: Boolean [mrb_bool]
n: Symbol [mrb_sym]
&: Block [mrb_value]
*: rest argument [mrb_value*,int]
|: optional
string mruby type C type note
----------------------------------------------------------------------------------------------
o: Object [mrb_value]
S: String [mrb_value]
A: Array [mrb_value]
H: Hash [mrb_value]
s: String [char*,int] Receive two arguments.
z: String [char*] NUL terminated string.
a: Array [mrb_value*,mrb_int] Receive two arguments.
f: Float [mrb_float]
i: Integer [mrb_int]
b: Boolean [mrb_bool]
n: Symbol [mrb_sym]
&: 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.
*/
int
mrb_get_args(mrb_state *mrb, const char *format, ...)
@@ -487,7 +495,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
if (i < argc) {
ss = to_str(mrb, *sp++);
s = mrb_str_ptr(ss);
if (strlen(s->ptr) != s->len) {
if (strlen(s->ptr) < s->len) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "String contains NUL");
}
*ps = s->ptr;
@@ -902,6 +910,12 @@ mrb_mod_module_eval(mrb_state *mrb, mrb_value mod)
return mrb_yield_internal(mrb, b, 0, 0, mod, c);
}
mrb_value
mrb_mod_dummy_visibility(mrb_state *mrb, mrb_value mod)
{
return mod;
}
mrb_value
mrb_singleton_class(mrb_state *mrb, mrb_value v)
{
@@ -933,7 +947,7 @@ void
mrb_define_singleton_method(mrb_state *mrb, struct RObject *o, const char *name, mrb_func_t func, mrb_aspec aspec)
{
prepare_singleton_class(mrb, (struct RBasic*)o);
mrb_define_method_id(mrb, o->c, mrb_intern(mrb, name), func, aspec);
mrb_define_method_id(mrb, o->c, mrb_intern_cstr(mrb, name), func, aspec);
}
void
@@ -1069,6 +1083,7 @@ mrb_class_new_class(mrb_state *mrb, mrb_value cv)
super = mrb_obj_value(mrb->object_class);
}
new_class = mrb_class_new(mrb, mrb_class_ptr(super));
mrb_funcall(mrb, super, "inherited", 1, mrb_obj_value(new_class));
return mrb_obj_value(new_class);
}
@@ -1134,16 +1149,14 @@ mrb_bob_not(mrb_state *mrb, mrb_value cv)
static mrb_value
mrb_bob_missing(mrb_state *mrb, mrb_value mod)
{
mrb_value name, *a;
mrb_sym name;
mrb_value *a;
int alen;
mrb_value inspect;
mrb_get_args(mrb, "o*", &name, &a, &alen);
if (!mrb_symbol_p(name)) {
mrb_raise(mrb, E_TYPE_ERROR, "name should be a symbol");
}
mrb_get_args(mrb, "n*", &name, &a, &alen);
if (mrb_respond_to(mrb,mod,mrb_intern2(mrb,"inspect",7))){
if (mrb_respond_to(mrb,mod,mrb_intern2(mrb, "inspect",7))){
inspect = mrb_funcall(mrb, mod, "inspect", 0);
if (RSTRING_LEN(inspect) > 64) {
inspect = mrb_any_to_s(mrb, mod);
@@ -1154,12 +1167,12 @@ mrb_bob_missing(mrb_state *mrb, mrb_value mod)
}
mrb_raisef(mrb, E_NOMETHOD_ERROR, "undefined method '%S' for %S",
mrb_sym2str(mrb, mrb_symbol(name)), inspect);
mrb_sym2str(mrb, name), inspect);
/* not reached */
return mrb_nil_value();
}
int
mrb_bool
mrb_obj_respond_to(struct RClass* c, mrb_sym mid)
{
khiter_t k;
@@ -1183,7 +1196,7 @@ mrb_obj_respond_to(struct RClass* c, mrb_sym mid)
return FALSE; /* no method */
}
int
mrb_bool
mrb_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym mid)
{
return mrb_obj_respond_to(mrb_class(mrb, obj), mid);
@@ -1338,7 +1351,7 @@ mrb_alias_method(mrb_state *mrb, struct RClass *c, mrb_sym a, mrb_sym b)
void
mrb_define_alias(mrb_state *mrb, struct RClass *klass, const char *name1, const char *name2)
{
mrb_alias_method(mrb, klass, mrb_intern(mrb, name1), mrb_intern(mrb, name2));
mrb_alias_method(mrb, klass, mrb_intern_cstr(mrb, name1), mrb_intern_cstr(mrb, name2));
}
/*
@@ -1410,10 +1423,10 @@ mrb_value
mrb_mod_alias(mrb_state *mrb, mrb_value mod)
{
struct RClass *c = mrb_class_ptr(mod);
mrb_value new_value, old_value;
mrb_sym new_name, old_name;
mrb_get_args(mrb, "oo", &new_value, &old_value);
mrb_alias_method(mrb, c, mrb_symbol(new_value), mrb_symbol(old_value));
mrb_get_args(mrb, "nn", &new_name, &old_name);
mrb_alias_method(mrb, c, new_name, old_name);
return mrb_nil_value();
}
@@ -1424,7 +1437,8 @@ undef_method(mrb_state *mrb, struct RClass *c, mrb_sym a)
if (!mrb_obj_respond_to(c, a)) {
mrb_name_error(mrb, a, "undefined method '%S' for class '%S'", mrb_sym2str(mrb, a), mrb_obj_value(c));
} else {
}
else {
MRB_SET_VALUE(m, MRB_TT_PROC, value.p, 0);
mrb_define_method_vm(mrb, c, a, m);
}
@@ -1433,7 +1447,7 @@ undef_method(mrb_state *mrb, struct RClass *c, mrb_sym a)
void
mrb_undef_method(mrb_state *mrb, struct RClass *c, const char *name)
{
undef_method(mrb, c, mrb_intern(mrb, name));
undef_method(mrb, c, mrb_intern_cstr(mrb, name));
}
void
@@ -1506,7 +1520,8 @@ get_sym_or_str_arg(mrb_state *mrb)
if (mrb_symbol_p(sym_or_str) || mrb_string_p(sym_or_str)) {
return sym_or_str;
} else {
}
else {
mrb_value obj = mrb_funcall(mrb, sym_or_str, "inspect", 0);
mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", obj);
return mrb_nil_value();
@@ -1538,7 +1553,8 @@ mrb_mod_cvar_defined(mrb_state *mrb, mrb_value mod)
if (mrb_symbol_p(id)) {
check_cv_name_sym(mrb, mrb_symbol(id));
defined_p = mrb_cv_defined(mrb, mod, mrb_symbol(id));
} else {
}
else {
mrb_value sym;
check_cv_name_str(mrb, id);
sym = mrb_check_intern_str(mrb, id);
@@ -1690,7 +1706,8 @@ mrb_mod_method_defined(mrb_state *mrb, mrb_value mod)
id = get_sym_or_str_arg(mrb);
if (mrb_symbol_p(id)) {
method_defined_p = mrb_obj_respond_to(mrb_class_ptr(mod), mrb_symbol(id));
} else {
}
else {
mrb_value sym = mrb_check_intern_str(mrb, id);
if (mrb_nil_p(sym)) {
method_defined_p = FALSE;
@@ -1774,7 +1791,8 @@ mrb_mod_const_defined(mrb_state *mrb, mrb_value mod)
if (mrb_type(id) == MRB_TT_SYMBOL) {
check_const_name_sym(mrb, mrb_symbol(id));
const_defined_p = mrb_const_defined(mrb, mod, mrb_symbol(id));
} else {
}
else {
mrb_value sym;
check_const_name_str(mrb, id);
sym = mrb_check_intern_str(mrb, id);
@@ -1874,10 +1892,10 @@ mrb_init_class(mrb_state *mrb)
mrb_define_const(mrb, obj, "Class", mrb_obj_value(cls));
/* name each classes */
mrb_name_class(mrb, bob, mrb_intern(mrb, "BasicObject"));
mrb_name_class(mrb, obj, mrb_intern(mrb, "Object")); /* 15.2.1 */
mrb_name_class(mrb, mod, mrb_intern(mrb, "Module")); /* 15.2.2 */
mrb_name_class(mrb, cls, mrb_intern(mrb, "Class")); /* 15.2.3 */
mrb_name_class(mrb, bob, mrb_intern2(mrb, "BasicObject", 11)); /* 15.2.1 */
mrb_name_class(mrb, obj, mrb_intern2(mrb, "Object", 6)); /* 15.2.1 */
mrb_name_class(mrb, mod, mrb_intern2(mrb, "Module", 6)); /* 15.2.2 */
mrb_name_class(mrb, cls, mrb_intern2(mrb, "Class", 5)); /* 15.2.3 */
MRB_SET_INSTANCE_TT(cls, MRB_TT_CLASS);
mrb_define_method(mrb, bob, "initialize", mrb_bob_init, MRB_ARGS_NONE());
@@ -1904,6 +1922,9 @@ mrb_init_class(mrb_state *mrb)
mrb_define_method(mrb, mod, "instance_methods", mrb_mod_instance_methods, MRB_ARGS_ANY()); /* 15.2.2.4.33 */
mrb_define_method(mrb, mod, "method_defined?", mrb_mod_method_defined, MRB_ARGS_REQ(1)); /* 15.2.2.4.34 */
mrb_define_method(mrb, mod, "module_eval", mrb_mod_module_eval, MRB_ARGS_ANY()); /* 15.2.2.4.35 */
mrb_define_method(mrb, mod, "private", mrb_mod_dummy_visibility, MRB_ARGS_ANY()); /* 15.2.2.4.36 */
mrb_define_method(mrb, mod, "protected", mrb_mod_dummy_visibility, MRB_ARGS_ANY()); /* 15.2.2.4.37 */
mrb_define_method(mrb, mod, "public", mrb_mod_dummy_visibility, MRB_ARGS_ANY()); /* 15.2.2.4.38 */
mrb_define_method(mrb, mod, "remove_class_variable", mrb_mod_remove_cvar, MRB_ARGS_REQ(1)); /* 15.2.2.4.39 */
mrb_define_method(mrb, mod, "remove_method", mrb_mod_remove_method, MRB_ARGS_ANY()); /* 15.2.2.4.41 */
mrb_define_method(mrb, mod, "to_s", mrb_mod_to_s, MRB_ARGS_NONE());
+17 -15
View File
@@ -59,7 +59,7 @@ typedef struct scope {
int icapa;
mrb_irep *irep;
int pcapa;
size_t pcapa;
int scapa;
int nlocals;
@@ -426,9 +426,8 @@ push_(codegen_scope *s)
static inline int
new_lit(codegen_scope *s, mrb_value val)
{
int i;
size_t i;
switch (mrb_type(val)) {
case MRB_TT_STRING:
for (i=0; i<s->irep->plen; i++) {
@@ -448,7 +447,7 @@ new_lit(codegen_scope *s, mrb_value val)
}
break;
}
if (s->irep->plen == s->pcapa) {
s->pcapa *= 2;
s->irep->pool = (mrb_value *)codegen_realloc(s, s->irep->pool, sizeof(mrb_value)*s->pcapa);
@@ -462,7 +461,7 @@ new_lit(codegen_scope *s, mrb_value val)
static inline int
new_msym(codegen_scope *s, mrb_sym sym)
{
int i, len;
size_t i, len;
len = s->irep->slen;
if (len > 256) len = 256;
@@ -481,7 +480,7 @@ new_msym(codegen_scope *s, mrb_sym sym)
static inline int
new_sym(codegen_scope *s, mrb_sym sym)
{
int i;
size_t i;
for (i=0; i<s->irep->slen; i++) {
if (s->irep->syms[i] == sym) return i;
@@ -684,7 +683,7 @@ scope_body(codegen_scope *s, node *tree)
return idx - s->idx;
}
static int
static mrb_bool
nosplat(node *t)
{
while (t) {
@@ -2065,7 +2064,7 @@ codegen(codegen_scope *s, node *tree, int val)
char *p1 = (char*)tree->car;
char *p2 = (char*)tree->cdr;
int ai = mrb_gc_arena_save(s->mrb);
int sym = new_sym(s, mrb_intern(s->mrb, REGEXP_CLASS));
int sym = new_sym(s, mrb_intern2(s->mrb, REGEXP_CLASS, REGEXP_CLASS_CSTR_LEN));
int off = new_lit(s, mrb_str_new(s->mrb, p1, strlen(p1)));
int argc = 1;
@@ -2092,7 +2091,7 @@ codegen(codegen_scope *s, node *tree, int val)
if (val) {
node *n = tree->car;
int ai = mrb_gc_arena_save(s->mrb);
int sym = new_sym(s, mrb_intern(s->mrb, REGEXP_CLASS));
int sym = new_sym(s, mrb_intern2(s->mrb, REGEXP_CLASS, REGEXP_CLASS_CSTR_LEN));
int argc = 1;
int off;
char *p;
@@ -2506,7 +2505,8 @@ codedump(mrb_state *mrb, int n)
{
#ifdef ENABLE_STDIO
mrb_irep *irep = mrb->irep[n];
int i, ai;
uint32_t i;
int ai;
mrb_code c;
if (!irep) return;
@@ -2842,13 +2842,15 @@ codegen_start(mrb_state *mrb, parser_state *p)
if (p->filename) {
scope->filename = p->filename;
}
if (setjmp(scope->jmp) != 0) {
if (setjmp(scope->jmp) == 0) {
// prepare irep
codegen(scope, p->tree, NOVAL);
mrb_pool_close(scope->mpool);
return 0;
}
else {
return -1;
}
// prepare irep
codegen(scope, p->tree, NOVAL);
mrb_pool_close(scope->mpool);
return 0;
}
int
+1 -1
View File
@@ -6,7 +6,7 @@
#include <limits.h>
#include <stdint.h>
#include <sys/types.h>
#include <stddef.h>
// Calculate CRC (CRC-16-CCITT)
//
+4 -5
View File
@@ -334,8 +334,7 @@ static int
write_lineno_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin)
{
uint8_t *cur = bin;
size_t filename_len = 0;
int iseq_no;
size_t filename_len = 0, iseq_no;
cur += sizeof(uint32_t); /* record size */
@@ -365,13 +364,13 @@ write_lineno_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin)
}
static int
mrb_write_section_lineno(mrb_state *mrb, int start_index, uint8_t *bin)
mrb_write_section_lineno(mrb_state *mrb, size_t start_index, uint8_t *bin)
{
int irep_no;
size_t irep_no;
uint32_t section_size = 0, rlen = 0; /* size of irep record */
uint8_t *cur = bin;
if (mrb == NULL || start_index < 0 || start_index >= mrb->irep_len || bin == NULL) {
if (mrb == NULL || start_index >= mrb->irep_len || bin == NULL) {
return MRB_DUMP_INVALID_ARGUMENT;
}
+7 -5
View File
@@ -5,7 +5,6 @@
*/
#include <errno.h>
#include <setjmp.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
@@ -147,7 +146,8 @@ exc_inspect(mrb_state *mrb, mrb_value exc)
if (!mrb_nil_p(mesg) && RSTRING_LEN(mesg) > 0) {
mrb_str_cat(mrb, str, ": ", 2);
mrb_str_append(mrb, str, mesg);
} else {
}
else {
mrb_str_cat(mrb, str, ": ", 2);
mrb_str_cat_cstr(mrb, str, mrb_obj_classname(mrb, exc));
}
@@ -218,7 +218,7 @@ mrb_exc_raise(mrb_state *mrb, mrb_value exc)
mrb_p(mrb, exc);
abort();
}
longjmp(*(jmp_buf*)mrb->jmp, 1);
mrb_longjmp(mrb);
}
void
@@ -425,10 +425,12 @@ mrb_sys_fail(mrb_state *mrb, const char *mesg)
sce = mrb_class_get(mrb, "SystemCallError");
if (mesg != NULL) {
mrb_funcall(mrb, mrb_obj_value(sce), "_sys_fail", 2, mrb_fixnum_value(no), mrb_str_new_cstr(mrb, mesg));
} else {
}
else {
mrb_funcall(mrb, mrb_obj_value(sce), "_sys_fail", 1, mrb_fixnum_value(no));
}
} else {
}
else {
mrb_raise(mrb, E_RUNTIME_ERROR, mesg);
}
}
+1
View File
@@ -14,5 +14,6 @@ mrb_value make_exception(mrb_state *mrb, int argc, mrb_value *argv, int isstr);
mrb_value mrb_make_exception(mrb_state *mrb, int argc, mrb_value *argv);
mrb_value mrb_format(mrb_state *mrb, const char *format, ...);
void mrb_exc_print(mrb_state *mrb, struct RObject *exc);
void mrb_longjmp(mrb_state *mrb);
#endif /* MRUBY_ERROR_H */
+192 -143
View File
@@ -11,6 +11,7 @@
# include <limits.h>
#endif
#include <string.h>
#include <stdlib.h>
#include "mruby.h"
#include "mruby/array.h"
#include "mruby/class.h"
@@ -37,18 +38,23 @@
* Gray - Marked, But the child objects are unmarked.
* Black - Marked, the child objects are also marked.
== Two white part
== Two White Types
The white has a different part of A and B.
In sweep phase, the sweep target white is either A or B.
The sweep target white is switched just before sweep phase.
e.g. A -> B -> A -> B ...
There're two white color types in a flip-flop fassion: White-A and White-B,
which respectively represent the Current White color (the newly allocated
objects in the current GC cycle) and the Sweep Target White color (the
dead objects to be swept).
All objects are painted white when allocated.
This white is another the sweep target white.
For example, if the sweep target white is A, it's B.
So objects when allocated in sweep phase will be next sweep phase target.
Therefore, these objects will not be released accidentally in sweep phase.
A and B will be switched just at the beginning of the next GC cycle. At
that time, all the dead objects have been swept, while the newly created
objects in the current GC cycle which finally remains White are now
regarded as dead objects. Instead of traversing all the White-A objects and
paint them as White-B, just switch the meaning of White-A and White-B would
be much cheaper.
As a result, the objects we sweep in the current GC cycle are always
left from the previous GC cycle. This allows us to sweep objects
incrementally, without the disturbance of the newly created objects.
== Execution Timing
@@ -60,7 +66,7 @@
For details, see the comments for each function.
= Write Barrier
== Write Barrier
mruby implementer, C extension library writer must write a write
barrier when writing a pointer to an object on object's field.
@@ -69,6 +75,20 @@
* mrb_field_write_barrier
* mrb_write_barrier
== Generational Mode
mruby's GC offers an Generational Mode while re-using the tri-color GC
infrastructure. It will treat the Black objects as Old objects after each
sweep phase, instead of paint them to White. The key idea are still same as
the traditional generational GC:
* Minor GC - just traverse the Young objects (Gray objects) in the mark
phase, then only sweep the newly created objects, and leave
the Old objects live.
* Major GC - same as a full regular GC cycle.
For details, see the comments for each function.
*/
@@ -137,39 +157,46 @@ gettimeofday_time(void)
#endif
#ifdef GC_DEBUG
#include <assert.h>
#define gc_assert(expect) assert(expect)
#define DEBUG(x) (x)
#else
#define gc_assert(expect) ((void)0)
#define DEBUG(x)
#endif
#define GC_STEP_SIZE 1024
void*
mrb_realloc_simple(mrb_state *mrb, void *p, size_t len)
{
void *p2;
p2 = (mrb->allocf)(mrb, p, len, mrb->ud);
if (!p2 && len > 0 && mrb->heaps) {
mrb_full_gc(mrb);
p2 = (mrb->allocf)(mrb, p, len, mrb->ud);
}
return p2;
}
void*
mrb_realloc(mrb_state *mrb, void *p, size_t len)
{
void *p2;
p2 = (mrb->allocf)(mrb, p, len, mrb->ud);
if (!p2 && len > 0 && mrb->heaps) {
mrb_garbage_collect(mrb);
p2 = (mrb->allocf)(mrb, p, len, mrb->ud);
}
p2 = mrb_realloc_simple(mrb, p, len);
if (!p2 && len) {
if (mrb->out_of_memory) {
/* mrb_panic(mrb); */
}
else {
mrb->out_of_memory = 1;
mrb->out_of_memory = TRUE;
mrb_raise(mrb, E_RUNTIME_ERROR, "Out of memory");
}
}
else {
mrb->out_of_memory = 0;
mrb->out_of_memory = FALSE;
}
return p2;
@@ -181,6 +208,12 @@ mrb_malloc(mrb_state *mrb, size_t len)
return mrb_realloc(mrb, 0, len);
}
void*
mrb_malloc_simple(mrb_state *mrb, size_t len)
{
return mrb_realloc_simple(mrb, 0, len);
}
void*
mrb_calloc(mrb_state *mrb, size_t nelem, size_t len)
{
@@ -195,7 +228,8 @@ mrb_calloc(mrb_state *mrb, size_t nelem, size_t len)
if (p) {
memset(p, 0, size);
}
} else {
}
else {
p = NULL;
}
@@ -295,8 +329,8 @@ add_heap(mrb_state *mrb)
void
mrb_init_heap(mrb_state *mrb)
{
mrb->heaps = 0;
mrb->free_heaps = 0;
mrb->heaps = NULL;
mrb->free_heaps = NULL;
add_heap(mrb);
mrb->gc_interval_ratio = DEFAULT_GC_INTERVAL_RATIO;
mrb->gc_step_ratio = DEFAULT_GC_STEP_RATIO;
@@ -353,7 +387,7 @@ mrb_obj_alloc(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls)
static const RVALUE RVALUE_zero = { { { MRB_TT_FALSE } } };
#ifdef MRB_GC_STRESS
mrb_garbage_collect(mrb);
mrb_full_gc(mrb);
#endif
if (mrb->gc_threshold < mrb->live) {
mrb_incremental_gc(mrb);
@@ -390,6 +424,20 @@ add_gray_list(mrb_state *mrb, struct RBasic *obj)
mrb->gray_list = obj;
}
static void
mark_context_stack(mrb_state *mrb, struct mrb_context *c)
{
size_t i;
size_t e;
e = c->stack - c->stbase;
if (c->ci) e += c->ci->nregs;
if (c->stbase + e > c->stend) e = c->stend - c->stbase;
for (i=0; i<e; i++) {
mrb_gc_mark_value(mrb, c->stbase[i]);
}
}
static void
mark_context(mrb_state *mrb, struct mrb_context *c)
{
@@ -398,12 +446,8 @@ mark_context(mrb_state *mrb, struct mrb_context *c)
mrb_callinfo *ci;
/* mark stack */
e = c->stack - c->stbase;
if (c->ci) e += c->ci->nregs;
if (c->stbase + e > c->stend) e = c->stend - c->stbase;
for (i=0; i<e; i++) {
mrb_gc_mark_value(mrb, c->stbase[i]);
}
mark_context_stack(mrb, c);
/* mark ensure stack */
e = (c->ci) ? c->ci->eidx : 0;
for (i=0; i<e; i++) {
@@ -424,7 +468,7 @@ mark_context(mrb_state *mrb, struct mrb_context *c)
static void
gc_mark_children(mrb_state *mrb, struct RBasic *obj)
{
gc_assert(is_gray(obj));
mrb_assert(is_gray(obj));
paint_black(obj);
mrb->gray_list = obj->gcnext;
mrb_gc_mark(mrb, (struct RBasic*)obj->c);
@@ -521,7 +565,7 @@ mrb_gc_mark(mrb_state *mrb, struct RBasic *obj)
{
if (obj == 0) return;
if (!is_white(obj)) return;
gc_assert((obj)->tt != MRB_TT_FREE);
mrb_assert((obj)->tt != MRB_TT_FREE);
add_gray_list(mrb, obj);
}
@@ -561,7 +605,7 @@ obj_free(mrb_state *mrb, struct RBasic *obj)
if (e->cioff < 0) {
mrb_free(mrb, e->stack);
e->stack = 0;
e->stack = NULL;
}
}
break;
@@ -613,12 +657,11 @@ obj_free(mrb_state *mrb, struct RBasic *obj)
static void
root_scan_phase(mrb_state *mrb)
{
int j;
size_t i, e;
size_t i, e, j;
if (!is_minor_gc(mrb)) {
mrb->gray_list = 0;
mrb->variable_gray_list = 0;
mrb->gray_list = NULL;
mrb->atomic_gray_list = NULL;
}
mrb_gc_mark_gv(mrb);
@@ -728,6 +771,18 @@ gc_gray_mark(mrb_state *mrb, struct RBasic *obj)
return children;
}
static void
gc_mark_gray_list(mrb_state *mrb) {
while (mrb->gray_list) {
if (is_gray(mrb->gray_list))
gc_mark_children(mrb, mrb->gray_list);
else
mrb->gray_list = mrb->gray_list->gcnext;
}
}
static size_t
incremental_marking_phase(mrb_state *mrb, size_t limit)
{
@@ -743,22 +798,13 @@ incremental_marking_phase(mrb_state *mrb, size_t limit)
static void
final_marking_phase(mrb_state *mrb)
{
while (mrb->gray_list) {
if (is_gray(mrb->gray_list))
gc_mark_children(mrb, mrb->gray_list);
else
mrb->gray_list = mrb->gray_list->gcnext;
}
gc_assert(mrb->gray_list == NULL);
mrb->gray_list = mrb->variable_gray_list;
mrb->variable_gray_list = 0;
while (mrb->gray_list) {
if (is_gray(mrb->gray_list))
gc_mark_children(mrb, mrb->gray_list);
else
mrb->gray_list = mrb->gray_list->gcnext;
}
gc_assert(mrb->gray_list == NULL);
mark_context_stack(mrb, mrb->root_c);
gc_mark_gray_list(mrb);
mrb_assert(mrb->gray_list == NULL);
mrb->gray_list = mrb->atomic_gray_list;
mrb->atomic_gray_list = NULL;
gc_mark_gray_list(mrb);
mrb_assert(mrb->gray_list == NULL);
}
static void
@@ -858,17 +904,31 @@ incremental_gc(mrb_state *mrb, size_t limit)
}
default:
/* unknown state */
gc_assert(0);
mrb_assert(0);
return 0;
}
}
static void
advance_phase(mrb_state *mrb, enum gc_state to_state)
incremental_gc_until(mrb_state *mrb, enum gc_state to_state)
{
while (mrb->gc_state != to_state) {
do {
incremental_gc(mrb, ~0);
} while (mrb->gc_state != to_state);
}
static void
incremental_gc_step(mrb_state *mrb)
{
size_t limit = 0, result = 0;
limit = (GC_STEP_SIZE/100) * mrb->gc_step_ratio;
while (result < limit) {
result += incremental_gc(mrb, limit);
if (mrb->gc_state == GC_STATE_NONE)
break;
}
mrb->gc_threshold = mrb->live + GC_STEP_SIZE;
}
static void
@@ -876,15 +936,15 @@ clear_all_old(mrb_state *mrb)
{
size_t origin_mode = mrb->is_generational_gc_mode;
gc_assert(is_generational(mrb));
mrb_assert(is_generational(mrb));
if (is_major_gc(mrb)) {
advance_phase(mrb, GC_STATE_NONE);
incremental_gc_until(mrb, GC_STATE_NONE);
}
mrb->is_generational_gc_mode = FALSE;
prepare_incremental_sweep(mrb);
advance_phase(mrb, GC_STATE_NONE);
mrb->variable_gray_list = mrb->gray_list = NULL;
incremental_gc_until(mrb, GC_STATE_NONE);
mrb->atomic_gray_list = mrb->gray_list = NULL;
mrb->is_generational_gc_mode = origin_mode;
}
@@ -897,26 +957,19 @@ mrb_incremental_gc(mrb_state *mrb)
GC_TIME_START;
if (is_minor_gc(mrb)) {
do {
incremental_gc(mrb, ~0);
} while (mrb->gc_state != GC_STATE_NONE);
incremental_gc_until(mrb, GC_STATE_NONE);
}
else {
size_t limit = 0, result = 0;
limit = (GC_STEP_SIZE/100) * mrb->gc_step_ratio;
while (result < limit) {
result += incremental_gc(mrb, limit);
if (mrb->gc_state == GC_STATE_NONE)
break;
}
incremental_gc_step(mrb);
}
if (mrb->gc_state == GC_STATE_NONE) {
gc_assert(mrb->live >= mrb->gc_live_after_mark);
mrb_assert(mrb->live >= mrb->gc_live_after_mark);
mrb->gc_threshold = (mrb->gc_live_after_mark/100) * mrb->gc_interval_ratio;
if (mrb->gc_threshold < GC_STEP_SIZE) {
mrb->gc_threshold = GC_STEP_SIZE;
}
if (is_major_gc(mrb)) {
mrb->majorgc_old_threshold = mrb->gc_live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO;
mrb->gc_full = FALSE;
@@ -928,28 +981,21 @@ mrb_incremental_gc(mrb_state *mrb)
}
}
}
else {
mrb->gc_threshold = mrb->live + GC_STEP_SIZE;
}
GC_TIME_STOP_AND_REPORT;
}
/* Perform a full gc cycle */
void
mrb_garbage_collect(mrb_state *mrb)
mrb_full_gc(mrb_state *mrb)
{
size_t max_limit = ~0;
if (mrb->gc_disabled) return;
GC_INVOKE_TIME_REPORT("mrb_garbage_collect()");
GC_INVOKE_TIME_REPORT("mrb_full_gc()");
GC_TIME_START;
if (mrb->gc_state == GC_STATE_SWEEP) {
/* finish sweep phase */
while (mrb->gc_state != GC_STATE_NONE) {
incremental_gc(mrb, max_limit);
}
incremental_gc_until(mrb, GC_STATE_NONE);
}
/* clean all black object as old */
@@ -958,10 +1004,7 @@ mrb_garbage_collect(mrb_state *mrb)
mrb->gc_full = TRUE;
}
do {
incremental_gc(mrb, max_limit);
} while (mrb->gc_state != GC_STATE_NONE);
incremental_gc_until(mrb, GC_STATE_NONE);
mrb->gc_threshold = (mrb->gc_live_after_mark/100) * mrb->gc_interval_ratio;
if (is_generational(mrb)) {
@@ -972,6 +1015,12 @@ mrb_garbage_collect(mrb_state *mrb)
GC_TIME_STOP_AND_REPORT;
}
void
mrb_garbage_collect(mrb_state *mrb)
{
mrb_full_gc(mrb);
}
int
mrb_gc_arena_save(mrb_state *mrb)
{
@@ -995,14 +1044,14 @@ mrb_field_write_barrier(mrb_state *mrb, struct RBasic *obj, struct RBasic *value
if (!is_black(obj)) return;
if (!is_white(value)) return;
gc_assert(!is_dead(mrb, value) && !is_dead(mrb, obj));
gc_assert(is_generational(mrb) || mrb->gc_state != GC_STATE_NONE);
mrb_assert(!is_dead(mrb, value) && !is_dead(mrb, obj));
mrb_assert(is_generational(mrb) || mrb->gc_state != GC_STATE_NONE);
if (is_generational(mrb) || mrb->gc_state == GC_STATE_MARK) {
add_gray_list(mrb, value);
}
else {
gc_assert(mrb->gc_state == GC_STATE_SWEEP);
mrb_assert(mrb->gc_state == GC_STATE_SWEEP);
paint_partial_white(mrb, obj); /* for never write barriers */
}
}
@@ -1021,11 +1070,11 @@ mrb_write_barrier(mrb_state *mrb, struct RBasic *obj)
{
if (!is_black(obj)) return;
gc_assert(!is_dead(mrb, obj));
gc_assert(is_generational(mrb) || mrb->gc_state != GC_STATE_NONE);
mrb_assert(!is_dead(mrb, obj));
mrb_assert(is_generational(mrb) || mrb->gc_state != GC_STATE_NONE);
paint_gray(obj);
obj->gcnext = mrb->variable_gray_list;
mrb->variable_gray_list = obj;
obj->gcnext = mrb->atomic_gray_list;
mrb->atomic_gray_list = obj;
}
/*
@@ -1039,7 +1088,7 @@ mrb_write_barrier(mrb_state *mrb, struct RBasic *obj)
static mrb_value
gc_start(mrb_state *mrb, mrb_value obj)
{
mrb_garbage_collect(mrb);
mrb_full_gc(mrb);
return mrb_nil_value();
}
@@ -1159,11 +1208,11 @@ change_gen_gc_mode(mrb_state *mrb, mrb_int enable)
{
if (is_generational(mrb) && !enable) {
clear_all_old(mrb);
gc_assert(mrb->gc_state == GC_STATE_NONE);
mrb_assert(mrb->gc_state == GC_STATE_NONE);
mrb->gc_full = FALSE;
}
else if (!is_generational(mrb) && enable) {
advance_phase(mrb, GC_STATE_NONE);
incremental_gc_until(mrb, GC_STATE_NONE);
mrb->majorgc_old_threshold = mrb->gc_live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO;
mrb->gc_full = FALSE;
}
@@ -1271,7 +1320,7 @@ test_mrb_field_write_barrier(void)
mrb->gc_state = GC_STATE_MARK;
mrb_field_write_barrier(mrb, obj, value);
gc_assert(is_gray(value));
mrb_assert(is_gray(value));
puts(" in GC_STATE_SWEEP");
@@ -1279,8 +1328,8 @@ test_mrb_field_write_barrier(void)
mrb->gc_state = GC_STATE_SWEEP;
mrb_field_write_barrier(mrb, obj, value);
gc_assert(obj->color & mrb->current_white_part);
gc_assert(value->color & mrb->current_white_part);
mrb_assert(obj->color & mrb->current_white_part);
mrb_assert(value->color & mrb->current_white_part);
puts(" fail with black");
@@ -1289,7 +1338,7 @@ test_mrb_field_write_barrier(void)
paint_partial_white(mrb,value);
mrb_field_write_barrier(mrb, obj, value);
gc_assert(obj->color & mrb->current_white_part);
mrb_assert(obj->color & mrb->current_white_part);
puts(" fail with gray");
@@ -1298,7 +1347,7 @@ test_mrb_field_write_barrier(void)
paint_gray(value);
mrb_field_write_barrier(mrb, obj, value);
gc_assert(is_gray(value));
mrb_assert(is_gray(value));
{
@@ -1311,7 +1360,7 @@ test_mrb_field_write_barrier(void)
mrb->gc_state = GC_STATE_MARK;
mrb_field_write_barrier_value(mrb, obj, value);
gc_assert(is_gray(mrb_basic_ptr(value)));
mrb_assert(is_gray(mrb_basic_ptr(value)));
}
mrb_close(mrb);
@@ -1331,15 +1380,15 @@ test_mrb_write_barrier(void)
mrb->gc_state = GC_STATE_MARK;
mrb_write_barrier(mrb, obj);
gc_assert(is_gray(obj));
gc_assert(mrb->variable_gray_list == obj);
mrb_assert(is_gray(obj));
mrb_assert(mrb->atomic_gray_list == obj);
puts(" fail with gray");
paint_gray(obj);
mrb_write_barrier(mrb, obj);
gc_assert(is_gray(obj));
mrb_assert(is_gray(obj));
mrb_close(mrb);
}
@@ -1352,17 +1401,17 @@ test_add_gray_list(void)
puts("test_add_gray_list");
change_gen_gc_mode(mrb, FALSE);
gc_assert(mrb->gray_list == NULL);
mrb_assert(mrb->gray_list == NULL);
obj1 = mrb_basic_ptr(mrb_str_new_cstr(mrb, "test"));
add_gray_list(mrb, obj1);
gc_assert(mrb->gray_list == obj1);
gc_assert(is_gray(obj1));
mrb_assert(mrb->gray_list == obj1);
mrb_assert(is_gray(obj1));
obj2 = mrb_basic_ptr(mrb_str_new_cstr(mrb, "test"));
add_gray_list(mrb, obj2);
gc_assert(mrb->gray_list == obj2);
gc_assert(mrb->gray_list->gcnext == obj1);
gc_assert(is_gray(obj2));
mrb_assert(mrb->gray_list == obj2);
mrb_assert(mrb->gray_list->gcnext == obj1);
mrb_assert(is_gray(obj2));
mrb_close(mrb);
}
@@ -1381,8 +1430,8 @@ test_gc_gray_mark(void)
obj = (struct RBasic*)mrb->object_class;
paint_gray(obj);
gray_num = gc_gray_mark(mrb, obj);
gc_assert(is_black(obj));
gc_assert(gray_num > 1);
mrb_assert(is_black(obj));
mrb_assert(gray_num > 1);
puts(" in MRB_TT_ARRAY");
obj_v = mrb_ary_new(mrb);
@@ -1391,9 +1440,9 @@ test_gc_gray_mark(void)
paint_partial_white(mrb, mrb_basic_ptr(value_v));
mrb_ary_push(mrb, obj_v, value_v);
gray_num = gc_gray_mark(mrb, mrb_basic_ptr(obj_v));
gc_assert(is_black(mrb_basic_ptr(obj_v)));
gc_assert(is_gray(mrb_basic_ptr(value_v)));
gc_assert(gray_num == 1);
mrb_assert(is_black(mrb_basic_ptr(obj_v)));
mrb_assert(is_gray(mrb_basic_ptr(value_v)));
mrb_assert(gray_num == 1);
mrb_close(mrb);
}
@@ -1409,16 +1458,16 @@ test_incremental_gc(void)
puts("test_incremental_gc");
change_gen_gc_mode(mrb, FALSE);
puts(" in mrb_garbage_collect");
mrb_garbage_collect(mrb);
puts(" in mrb_full_gc");
mrb_full_gc(mrb);
gc_assert(mrb->gc_state == GC_STATE_NONE);
mrb_assert(mrb->gc_state == GC_STATE_NONE);
puts(" in GC_STATE_NONE");
incremental_gc(mrb, max);
gc_assert(mrb->gc_state == GC_STATE_MARK);
mrb_assert(mrb->gc_state == GC_STATE_MARK);
puts(" in GC_STATE_MARK");
advance_phase(mrb, GC_STATE_SWEEP);
gc_assert(mrb->gc_state == GC_STATE_SWEEP);
incremental_gc_until(mrb, GC_STATE_SWEEP);
mrb_assert(mrb->gc_state == GC_STATE_SWEEP);
puts(" in GC_STATE_SWEEP");
page = mrb->heaps;
@@ -1438,13 +1487,13 @@ test_incremental_gc(void)
total += MRB_HEAP_PAGE_SIZE;
}
gc_assert(mrb->gray_list == NULL);
mrb_assert(mrb->gray_list == NULL);
incremental_gc(mrb, max);
gc_assert(mrb->gc_state == GC_STATE_SWEEP);
mrb_assert(mrb->gc_state == GC_STATE_SWEEP);
incremental_gc(mrb, max);
gc_assert(mrb->gc_state == GC_STATE_NONE);
mrb_assert(mrb->gc_state == GC_STATE_NONE);
free = (RVALUE*)mrb->heaps->freelist;
while (free) {
@@ -1452,30 +1501,30 @@ test_incremental_gc(void)
free = (RVALUE*)free->as.free.next;
}
gc_assert(mrb->live == live);
gc_assert(mrb->live == total-freed);
mrb_assert(mrb->live == live);
mrb_assert(mrb->live == total-freed);
puts("test_incremental_gc(gen)");
advance_phase(mrb, GC_STATE_SWEEP);
incremental_gc_until(mrb, GC_STATE_SWEEP);
change_gen_gc_mode(mrb, TRUE);
gc_assert(mrb->gc_full == FALSE);
gc_assert(mrb->gc_state == GC_STATE_NONE);
mrb_assert(mrb->gc_full == FALSE);
mrb_assert(mrb->gc_state == GC_STATE_NONE);
puts(" in minor");
gc_assert(is_minor_gc(mrb));
gc_assert(mrb->majorgc_old_threshold > 0);
mrb_assert(is_minor_gc(mrb));
mrb_assert(mrb->majorgc_old_threshold > 0);
mrb->majorgc_old_threshold = 0;
mrb_incremental_gc(mrb);
gc_assert(mrb->gc_full == TRUE);
gc_assert(mrb->gc_state == GC_STATE_NONE);
mrb_assert(mrb->gc_full == TRUE);
mrb_assert(mrb->gc_state == GC_STATE_NONE);
puts(" in major");
gc_assert(is_major_gc(mrb));
mrb_assert(is_major_gc(mrb));
do {
mrb_incremental_gc(mrb);
} while (mrb->gc_state != GC_STATE_NONE);
gc_assert(mrb->gc_full == FALSE);
mrb_assert(mrb->gc_full == FALSE);
mrb_close(mrb);
}
@@ -1490,12 +1539,12 @@ test_incremental_sweep_phase(void)
add_heap(mrb);
mrb->sweeps = mrb->heaps;
gc_assert(mrb->heaps->next->next == NULL);
gc_assert(mrb->free_heaps->next->next == NULL);
mrb_assert(mrb->heaps->next->next == NULL);
mrb_assert(mrb->free_heaps->next->next == NULL);
incremental_sweep_phase(mrb, MRB_HEAP_PAGE_SIZE*3);
gc_assert(mrb->heaps->next == NULL);
gc_assert(mrb->heaps == mrb->free_heaps);
mrb_assert(mrb->heaps->next == NULL);
mrb_assert(mrb->heaps == mrb->free_heaps);
mrb_close(mrb);
}
+8 -16
View File
@@ -145,7 +145,9 @@ mrb_hash_set(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value val) /* mr
k = kh_get(ht, h, key);
if (k == kh_end(h)) {
/* expand */
int ai = mrb_gc_arena_save(mrb);
k = kh_put(ht, h, KEY(key));
mrb_gc_arena_restore(mrb, ai);
}
kh_value(h, k) = val;
@@ -169,7 +171,9 @@ mrb_hash_dup(mrb_state *mrb, mrb_value hash)
for (k = kh_begin(h); k != kh_end(h); k++) {
if (kh_exist(h,k)) {
int ai = mrb_gc_arena_save(mrb);
ret_k = kh_put(ht, ret_h, KEY(kh_key(h,k)));
mrb_gc_arena_restore(mrb, ai);
kh_val(ret_h, ret_k) = kh_val(h,k);
}
}
@@ -772,16 +776,9 @@ mrb_value
mrb_hash_empty_p(mrb_state *mrb, mrb_value self)
{
khash_t(ht) *h = RHASH_TBL(self);
mrb_bool empty_p;
if (h) {
empty_p = (kh_size(h) == 0);
}
else {
empty_p = 1;
}
return mrb_bool_value(empty_p);
if (h) return mrb_bool_value(kh_size(h) == 0);
return mrb_true_value();
}
static mrb_value
@@ -921,17 +918,12 @@ mrb_hash_has_keyWithKey(mrb_state *mrb, mrb_value hash, mrb_value key)
{
khash_t(ht) *h = RHASH_TBL(hash);
khiter_t k;
mrb_bool result;
if (h) {
k = kh_get(ht, h, key);
result = (k != kh_end(h));
return mrb_bool_value(k != kh_end(h));
}
else {
result = 0;
}
return mrb_bool_value(result);
return mrb_false_value();
}
/* 15.2.13.4.13 */
+47 -19
View File
@@ -26,7 +26,7 @@ typedef enum {
NOEX_RESPONDS = 0x80
} mrb_method_flag_t;
int
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_intern2(mrb, "to_s", 4));
@@ -521,7 +521,7 @@ mrb_obj_instance_eval(mrb_state *mrb, mrb_value self)
return mrb_yield_internal(mrb, b, 0, 0, self, c);
}
int
mrb_bool
mrb_obj_is_instance_of(mrb_state *mrb, mrb_value obj, struct RClass* c)
{
if (mrb_obj_class(mrb, obj) == c) return TRUE;
@@ -549,15 +549,40 @@ obj_is_instance_of(mrb_state *mrb, mrb_value self)
}
static void
check_iv_name(mrb_state *mrb, mrb_sym id)
valid_iv_name(mrb_state *mrb, mrb_sym iv_name_id, const char* s, size_t 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));
}
}
static void
check_iv_name(mrb_state *mrb, mrb_sym iv_name_id)
{
const char *s;
size_t len;
s = mrb_sym2name_len(mrb, id, &len);
if (len < 2 || !(s[0] == '@' && s[1] != '@')) {
mrb_name_error(mrb, id, "`%S' is not allowed as an instance variable name", mrb_sym2str(mrb, id));
s = mrb_sym2name_len(mrb, iv_name_id, &len);
valid_iv_name(mrb, iv_name_id, s, len);
}
static mrb_sym
get_valid_iv_sym(mrb_state *mrb, mrb_value iv_name)
{
mrb_sym iv_name_id;
mrb_assert(mrb_symbol_p(iv_name) || mrb_string_p(iv_name));
if (mrb_string_p(iv_name)) {
iv_name_id = mrb_intern_cstr(mrb, RSTRING_PTR(iv_name));
valid_iv_name(mrb, iv_name_id, RSTRING_PTR(iv_name), RSTRING_LEN(iv_name));
}
else {
iv_name_id = mrb_symbol(iv_name);
check_iv_name(mrb, iv_name_id);
}
return iv_name_id;
}
/* 15.3.1.3.20 */
@@ -582,10 +607,11 @@ mrb_value
mrb_obj_ivar_defined(mrb_state *mrb, mrb_value self)
{
mrb_sym mid;
mrb_value sym;
mrb_bool defined_p;
mrb_get_args(mrb, "n", &mid);
check_iv_name(mrb, mid);
mrb_get_args(mrb, "o", &sym);
mid = get_valid_iv_sym(mrb, sym);
defined_p = mrb_obj_iv_defined(mrb, mrb_obj_ptr(self), mid);
return mrb_bool_value(defined_p);
@@ -614,12 +640,13 @@ mrb_obj_ivar_defined(mrb_state *mrb, mrb_value self)
mrb_value
mrb_obj_ivar_get(mrb_state *mrb, mrb_value self)
{
mrb_sym id;
mrb_sym iv_name_id;
mrb_value iv_name;
mrb_get_args(mrb, "n", &id);
mrb_get_args(mrb, "o", &iv_name);
check_iv_name(mrb, id);
return mrb_iv_get(mrb, self, id);
iv_name_id = get_valid_iv_sym(mrb, iv_name);
return mrb_iv_get(mrb, self, iv_name_id);
}
/* 15.3.1.3.22 */
@@ -645,12 +672,13 @@ mrb_obj_ivar_get(mrb_state *mrb, mrb_value self)
mrb_value
mrb_obj_ivar_set(mrb_state *mrb, mrb_value self)
{
mrb_sym id;
mrb_value val;
mrb_sym iv_name_id;
mrb_value iv_name, val;
mrb_get_args(mrb, "no", &id, &val);
check_iv_name(mrb, id);
mrb_iv_set(mrb, self, id, val);
mrb_get_args(mrb, "oo", &iv_name, &val);
iv_name_id = get_valid_iv_sym(mrb, iv_name);
mrb_iv_set(mrb, self, iv_name_id, val);
return val;
}
@@ -938,7 +966,7 @@ mrb_obj_remove_instance_variable(mrb_state *mrb, mrb_value self)
return val;
}
static inline int
static inline mrb_bool
basic_obj_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym id, int pub)
{
return mrb_respond_to(mrb, obj, id);
@@ -1101,5 +1129,5 @@ mrb_init_kernel(mrb_state *mrb)
mrb_define_method(mrb, krn, "to_s", mrb_any_to_s, MRB_ARGS_NONE()); /* 15.3.1.3.46 */
mrb_include_module(mrb, mrb->object_class, mrb->kernel_module);
mrb_alias_method(mrb, mrb->module_class, mrb_intern(mrb, "dup"), mrb_intern(mrb, "clone"));
mrb_alias_method(mrb, mrb->module_class, mrb_intern2(mrb, "dup", 3), mrb_intern2(mrb, "clone", 5));
}
+13 -10
View File
@@ -187,7 +187,6 @@ read_rite_section_irep(mrb_state *mrb, const uint8_t *bin)
{
int result;
size_t sirep;
size_t i;
uint32_t len;
uint16_t nirep;
uint16_t n;
@@ -200,14 +199,14 @@ read_rite_section_irep(mrb_state *mrb, const uint8_t *bin)
nirep = bin_to_uint16(header->nirep);
//Read Binary Data Section
for (n = 0, i = sirep; n < nirep; n++, i++) {
for (n = 0; n < nirep; n++) {
result = read_rite_irep_record(mrb, bin, &len);
if (result != MRB_DUMP_OK)
goto error_exit;
bin += len;
}
result = sirep + bin_to_uint16(header->sirep);
result = nirep;
error_exit:
if (result < MRB_DUMP_OK) {
irep_free(sirep, mrb);
@@ -368,7 +367,7 @@ mrb_read_irep(mrb_state *mrb, const uint8_t *bin)
bin += bin_to_uint32(section_header->section_size);
} while (memcmp(section_header->section_identify, RITE_BINARY_EOF, sizeof(section_header->section_identify)) != 0);
return total_nirep;
return sirep;
}
static void
@@ -464,7 +463,6 @@ read_rite_section_irep_file(mrb_state *mrb, FILE *fp)
{
int32_t result;
size_t sirep;
size_t i;
uint16_t nirep;
uint16_t n;
uint32_t len, buf_size;
@@ -488,7 +486,7 @@ read_rite_section_irep_file(mrb_state *mrb, FILE *fp)
}
//Read Binary Data Section
for (n = 0, i = sirep; n < nirep; n++, i++) {
for (n = 0; n < nirep; n++) {
void *ptr;
if (fread(buf, record_header_size, 1, fp) == 0) {
@@ -516,7 +514,7 @@ read_rite_section_irep_file(mrb_state *mrb, FILE *fp)
goto error_exit;
}
result = sirep + bin_to_uint16(header.sirep);
result = nirep;
error_exit:
if (buf) {
mrb_free(mrb, buf);
@@ -539,7 +537,9 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp)
size_t sirep;
struct rite_section_header section_header;
long fpos;
const size_t block_size = 1 << 14;
size_t block_size = 1 << 14;
const uint8_t block_fallback_count = 4;
int i;
const size_t buf_size = sizeof(struct rite_binary_header);
if ((mrb == NULL) || (fp == NULL)) {
@@ -564,7 +564,10 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp)
/* verify CRC */
fpos = ftell(fp);
/* You don't need use SIZE_ERROR as block_size is enough small. */
buf = mrb_malloc(mrb, block_size);
for (i = 0; i < block_fallback_count; i++,block_size >>= 1){
buf = mrb_malloc_simple(mrb, block_size);
if (buf) break;
}
if (!buf) {
return MRB_DUMP_GENERAL_FAILURE;
}
@@ -609,7 +612,7 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp)
fseek(fp, fpos + section_size, SEEK_SET);
} while (memcmp(section_header.section_identify, RITE_BINARY_EOF, sizeof(section_header.section_identify)) != 0);
return total_nirep;
return sirep;
}
mrb_value
+9 -7
View File
@@ -4,7 +4,6 @@
** See Copyright Notice in mruby.h
*/
#include <assert.h>
#include <float.h>
#if defined(__FreeBSD__) && __FreeBSD__ < 4
# include <floatingpoint.h>
@@ -240,7 +239,8 @@ mrb_flo_to_str(mrb_state *mrb, mrb_value flo, int max_digit)
*(c++) = 'e';
if (exp > 0) {
*(c++) = '+';
} else {
}
else {
*(c++) = '-';
exp = -exp;
}
@@ -781,7 +781,7 @@ fixdivmod(mrb_state *mrb, mrb_int x, mrb_int y, mrb_int *divp, mrb_int *modp)
{
mrb_int div, mod;
/* TODO: add assert(y != 0) to make sure */
/* TODO: add mrb_assert(y != 0) to make sure */
if (y < 0) {
if (x < 0)
@@ -998,7 +998,7 @@ fix_xor(mrb_state *mrb, mrb_value x)
#define NUMERIC_SHIFT_WIDTH_MAX (sizeof(mrb_int)*CHAR_BIT-1)
static mrb_value
lshift(mrb_state *mrb, mrb_int val, int width)
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)",
@@ -1010,7 +1010,7 @@ lshift(mrb_state *mrb, mrb_int val, int width)
}
static mrb_value
rshift(mrb_int val, int width)
rshift(mrb_int val, size_t width)
{
if (width >= NUMERIC_SHIFT_WIDTH_MAX) {
if (val < 0) {
@@ -1253,12 +1253,14 @@ mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, int base)
if (val == 0) {
*--b = '0';
} else if (val < 0) {
}
else if (val < 0) {
do {
*--b = mrb_digitmap[-(val % base)];
} while (val /= base);
*--b = '-';
} else {
}
else {
do {
*--b = mrb_digitmap[(int)(val % base)];
} while (val /= base);
+37 -42
View File
@@ -5,18 +5,19 @@
*/
#include "mruby.h"
#include "mruby/array.h"
#include "mruby/class.h"
#include "mruby/numeric.h"
#include "mruby/string.h"
#include "error.h"
int
mrb_bool
mrb_obj_eq(mrb_state *mrb, mrb_value v1, mrb_value v2)
{
if (mrb_type(v1) != mrb_type(v2)) return FALSE;
switch (mrb_type(v1)) {
case MRB_TT_TRUE:
return 1;
return TRUE;
case MRB_TT_FALSE:
case MRB_TT_FIXNUM:
@@ -32,14 +33,14 @@ mrb_obj_eq(mrb_state *mrb, mrb_value v1, mrb_value v2)
}
}
int
mrb_bool
mrb_obj_equal(mrb_state *mrb, mrb_value v1, mrb_value v2)
{
/* temporary definition */
return mrb_obj_eq(mrb, v1, v2);
}
int
mrb_bool
mrb_equal(mrb_state *mrb, mrb_value obj1, mrb_value obj2)
{
mrb_value result;
@@ -67,7 +68,7 @@ mrb_equal(mrb_state *mrb, mrb_value obj1, mrb_value obj2)
static mrb_value
mrb_true(mrb_state *mrb, mrb_value obj)
{
return mrb_true_value();
return mrb_true_value();
}
/* 15.2.4.3.5 */
@@ -171,9 +172,6 @@ true_to_s(mrb_state *mrb, mrb_value obj)
static mrb_value
true_or(mrb_state *mrb, mrb_value obj)
{
mrb_bool obj2;
mrb_get_args(mrb, "b", &obj2);
return mrb_true_value();
}
@@ -202,9 +200,6 @@ true_or(mrb_state *mrb, mrb_value obj)
static mrb_value
false_and(mrb_state *mrb, mrb_value obj)
{
mrb_bool obj2;
mrb_get_args(mrb, "b", &obj2);
return mrb_false_value();
}
@@ -302,7 +297,7 @@ convert_type(mrb_state *mrb, mrb_value val, const char *tname, const char *metho
{
mrb_sym m = 0;
m = mrb_intern(mrb, method);
m = mrb_intern_cstr(mrb, method);
if (!mrb_respond_to(mrb, val, m)) {
if (raise) {
mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S into %S", val, mrb_str_new_cstr(mrb, tname));
@@ -318,18 +313,18 @@ convert_type(mrb_state *mrb, mrb_value val, const char *tname, const char *metho
mrb_value
mrb_check_to_integer(mrb_state *mrb, mrb_value val, const char *method)
{
mrb_value v;
mrb_value v;
if (mrb_type(val) == MRB_TT_FIXNUM) return val;
v = convert_type(mrb, val, "Integer", method, FALSE);
if (mrb_nil_p(v) || mrb_type(v) != MRB_TT_FIXNUM) {
return mrb_nil_value();
}
return v;
if (mrb_type(val) == MRB_TT_FIXNUM) return val;
v = convert_type(mrb, val, "Integer", method, FALSE);
if (mrb_nil_p(v) || mrb_type(v) != MRB_TT_FIXNUM) {
return mrb_nil_value();
}
return v;
}
mrb_value
mrb_convert_type(mrb_state *mrb, mrb_value val, mrb_int type, const char *tname, const char *method)
mrb_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const char *tname, const char *method)
{
mrb_value v;
@@ -343,7 +338,7 @@ mrb_convert_type(mrb_state *mrb, mrb_value val, mrb_int type, const char *tname,
}
mrb_value
mrb_check_convert_type(mrb_state *mrb, mrb_value val, mrb_int type, const char *tname, const char *method)
mrb_check_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const char *tname, const char *method)
{
mrb_value v;
@@ -354,8 +349,8 @@ mrb_check_convert_type(mrb_state *mrb, mrb_value val, mrb_int type, const char *
}
static const struct types {
unsigned char type;
const char *name;
unsigned char type;
const char *name;
} builtin_types[] = {
// {MRB_TT_NIL, "nil"},
{MRB_TT_FALSE, "false"},
@@ -473,7 +468,7 @@ mrb_any_to_s(mrb_state *mrb, mrb_value obj)
* b.kind_of? M #=> true
*/
int
mrb_bool
mrb_obj_is_kind_of(mrb_state *mrb, mrb_value obj, struct RClass *c)
{
struct RClass *cl = mrb_class(mrb, obj);
@@ -499,21 +494,21 @@ mrb_obj_is_kind_of(mrb_state *mrb, mrb_value obj, struct RClass *c)
static mrb_value
mrb_to_integer(mrb_state *mrb, mrb_value val, const char *method)
{
mrb_value v;
mrb_value v;
if (mrb_fixnum_p(val)) return val;
v = convert_type(mrb, val, "Integer", method, TRUE);
if (!mrb_obj_is_kind_of(mrb, v, mrb->fixnum_class)) {
mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S to Integer (%S#%S gives %S)",
val, val, mrb_str_new_cstr(mrb, method), v);
}
return v;
if (mrb_fixnum_p(val)) return val;
v = convert_type(mrb, val, "Integer", method, TRUE);
if (!mrb_obj_is_kind_of(mrb, v, mrb->fixnum_class)) {
mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S to Integer (%S#%S gives %S)",
val, val, mrb_str_new_cstr(mrb, method), v);
}
return v;
}
mrb_value
mrb_to_int(mrb_state *mrb, mrb_value val)
{
return mrb_to_integer(mrb, val, "to_int");
return mrb_to_integer(mrb, val, "to_int");
}
static mrb_value
@@ -529,7 +524,7 @@ mrb_convert_to_integer(mrb_state *mrb, mrb_value val, int base)
case MRB_TT_FLOAT:
if (base != 0) goto arg_error;
if (FIXABLE(mrb_float(val))) {
break;
break;
}
return mrb_flo_to_fixnum(mrb, val);
@@ -545,14 +540,14 @@ string_conv:
break;
}
if (base != 0) {
tmp = mrb_check_string_type(mrb, val);
if (!mrb_nil_p(tmp)) goto string_conv;
arg_error:
mrb_raise(mrb, E_ARGUMENT_ERROR, "base specified for non string value");
tmp = mrb_check_string_type(mrb, val);
if (!mrb_nil_p(tmp)) goto string_conv;
arg_error:
mrb_raise(mrb, E_ARGUMENT_ERROR, "base specified for non string value");
}
tmp = convert_type(mrb, val, "Integer", "to_int", FALSE);
if (mrb_nil_p(tmp)) {
return mrb_to_integer(mrb, val, "to_i");
return mrb_to_integer(mrb, val, "to_i");
}
return tmp;
}
@@ -560,14 +555,14 @@ string_conv:
mrb_value
mrb_Integer(mrb_state *mrb, mrb_value val)
{
return mrb_convert_to_integer(mrb, val, 0);
return mrb_convert_to_integer(mrb, val, 0);
}
mrb_value
mrb_Float(mrb_state *mrb, mrb_value val)
{
if (mrb_nil_p(val)) {
mrb_raise(mrb, E_TYPE_ERROR, "can't convert nil into Float");
mrb_raise(mrb, E_TYPE_ERROR, "can't convert nil into Float");
}
switch (mrb_type(val)) {
case MRB_TT_FIXNUM:
@@ -590,7 +585,7 @@ mrb_inspect(mrb_state *mrb, mrb_value obj)
return mrb_obj_as_string(mrb, mrb_funcall(mrb, obj, "inspect", 0, 0));
}
int
mrb_bool
mrb_eql(mrb_state *mrb, mrb_value obj1, mrb_value obj2)
{
if (mrb_obj_eq(mrb, obj1, obj2)) return TRUE;
+101 -98
View File
@@ -17,27 +17,27 @@
/* Ax:OP = 25: 7 */
/* A:Bz:Cz:OP = 9:14: 2: 7 */
#define GET_OPCODE(i) ((int)(((mrb_code)(i)) & 0x7f))
#define GETARG_A(i) ((int)((((mrb_code)(i)) >> 23) & 0x1ff))
#define GETARG_B(i) ((int)((((mrb_code)(i)) >> 14) & 0x1ff))
#define GETARG_C(i) ((int)((((mrb_code)(i)) >> 7) & 0x7f))
#define GETARG_Bx(i) ((int)((((mrb_code)(i)) >> 7) & 0xffff))
#define GETARG_sBx(i) ((int)(GETARG_Bx(i)-MAXARG_sBx))
#define GETARG_Ax(i) ((int32_t)((((mrb_code)(i)) >> 7) & 0x1ffffff))
#define GET_OPCODE(i) ((int)(((mrb_code)(i)) & 0x7f))
#define GETARG_A(i) ((int)((((mrb_code)(i)) >> 23) & 0x1ff))
#define GETARG_B(i) ((int)((((mrb_code)(i)) >> 14) & 0x1ff))
#define GETARG_C(i) ((int)((((mrb_code)(i)) >> 7) & 0x7f))
#define GETARG_Bx(i) ((int)((((mrb_code)(i)) >> 7) & 0xffff))
#define GETARG_sBx(i) ((int)(GETARG_Bx(i)-MAXARG_sBx))
#define GETARG_Ax(i) ((int32_t)((((mrb_code)(i)) >> 7) & 0x1ffffff))
#define GETARG_UNPACK_b(i,n1,n2) ((int)((((mrb_code)(i)) >> (7+(n2))) & (((1<<(n1))-1))))
#define GETARG_UNPACK_c(i,n1,n2) ((int)((((mrb_code)(i)) >> 7) & (((1<<(n2))-1))))
#define GETARG_b(i) GETARG_UNPACK_b(i,14,2)
#define GETARG_c(i) GETARG_UNPACK_c(i,14,2)
#define GETARG_b(i) GETARG_UNPACK_b(i,14,2)
#define GETARG_c(i) GETARG_UNPACK_c(i,14,2)
#define MKOPCODE(op) ((op) & 0x7f)
#define MKARG_A(c) ((mrb_code)((c) & 0x1ff) << 23)
#define MKARG_B(c) ((mrb_code)((c) & 0x1ff) << 14)
#define MKARG_C(c) (((c) & 0x7f) << 7)
#define MKARG_Bx(v) ((mrb_code)((v) & 0xffff) << 7)
#define MKARG_sBx(v) MKARG_Bx((v)+MAXARG_sBx)
#define MKARG_Ax(v) ((mrb_code)((v) & 0x1ffffff) << 7)
#define MKOPCODE(op) ((op) & 0x7f)
#define MKARG_A(c) ((mrb_code)((c) & 0x1ff) << 23)
#define MKARG_B(c) ((mrb_code)((c) & 0x1ff) << 14)
#define MKARG_C(c) (((c) & 0x7f) << 7)
#define MKARG_Bx(v) ((mrb_code)((v) & 0xffff) << 7)
#define MKARG_sBx(v) MKARG_Bx((v)+MAXARG_sBx)
#define MKARG_Ax(v) ((mrb_code)((v) & 0x1ffffff) << 7)
#define MKARG_PACK(b,n1,c,n2) ((((b) & ((1<<n1)-1)) << (7+n2))|(((c) & ((1<<n2)-1)) << 7))
#define MKARG_bc(b,c) MKARG_PACK(b,14,c,2)
#define MKARG_bc(b,c) MKARG_PACK(b,14,c,2)
#define MKOP_A(op,a) (MKOPCODE(op)|MKARG_A(a))
#define MKOP_AB(op,a,b) (MKOP_A(op,a)|MKARG_B(b))
@@ -50,98 +50,101 @@
#define MKOP_Abc(op,a,b,c) (MKOP_A(op,a)|MKARG_bc(b,c))
enum {
OP_NOP=0,/* */
OP_MOVE,/* A B R(A) := R(B) */
OP_LOADL,/* A Bx R(A) := Lit(Bx) */
OP_LOADI,/* A sBx R(A) := sBx */
OP_LOADSYM,/* A Bx R(A) := Sym(Bx) */
OP_LOADNIL,/* A R(A) := nil */
OP_LOADSELF,/* A R(A) := self */
OP_LOADT,/* A R(A) := true */
OP_LOADF,/* A R(A) := false */
/*-----------------------------------------------------------------------
operation code operand description
------------------------------------------------------------------------*/
OP_NOP=0,/* */
OP_MOVE,/* A B R(A) := R(B) */
OP_LOADL,/* A Bx R(A) := Lit(Bx) */
OP_LOADI,/* A sBx R(A) := sBx */
OP_LOADSYM,/* A Bx R(A) := Sym(Bx) */
OP_LOADNIL,/* A R(A) := nil */
OP_LOADSELF,/* A R(A) := self */
OP_LOADT,/* A R(A) := true */
OP_LOADF,/* A R(A) := false */
OP_GETGLOBAL,/* A Bx R(A) := getglobal(Sym(Bx)) */
OP_SETGLOBAL,/* A Bx setglobal(Sym(Bx), R(A)) */
OP_GETSPECIAL,/*A Bx R(A) := Special[Bx] */
OP_SETSPECIAL,/*A Bx Special[Bx] := R(A) */
OP_GETIV,/* A Bx R(A) := ivget(Sym(Bx)) */
OP_SETIV,/* A Bx ivset(Sym(Bx),R(A)) */
OP_GETCV,/* A Bx R(A) := cvget(Sym(Bx)) */
OP_SETCV,/* A Bx cvset(Sym(Bx),R(A)) */
OP_GETCONST,/* A Bx R(A) := constget(Sym(Bx)) */
OP_SETCONST,/* A Bx constset(Sym(Bx),R(A)) */
OP_GETMCNST,/* A Bx R(A) := R(A)::Sym(B) */
OP_SETMCNST,/* A Bx R(A+1)::Sym(B) := R(A) */
OP_GETUPVAR,/* A B C R(A) := uvget(B,C) */
OP_SETUPVAR,/* A B C uvset(B,C,R(A)) */
OP_GETGLOBAL,/* A Bx R(A) := getglobal(Sym(Bx)) */
OP_SETGLOBAL,/* A Bx setglobal(Sym(Bx), R(A)) */
OP_GETSPECIAL,/*A Bx R(A) := Special[Bx] */
OP_SETSPECIAL,/*A Bx Special[Bx] := R(A) */
OP_GETIV,/* A Bx R(A) := ivget(Sym(Bx)) */
OP_SETIV,/* A Bx ivset(Sym(Bx),R(A)) */
OP_GETCV,/* A Bx R(A) := cvget(Sym(Bx)) */
OP_SETCV,/* A Bx cvset(Sym(Bx),R(A)) */
OP_GETCONST,/* A Bx R(A) := constget(Sym(Bx)) */
OP_SETCONST,/* A Bx constset(Sym(Bx),R(A)) */
OP_GETMCNST,/* A Bx R(A) := R(A)::Sym(B) */
OP_SETMCNST,/* A Bx R(A+1)::Sym(B) := R(A) */
OP_GETUPVAR,/* A B C R(A) := uvget(B,C) */
OP_SETUPVAR,/* A B C uvset(B,C,R(A)) */
OP_JMP,/* sBx pc+=sBx */
OP_JMPIF,/* A sBx if R(A) pc+=sBx */
OP_JMPNOT,/* A sBx if !R(A) pc+=sBx */
OP_ONERR,/* sBx rescue_push(pc+sBx) */
OP_RESCUE,/* A clear(exc); R(A) := exception (ignore when A=0) */
OP_POPERR,/* A A.times{rescue_pop()} */
OP_RAISE,/* A raise(R(A)) */
OP_EPUSH,/* Bx ensure_push(SEQ[Bx]) */
OP_EPOP,/* A A.times{ensure_pop().call} */
OP_JMP,/* sBx pc+=sBx */
OP_JMPIF,/* A sBx if R(A) pc+=sBx */
OP_JMPNOT,/* A sBx if !R(A) pc+=sBx */
OP_ONERR,/* sBx rescue_push(pc+sBx) */
OP_RESCUE,/* A clear(exc); R(A) := exception (ignore when A=0) */
OP_POPERR,/* A A.times{rescue_pop()} */
OP_RAISE,/* A raise(R(A)) */
OP_EPUSH,/* Bx ensure_push(SEQ[Bx]) */
OP_EPOP,/* A A.times{ensure_pop().call} */
OP_SEND,/* A B C R(A) := call(R(A),mSym(B),R(A+1),...,R(A+C)) */
OP_SENDB,/* A B C R(A) := call(R(A),mSym(B),R(A+1),...,R(A+C),&R(A+C+1))*/
OP_FSEND,/* A B C R(A) := fcall(R(A),mSym(B),R(A+1),...,R(A+C-1)) */
OP_CALL,/* A B C R(A) := self.call(R(A),.., R(A+C)) */
OP_SUPER,/* A B C R(A) := super(R(A+1),... ,R(A+C-1)) */
OP_ARGARY,/* A Bx R(A) := argument array (16=6:1:5:4) */
OP_ENTER,/* Ax arg setup according to flags (24=5:5:1:5:5:1:1) */
OP_KARG,/* A B C R(A) := kdict[mSym(B)]; if C kdict.rm(mSym(B)) */
OP_KDICT,/* A C R(A) := kdict */
OP_SEND,/* A B C R(A) := call(R(A),mSym(B),R(A+1),...,R(A+C)) */
OP_SENDB,/* A B C R(A) := call(R(A),mSym(B),R(A+1),...,R(A+C),&R(A+C+1))*/
OP_FSEND,/* A B C R(A) := fcall(R(A),mSym(B),R(A+1),...,R(A+C-1)) */
OP_CALL,/* A B C R(A) := self.call(R(A),.., R(A+C)) */
OP_SUPER,/* A B C R(A) := super(R(A+1),... ,R(A+C-1)) */
OP_ARGARY,/* A Bx R(A) := argument array (16=6:1:5:4) */
OP_ENTER,/* Ax arg setup according to flags (24=5:5:1:5:5:1:1) */
OP_KARG,/* A B C R(A) := kdict[mSym(B)]; if C kdict.rm(mSym(B)) */
OP_KDICT,/* A C R(A) := kdict */
OP_RETURN,/* A B return R(A) (B=normal,in-block return/break) */
OP_TAILCALL,/* A B C return call(R(A),mSym(B),*R(C)) */
OP_BLKPUSH,/* A Bx R(A) := block (16=6:1:5:4) */
OP_RETURN,/* A B return R(A) (B=normal,in-block return/break) */
OP_TAILCALL,/* A B C return call(R(A),mSym(B),*R(C)) */
OP_BLKPUSH,/* A Bx R(A) := block (16=6:1:5:4) */
OP_ADD,/* A B C R(A) := R(A)+R(A+1) (mSyms[B]=:+,C=1) */
OP_ADDI,/* A B C R(A) := R(A)+C (mSyms[B]=:+) */
OP_SUB,/* A B C R(A) := R(A)-R(A+1) (mSyms[B]=:-,C=1) */
OP_SUBI,/* A B C R(A) := R(A)-C (mSyms[B]=:-) */
OP_MUL,/* A B C R(A) := R(A)*R(A+1) (mSyms[B]=:*,C=1) */
OP_DIV,/* A B C R(A) := R(A)/R(A+1) (mSyms[B]=:/,C=1) */
OP_EQ,/* A B C R(A) := R(A)==R(A+1) (mSyms[B]=:==,C=1) */
OP_LT,/* A B C R(A) := R(A)<R(A+1) (mSyms[B]=:<,C=1) */
OP_LE,/* A B C R(A) := R(A)<=R(A+1) (mSyms[B]=:<=,C=1) */
OP_GT,/* A B C R(A) := R(A)>R(A+1) (mSyms[B]=:>,C=1) */
OP_GE,/* A B C R(A) := R(A)>=R(A+1) (mSyms[B]=:>=,C=1) */
OP_ADD,/* A B C R(A) := R(A)+R(A+1) (mSyms[B]=:+,C=1) */
OP_ADDI,/* A B C R(A) := R(A)+C (mSyms[B]=:+) */
OP_SUB,/* A B C R(A) := R(A)-R(A+1) (mSyms[B]=:-,C=1) */
OP_SUBI,/* A B C R(A) := R(A)-C (mSyms[B]=:-) */
OP_MUL,/* A B C R(A) := R(A)*R(A+1) (mSyms[B]=:*,C=1) */
OP_DIV,/* A B C R(A) := R(A)/R(A+1) (mSyms[B]=:/,C=1) */
OP_EQ,/* A B C R(A) := R(A)==R(A+1) (mSyms[B]=:==,C=1) */
OP_LT,/* A B C R(A) := R(A)<R(A+1) (mSyms[B]=:<,C=1) */
OP_LE,/* A B C R(A) := R(A)<=R(A+1) (mSyms[B]=:<=,C=1) */
OP_GT,/* A B C R(A) := R(A)>R(A+1) (mSyms[B]=:>,C=1) */
OP_GE,/* A B C R(A) := R(A)>=R(A+1) (mSyms[B]=:>=,C=1) */
OP_ARRAY,/* A B C R(A) := ary_new(R(B),R(B+1)..R(B+C)) */
OP_ARYCAT,/* A B ary_cat(R(A),R(B)) */
OP_ARYPUSH,/* A B ary_push(R(A),R(B)) */
OP_AREF,/* A B C R(A) := R(B)[C] */
OP_ASET,/* A B C R(B)[C] := R(A) */
OP_APOST,/* A B C *R(A),R(A+1)..R(A+C) := R(A) */
OP_ARRAY,/* A B C R(A) := ary_new(R(B),R(B+1)..R(B+C)) */
OP_ARYCAT,/* A B ary_cat(R(A),R(B)) */
OP_ARYPUSH,/* A B ary_push(R(A),R(B)) */
OP_AREF,/* A B C R(A) := R(B)[C] */
OP_ASET,/* A B C R(B)[C] := R(A) */
OP_APOST,/* A B C *R(A),R(A+1)..R(A+C) := R(A) */
OP_STRING,/* A Bx R(A) := str_dup(Lit(Bx)) */
OP_STRCAT,/* A B str_cat(R(A),R(B)) */
OP_STRING,/* A Bx R(A) := str_dup(Lit(Bx)) */
OP_STRCAT,/* A B str_cat(R(A),R(B)) */
OP_HASH,/* A B C R(A) := hash_new(R(B),R(B+1)..R(B+C)) */
OP_LAMBDA,/* A Bz Cz R(A) := lambda(SEQ[Bz],Cm) */
OP_RANGE,/* A B C R(A) := range_new(R(B),R(B+1),C) */
OP_HASH,/* A B C R(A) := hash_new(R(B),R(B+1)..R(B+C)) */
OP_LAMBDA,/* A Bz Cz R(A) := lambda(SEQ[Bz],Cm) */
OP_RANGE,/* A B C R(A) := range_new(R(B),R(B+1),C) */
OP_OCLASS,/* A R(A) := ::Object */
OP_CLASS,/* A B R(A) := newclass(R(A),mSym(B),R(A+1)) */
OP_MODULE,/* A B R(A) := newmodule(R(A),mSym(B)) */
OP_EXEC,/* A Bx R(A) := blockexec(R(A),SEQ[Bx]) */
OP_METHOD,/* A B R(A).newmethod(mSym(B),R(A+1)) */
OP_SCLASS,/* A B R(A) := R(B).singleton_class */
OP_TCLASS,/* A R(A) := target_class */
OP_OCLASS,/* A R(A) := ::Object */
OP_CLASS,/* A B R(A) := newclass(R(A),mSym(B),R(A+1)) */
OP_MODULE,/* A B R(A) := newmodule(R(A),mSym(B)) */
OP_EXEC,/* A Bx R(A) := blockexec(R(A),SEQ[Bx]) */
OP_METHOD,/* A B R(A).newmethod(mSym(B),R(A+1)) */
OP_SCLASS,/* A B R(A) := R(B).singleton_class */
OP_TCLASS,/* A R(A) := target_class */
OP_DEBUG,/* A print R(A) */
OP_STOP,/* stop VM */
OP_ERR,/* Bx raise RuntimeError with message Lit(Bx) */
OP_DEBUG,/* A print R(A) */
OP_STOP,/* stop VM */
OP_ERR,/* Bx raise RuntimeError with message Lit(Bx) */
OP_RSVD1,/* reserved instruction #1 */
OP_RSVD2,/* reserved instruction #2 */
OP_RSVD3,/* reserved instruction #3 */
OP_RSVD4,/* reserved instruction #4 */
OP_RSVD5,/* reserved instruction #5 */
OP_RSVD1,/* reserved instruction #1 */
OP_RSVD2,/* reserved instruction #2 */
OP_RSVD3,/* reserved instruction #3 */
OP_RSVD4,/* reserved instruction #4 */
OP_RSVD5,/* reserved instruction #5 */
};
#define OP_L_STRICT 1
+19 -17
View File
@@ -1,6 +1,6 @@
/*
** parse.y - mruby parser
**
**
** See Copyright Notice in mruby.h
*/
@@ -272,7 +272,7 @@ new_scope(parser_state *p, node *body)
static node*
new_begin(parser_state *p, node *body)
{
if (body)
if (body)
return list2((node*)NODE_BEGIN, body);
return cons((node*)NODE_BEGIN, 0);
}
@@ -909,7 +909,7 @@ parsing_heredoc_inf(parser_state *p)
node *nd = p->parsing_heredoc;
if (nd == NULL)
return NULL;
/* assert(nd->car->car == NODE_HEREDOC); */
/* mrb_assert(nd->car->car == NODE_HEREDOC); */
return (parser_heredoc_info*)nd->car->cdr;
}
@@ -2744,7 +2744,7 @@ var_ref : variable
{
$$ = var_reference(p, $1);
}
| keyword_nil
| keyword_nil
{
$$ = new_nil(p);
}
@@ -3293,7 +3293,7 @@ peek_n(parser_state *p, int c, int n)
list = push(list, (node*)(intptr_t)c0);
} while(n--);
if (p->pb) {
p->pb = push(p->pb, (node*)list);
p->pb = append(p->pb, (node*)list);
}
else {
p->pb = list;
@@ -3408,7 +3408,7 @@ scan_oct(const int *start, int len, int *retlen)
const int *s = start;
int retval = 0;
/* assert(len <= 3) */
/* mrb_assert(len <= 3) */
while (len-- && *s >= '0' && *s <= '7') {
retval <<= 3;
retval |= *s++ - '0';
@@ -3426,7 +3426,7 @@ scan_hex(const int *start, int len, int *retlen)
register int retval = 0;
char *tmp;
/* assert(len <= 2) */
/* mrb_assert(len <= 2) */
while (len-- && *s && (tmp = (char*)strchr(hexdigit, *s))) {
retval <<= 4;
retval |= (tmp - hexdigit) & 15;
@@ -3620,12 +3620,14 @@ parse_string(parser_state *p)
tokadd(p, '\n');
}
else {
pushback(p, c);
if(type & STR_FUNC_REGEXP)
if (type & STR_FUNC_REGEXP) {
tokadd(p, '\\');
tokadd(p, read_escape(p));
if (c != -1)
tokadd(p, c);
} else {
pushback(p, c);
tokadd(p, read_escape(p));
}
if (hinf)
hinf->line_head = FALSE;
}
@@ -3684,7 +3686,7 @@ parse_string(parser_state *p)
tokadd(p, c);
}
}
tokfix(p);
p->lstate = EXPR_END;
@@ -3729,7 +3731,7 @@ parse_string(parser_state *p)
yylval.nd = new_str(p, tok(p), toklen(p));
return tSTRING;
}
static int
heredoc_identifier(parser_state *p)
@@ -4811,7 +4813,7 @@ parser_yylex(parser_state *p)
pushback(p, c);
if (last_state == EXPR_FNAME) goto gvar;
tokfix(p);
yylval.nd = new_nth_ref(p, atoi(tok(p)));
yylval.nd = new_nth_ref(p, atoi(tok(p)));
return tNTH_REF;
default:
@@ -5174,7 +5176,7 @@ parser_state*
mrb_parse_file(mrb_state *mrb, FILE *f, mrbc_context *c)
{
parser_state *p;
p = mrb_parser_new(mrb);
if (!p) return 0;
p->s = p->send = NULL;
@@ -5559,7 +5561,7 @@ parser_dump(mrb_state *mrb, node *tree, int offset)
printf("NODE_CALL:\n");
parser_dump(mrb, tree->car, offset+1);
dump_prefix(offset+1);
printf("method='%s' (%d)\n",
printf("method='%s' (%d)\n",
mrb_sym2name(mrb, sym(tree->cdr->car)),
(int)(intptr_t)tree->cdr->car);
tree = tree->cdr->cdr->car;
+7 -7
View File
@@ -53,7 +53,7 @@ mrb_pool_open(mrb_state *mrb)
if (pool) {
pool->mrb = mrb;
pool->pages = 0;
pool->pages = NULL;
}
return pool;
@@ -96,7 +96,7 @@ mrb_pool_alloc(mrb_pool *pool, size_t len)
struct mrb_pool_page *page;
size_t n;
if (!pool) return 0;
if (!pool) return NULL;
len += ALIGN_PADDING(len);
page = pool->pages;
while (page) {
@@ -109,7 +109,7 @@ mrb_pool_alloc(mrb_pool *pool, size_t len)
page = page->next;
}
page = page_alloc(pool, len);
if (!page) return 0;
if (!page) return NULL;
page->offset = len;
page->next = pool->pages;
pool->pages = page;
@@ -118,7 +118,7 @@ mrb_pool_alloc(mrb_pool *pool, size_t len)
return page->last;
}
int
mrb_bool
mrb_pool_can_realloc(mrb_pool *pool, void *p, size_t len)
{
struct mrb_pool_page *page;
@@ -145,7 +145,7 @@ mrb_pool_realloc(mrb_pool *pool, void *p, size_t oldlen, size_t newlen)
struct mrb_pool_page *page;
void *np;
if (!pool) return 0;
if (!pool) return NULL;
oldlen += ALIGN_PADDING(oldlen);
newlen += ALIGN_PADDING(newlen);
page = pool->pages;
@@ -177,10 +177,10 @@ main(void)
mrb_pool *pool;
void *p;
pool = mrb_pool_open(0);
pool = mrb_pool_open(NULL);
p = mrb_pool_alloc(pool, len);
for (i=1; i<20; i++) {
printf("%p (len=%d) %d\n", p, len, mrb_pool_can_realloc(pool, p, len*2));
printf("%p (len=%d) %ud\n", p, len, mrb_pool_can_realloc(pool, p, len*2));
p = mrb_pool_realloc(pool, p, len, len*2);
len *= 2;
}
+3 -3
View File
@@ -139,7 +139,7 @@ mrb_proc_arity(mrb_state *mrb, mrb_value self)
mrb_code *iseq = mrb_proc_iseq(mrb, p);
mrb_aspec aspec = GETARG_Ax(*iseq);
int ma, ra, pa, arity;
ma = MRB_ASPEC_REQ(aspec);
ra = MRB_ASPEC_REST(aspec);
pa = MRB_ASPEC_POST(aspec);
@@ -201,8 +201,8 @@ mrb_init_proc(mrb_state *mrb)
mrb_define_method(mrb, mrb->proc_class, "arity", mrb_proc_arity, MRB_ARGS_NONE());
m = mrb_proc_new(mrb, call_irep);
mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern(mrb, "call"), m);
mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern(mrb, "[]"), m);
mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern2(mrb, "call", 4), m);
mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern2(mrb, "[]", 2), m);
mrb_define_class_method(mrb, mrb->kernel_module, "lambda", proc_lambda, MRB_ARGS_NONE()); /* 15.3.1.2.6 */
mrb_define_method(mrb, mrb->kernel_module, "lambda", proc_lambda, MRB_ARGS_NONE()); /* 15.3.1.3.27 */
+30 -52
View File
@@ -152,33 +152,25 @@ mrb_range_eq(mrb_state *mrb, mrb_value range)
struct RRange *rr;
struct RRange *ro;
mrb_value obj;
mrb_bool eq_p;
mrb_get_args(mrb, "o", &obj);
if (mrb_obj_equal(mrb, range, obj)) {
eq_p = 1;
}
else if (!mrb_obj_is_instance_of(mrb, obj, mrb_obj_class(mrb, range))) { /* same class? */
eq_p = 0;
}
else {
rr = mrb_range_ptr(range);
ro = mrb_range_ptr(obj);
if (!mrb_obj_equal(mrb, rr->edges->beg, ro->edges->beg) ||
!mrb_obj_equal(mrb, rr->edges->end, ro->edges->end) ||
rr->excl != ro->excl) {
eq_p = 0;
}
else {
eq_p = 1;
}
if (mrb_obj_equal(mrb, range, obj)) return mrb_true_value();
if (!mrb_obj_is_instance_of(mrb, obj, mrb_obj_class(mrb, range))) { /* same class? */
return mrb_false_value();
}
return mrb_bool_value(eq_p);
rr = mrb_range_ptr(range);
ro = mrb_range_ptr(obj);
if (!mrb_bool(mrb_funcall(mrb, rr->edges->beg, "==", 1, ro->edges->beg)) ||
!mrb_bool(mrb_funcall(mrb, rr->edges->end, "==", 1, ro->edges->end)) ||
rr->excl != ro->excl) {
return mrb_false_value();
}
return mrb_true_value();
}
static int
static mrb_bool
r_le(mrb_state *mrb, mrb_value a, mrb_value b)
{
mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */
@@ -192,7 +184,7 @@ r_le(mrb_state *mrb, mrb_value a, mrb_value b)
return FALSE;
}
static int
static mrb_bool
r_gt(mrb_state *mrb, mrb_value a, mrb_value b)
{
mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b);
@@ -205,7 +197,7 @@ r_gt(mrb_state *mrb, mrb_value a, mrb_value b)
return FALSE;
}
static int
static mrb_bool
r_ge(mrb_state *mrb, mrb_value a, mrb_value b)
{
mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */
@@ -284,10 +276,10 @@ mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp,
if (beg < 0) {
beg += len;
if (beg < 0) goto out_of_range;
if (beg < 0) return FALSE;
}
if (beg > len) goto out_of_range;
if (beg > len) return FALSE;
if (end > len) end = len;
if (end < 0) end += len;
@@ -298,9 +290,6 @@ mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp,
*begp = beg;
*lenp = len;
return TRUE;
out_of_range:
return FALSE;
}
/* 15.2.14.4.12(x) */
@@ -385,34 +374,23 @@ range_eql(mrb_state *mrb, mrb_value range)
{
mrb_value obj;
struct RRange *r, *o;
mrb_bool eql_p;
mrb_get_args(mrb, "o", &obj);
if (mrb_obj_equal(mrb, range, obj)) {
eql_p = 1;
}
else if (!mrb_obj_is_kind_of(mrb, obj, RANGE_CLASS)) {
eql_p = 0;
}
else {
r = mrb_range_ptr(range);
if (mrb_type(obj) != MRB_TT_RANGE) {
eql_p = 0;
}
else {
o = mrb_range_ptr(obj);
if (!mrb_eql(mrb, r->edges->beg, o->edges->beg) ||
!mrb_eql(mrb, r->edges->end, o->edges->end) ||
(r->excl != o->excl)) {
eql_p = 0;
}
else {
eql_p = 1;
}
}
}
return mrb_bool_value(eql_p);
if (mrb_obj_equal(mrb, range, obj)) return mrb_true_value();
if (!mrb_obj_is_kind_of(mrb, obj, RANGE_CLASS)) {
return mrb_false_value();
}
if (mrb_type(obj) != MRB_TT_RANGE) return mrb_false_value();
r = mrb_range_ptr(range);
o = mrb_range_ptr(obj);
if (!mrb_eql(mrb, r->edges->beg, o->edges->beg) ||
!mrb_eql(mrb, r->edges->end, o->edges->end) ||
(r->excl != o->excl)) {
return mrb_false_value();
}
return mrb_true_value();
}
/* 15.2.14.4.15(x) */
+2 -1
View File
@@ -7,6 +7,7 @@
#ifndef RE_H
#define RE_H
#define REGEXP_CLASS "Regexp"
#define REGEXP_CLASS "Regexp"
#define REGEXP_CLASS_CSTR_LEN 6
#endif
+2 -6
View File
@@ -21,10 +21,6 @@ inspect_main(mrb_state *mrb, mrb_value mod)
return mrb_str_new(mrb, "main", 4);
}
#ifdef MRB_NAN_BOXING
#include <assert.h>
#endif
mrb_state*
mrb_open_allocf(mrb_allocf f, void *ud)
{
@@ -33,7 +29,7 @@ mrb_open_allocf(mrb_allocf f, void *ud)
mrb_state *mrb;
#ifdef MRB_NAN_BOXING
assert(sizeof(void*) == 4);
mrb_assert(sizeof(void*) == 4);
#endif
mrb = (mrb_state *)(f)(NULL, NULL, sizeof(mrb_state), ud);
@@ -192,7 +188,7 @@ mrb_value
mrb_top_self(mrb_state *mrb)
{
if (!mrb->top_self) {
mrb->top_self = (struct RObject*)mrb_obj_alloc(mrb, MRB_TT_OBJECT, mrb->object_class);
mrb->top_self = (struct RObject*)mrb_obj_alloc(mrb, MRB_TT_OBJECT, mrb->object_class);
mrb_define_singleton_method(mrb, mrb->top_self, "inspect", inspect_main, MRB_ARGS_NONE());
mrb_define_singleton_method(mrb, mrb->top_self, "to_s", inspect_main, MRB_ARGS_NONE());
}
+7 -24
View File
@@ -74,7 +74,7 @@ mrb_str_modify(mrb_state *mrb, struct RString *s)
if (p) {
memcpy(ptr, p, len);
}
ptr[len] = 0;
ptr[len] = '\0';
s->ptr = ptr;
s->aux.capa = len;
str_decref(mrb, shared);
@@ -104,10 +104,9 @@ mrb_str_resize(mrb_state *mrb, mrb_value str, mrb_int len)
mrb_str_modify(mrb, s);
slen = s->len;
if (len != slen) {
if (slen < len || slen -len > 1024) {
s->ptr = (char *)mrb_realloc(mrb, s->ptr, len+1);
if (slen < len || slen - len > 256) {
RESIZE_CAPA(s, len);
}
s->aux.capa = len;
s->len = len;
s->ptr[len] = '\0'; /* sentinel */
}
@@ -261,14 +260,7 @@ mrb_str_new_cstr(mrb_state *mrb, const char *p)
len = 0;
}
s = mrb_obj_alloc_string(mrb);
s->ptr = (char *)mrb_malloc(mrb, len+1);
if (p) {
memcpy(s->ptr, p, len);
}
s->ptr[len] = 0;
s->len = (mrb_int)len;
s->aux.capa = (mrb_int)len;
s = str_new(mrb, p, len);
return mrb_obj_value(s);
}
@@ -406,7 +398,7 @@ mrb_str_concat(mrb_state *mrb, mrb_value self, mrb_value other)
}
memcpy(s1->ptr+s1->len, s2->ptr, s2->len);
s1->len = len;
s1->ptr[len] = 0;
s1->ptr[len] = '\0';
}
/*
@@ -603,7 +595,7 @@ mrb_str_cmp_m(mrb_state *mrb, mrb_value str1)
return mrb_fixnum_value(result);
}
static int
static mrb_bool
str_eql(mrb_state *mrb, const mrb_value str1, const mrb_value str2)
{
const mrb_int len = RSTRING_LEN(str1);
@@ -614,7 +606,7 @@ str_eql(mrb_state *mrb, const mrb_value str1, const mrb_value str2)
return FALSE;
}
int
mrb_bool
mrb_str_equal(mrb_state *mrb, mrb_value str1, mrb_value str2)
{
if (mrb_obj_equal(mrb, str1, str2)) return TRUE;
@@ -2542,7 +2534,6 @@ mrb_init_string(mrb_state *mrb)
mrb_define_method(mrb, s, "*", mrb_str_times, MRB_ARGS_REQ(1)); /* 15.2.10.5.1 */
mrb_define_method(mrb, s, "<=>", mrb_str_cmp_m, MRB_ARGS_REQ(1)); /* 15.2.10.5.3 */
mrb_define_method(mrb, s, "==", mrb_str_equal_m, MRB_ARGS_REQ(1)); /* 15.2.10.5.4 */
mrb_define_method(mrb, s, "=~", noregexp, MRB_ARGS_REQ(1)); /* 15.2.10.5.5 */
mrb_define_method(mrb, s, "[]", mrb_str_aref_m, MRB_ARGS_ANY()); /* 15.2.10.5.6 */
mrb_define_method(mrb, s, "capitalize", mrb_str_capitalize, MRB_ARGS_NONE()); /* 15.2.10.5.7 */
mrb_define_method(mrb, s, "capitalize!", mrb_str_capitalize_bang, MRB_ARGS_REQ(1)); /* 15.2.10.5.8 */
@@ -2555,26 +2546,18 @@ mrb_init_string(mrb_state *mrb)
mrb_define_method(mrb, s, "empty?", mrb_str_empty_p, MRB_ARGS_NONE()); /* 15.2.10.5.16 */
mrb_define_method(mrb, s, "eql?", mrb_str_eql, MRB_ARGS_REQ(1)); /* 15.2.10.5.17 */
// NOTE: Regexp not implemented
mrb_define_method(mrb, s, "gsub", noregexp, MRB_ARGS_REQ(1)); /* 15.2.10.5.18 */
mrb_define_method(mrb, s, "gsub!", noregexp, MRB_ARGS_REQ(1)); /* 15.2.10.5.19 */
mrb_define_method(mrb, s, "hash", mrb_str_hash_m, MRB_ARGS_REQ(1)); /* 15.2.10.5.20 */
mrb_define_method(mrb, s, "include?", mrb_str_include, MRB_ARGS_REQ(1)); /* 15.2.10.5.21 */
mrb_define_method(mrb, s, "index", mrb_str_index_m, MRB_ARGS_ANY()); /* 15.2.10.5.22 */
mrb_define_method(mrb, s, "initialize", mrb_str_init, MRB_ARGS_REQ(1)); /* 15.2.10.5.23 */
mrb_define_method(mrb, s, "initialize_copy", mrb_str_replace, MRB_ARGS_REQ(1)); /* 15.2.10.5.24 */
mrb_define_method(mrb, s, "intern", mrb_str_intern, MRB_ARGS_NONE()); /* 15.2.10.5.25 */
mrb_define_method(mrb, s, "match", noregexp, MRB_ARGS_REQ(1)); /* 15.2.10.5.27 */
mrb_define_method(mrb, s, "replace", mrb_str_replace, MRB_ARGS_REQ(1)); /* 15.2.10.5.28 */
mrb_define_method(mrb, s, "reverse", mrb_str_reverse, MRB_ARGS_NONE()); /* 15.2.10.5.29 */
mrb_define_method(mrb, s, "reverse!", mrb_str_reverse_bang, MRB_ARGS_NONE()); /* 15.2.10.5.30 */
mrb_define_method(mrb, s, "rindex", mrb_str_rindex_m, MRB_ARGS_ANY()); /* 15.2.10.5.31 */
mrb_define_method(mrb, s, "scan", noregexp, MRB_ARGS_REQ(1)); /* 15.2.10.5.32 */
mrb_define_method(mrb, s, "slice", mrb_str_aref_m, MRB_ARGS_ANY()); /* 15.2.10.5.34 */
mrb_define_method(mrb, s, "split", mrb_str_split_m, MRB_ARGS_ANY()); /* 15.2.10.5.35 */
mrb_define_method(mrb, s, "sub", noregexp, MRB_ARGS_REQ(1)); /* 15.2.10.5.36 */
mrb_define_method(mrb, s, "sub!", noregexp, MRB_ARGS_REQ(1)); /* 15.2.10.5.37 */
mrb_define_method(mrb, s, "to_i", mrb_str_to_i, MRB_ARGS_ANY()); /* 15.2.10.5.38 */
mrb_define_method(mrb, s, "to_f", mrb_str_to_f, MRB_ARGS_NONE()); /* 15.2.10.5.39 */
+4 -4
View File
@@ -251,7 +251,7 @@ sym_to_sym(mrb_state *mrb, mrb_value sym)
#endif
#define is_identchar(c) (SIGN_EXTEND_CHAR(c)!=-1&&(ISALNUM(c) || (c) == '_'))
static int
static mrb_bool
is_special_global_name(const char* m)
{
switch (*m) {
@@ -274,7 +274,7 @@ is_special_global_name(const char* m)
return !*m;
}
static int
static mrb_bool
symname_p(const char *name)
{
const char *m = name;
@@ -382,7 +382,7 @@ mrb_sym2str(mrb_state *mrb, mrb_sym sym)
size_t len;
const char *name = mrb_sym2name_len(mrb, sym, &len);
mrb_value str;
if (!name) return mrb_undef_value(); /* can't happen */
str = mrb_str_new_static(mrb, name, len);
if (symname_p(name) && strlen(name) == len) {
@@ -452,5 +452,5 @@ mrb_init_symbol(mrb_state *mrb)
mrb_define_method(mrb, sym, "to_sym", sym_to_sym, MRB_ARGS_NONE()); /* 15.2.11.3.4 */
mrb_define_method(mrb, sym, "inspect", sym_inspect, MRB_ARGS_NONE()); /* 15.2.11.3.5(x) */
mrb_define_method(mrb, sym, "<=>", sym_cmp, MRB_ARGS_REQ(1));
mrb->init_sym = mrb_intern(mrb, "initialize");
mrb->init_sym = mrb_intern2(mrb, "initialize", 10);
}
+44 -3
View File
@@ -27,12 +27,21 @@ typedef struct segment {
struct segment *next;
} segment;
/* Instance variable table structure */
typedef struct iv_tbl {
segment *rootseg;
size_t size;
size_t last_len;
} iv_tbl;
/*
* Creates the instance variable table.
*
* Parameters
* mrb
* Returns
* the instance variable table.
*/
static iv_tbl*
iv_new(mrb_state *mrb)
{
@@ -47,6 +56,15 @@ iv_new(mrb_state *mrb)
return t;
}
/*
* Set the value for the symbol in the instance variable table.
*
* Parameters
* mrb
* t the instance variable table to be set in.
* sym the symbol to be used as the key.
* val the value to be set.
*/
static void
iv_put(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value val)
{
@@ -59,7 +77,7 @@ iv_put(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value val)
while (seg) {
for (i=0; i<MRB_SEGMENT_SIZE; i++) {
mrb_sym key = seg->key[i];
/* found room in last segment after last_len */
/* Found room in last segment after last_len */
if (!seg->next && i >= t->last_len) {
seg->key[i] = sym;
seg->val[i] = val;
@@ -80,7 +98,7 @@ iv_put(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value val)
seg = seg->next;
}
/* not found */
/* Not found */
t->size++;
if (matched_seg) {
matched_seg->key[matched_idx] = sym;
@@ -103,6 +121,18 @@ iv_put(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value val)
return;
}
/*
* Get a value for a symbol from the instance the variable table.
*
* Parameters
* mrb
* t the variable table to be searched.
* sym the symbol to be used as the key.
* vp the value pointer. Recieves the value if the specified symbol contains
* in the instance variable table.
* Returns
* true if the specfiyed symbol contains in the instance variable table.
*/
static mrb_bool
iv_get(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp)
{
@@ -127,6 +157,17 @@ iv_get(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp)
return FALSE;
}
/*
* Deletes the value for the symbol from the instance variable table.
*
* Parameters
* t the variable table to be searched.
* sym the symbol to be used as the key.
* vp the value pointer. Recieve the deleted value if the symbol contans
* in the instance varible table.
* Returns
* true if the specfied symbol contains in the instance variable table.
*/
static mrb_bool
iv_del(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp)
{
@@ -916,7 +957,7 @@ mrb_const_remove(mrb_state *mrb, mrb_value mod, mrb_sym sym)
void
mrb_define_const(mrb_state *mrb, struct RClass *mod, const char *name, mrb_value v)
{
mrb_obj_iv_set(mrb, (struct RObject*)mod, mrb_intern(mrb, name), v);
mrb_obj_iv_set(mrb, (struct RObject*)mod, mrb_intern_cstr(mrb, name), v);
}
void
+16 -10
View File
@@ -1,4 +1,4 @@
/*
/*
** vm.c - virtual machine for mruby
**
** See Copyright Notice in mruby.h
@@ -92,12 +92,12 @@ stack_init(mrb_state *mrb)
{
struct mrb_context *c = mrb->c;
/* assert(mrb->stack == NULL); */
/* mrb_assert(mrb->stack == NULL); */
c->stbase = (mrb_value *)mrb_calloc(mrb, STACK_INIT_SIZE, sizeof(mrb_value));
c->stend = c->stbase + STACK_INIT_SIZE;
c->stack = c->stbase;
/* assert(ci == NULL); */
/* mrb_assert(ci == NULL); */
c->cibase = (mrb_callinfo *)mrb_calloc(mrb, CALLINFO_INIT_SIZE, sizeof(mrb_callinfo));
c->ciend = c->cibase + CALLINFO_INIT_SIZE;
c->ci = c->cibase;
@@ -174,22 +174,22 @@ uvenv(mrb_state *mrb, int up)
struct REnv *e = mrb->c->ci->proc->env;
while (up--) {
if (!e) return 0;
if (!e) return NULL;
e = (struct REnv*)e->c;
}
return e;
}
static inline int
static inline mrb_bool
is_strict(mrb_state *mrb, struct REnv *e)
{
int cioff = e->cioff;
if (cioff >= 0 && mrb->c->cibase[cioff].proc &&
MRB_PROC_STRICT_P(mrb->c->cibase[cioff].proc)) {
return 1;
return TRUE;
}
return 0;
return FALSE;
}
static inline struct REnv*
@@ -279,7 +279,7 @@ ecall(mrb_state *mrb, int i)
mrb_value
mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, int argc, ...)
{
mrb_sym mid = mrb_intern(mrb, name);
mrb_sym mid = mrb_intern_cstr(mrb, name);
if (argc == 0) {
return mrb_funcall_argv(mrb, self, mid, 0, 0);
@@ -544,7 +544,7 @@ void mrb_gv_val_set(mrb_state *mrb, mrb_sym sym, mrb_value val);
mrb_value
mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
{
/* assert(mrb_proc_cfunc_p(proc)) */
/* mrb_assert(mrb_proc_cfunc_p(proc)) */
mrb_irep *irep = proc->body.irep;
mrb_code *pc = irep->iseq;
mrb_value *pool = irep->pool;
@@ -1261,7 +1261,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
mrb->c->stack = mrb->c->stbase + ci[1].stackidx;
if (ci[1].acc < 0 && prev_jmp) {
mrb->jmp = prev_jmp;
longjmp(*(jmp_buf*)mrb->jmp, 1);
mrb_longjmp(mrb);
}
while (eidx > ci->eidx) {
ecall(mrb, --eidx);
@@ -2127,3 +2127,9 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
}
END_DISPATCH;
}
void
mrb_longjmp(mrb_state *mrb)
{
longjmp(*(jmp_buf*)mrb->jmp, 1);
}