mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Merge upstream
This commit is contained in:
+23
-47
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <stddef.h>
|
||||
|
||||
// Calculate CRC (CRC-16-CCITT)
|
||||
//
|
||||
|
||||
+4
-5
@@ -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
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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) */
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user