summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/mruby/range.h2
-rw-r--r--src/array.c14
-rw-r--r--src/codegen.c17
-rw-r--r--src/gc.c6
-rw-r--r--src/hash.c7
-rw-r--r--src/kernel.c2
-rw-r--r--src/range.c24
-rw-r--r--src/string.c17
-rw-r--r--src/struct.c1
-rw-r--r--src/vm.c5
-rw-r--r--test/t/exception.rb10
11 files changed, 59 insertions, 46 deletions
diff --git a/include/mruby/range.h b/include/mruby/range.h
index 4f1f3803e..32094f9bb 100644
--- a/include/mruby/range.h
+++ b/include/mruby/range.h
@@ -26,7 +26,7 @@ struct RRange {
#define mrb_range_value(p) mrb_obj_value((void*)(p))
mrb_value mrb_range_new(mrb_state*, mrb_value, mrb_value, int);
-mrb_int mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_int err);
+mrb_int mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len);
#if defined(__cplusplus)
} /* extern "C" { */
diff --git a/src/array.c b/src/array.c
index 29e43b34f..88c15eb2c 100644
--- a/src/array.c
+++ b/src/array.c
@@ -63,6 +63,20 @@ mrb_ary_new(mrb_state *mrb)
return mrb_ary_new_capa(mrb, 0);
}
+/*
+ * to copy array, use this instead of memcpy because of portability
+ * * gcc on ARM may fail optimization of memcpy
+ * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka3934.html
+ * * gcc on MIPS also fail
+ * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39755
+ * * memcpy doesn't exist on freestanding environment
+ *
+ * If you optimize for binary size, use memcpy instead of this at your own risk
+ * of above portability issue.
+ *
+ * see also http://togetter.com/li/462898
+ *
+ */
static inline void
array_copy(mrb_value *dst, const mrb_value *src, size_t size)
{
diff --git a/src/codegen.c b/src/codegen.c
index 53324f321..88bce7dac 100644
--- a/src/codegen.c
+++ b/src/codegen.c
@@ -838,7 +838,6 @@ gen_assignment(codegen_scope *s, node *node, int sp, int val)
lv++;
up = up->prev;
}
- // assert(up!=0);
}
break;
case NODE_IVAR:
@@ -1571,15 +1570,20 @@ codegen(codegen_scope *s, node *tree, int val)
break;
case NODE_RETURN:
- codegen(s, tree, VAL);
- pop();
+ if (tree) {
+ codegen(s, tree, VAL);
+ pop();
+ }
+ else {
+ genop(s, MKOP_A(OP_LOADNIL, cursp()));
+ }
if (s->loop) {
genop(s, MKOP_AB(OP_RETURN, cursp(), OP_R_RETURN));
}
else {
genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL);
}
- push();
+ if (val) push();
break;
case NODE_YIELD:
@@ -1631,6 +1635,9 @@ codegen(codegen_scope *s, node *tree, int val)
codegen(s, tree, VAL);
pop();
}
+ else {
+ genop(s, MKOP_A(OP_LOADNIL, cursp()));
+ }
genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL);
}
if (val) push();
@@ -2125,6 +2132,7 @@ codegen(codegen_scope *s, node *tree, int val)
genop(s, MKOP_AB(OP_METHOD, cursp(), sym));
if (val) {
genop(s, MKOP_A(OP_LOADNIL, cursp()));
+ push();
}
}
break;
@@ -2144,6 +2152,7 @@ codegen(codegen_scope *s, node *tree, int val)
genop(s, MKOP_AB(OP_METHOD, cursp(), sym));
if (val) {
genop(s, MKOP_A(OP_LOADNIL, cursp()));
+ push();
}
}
break;
diff --git a/src/gc.c b/src/gc.c
index 45d8b99c8..58326d396 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -271,9 +271,9 @@ add_heap(mrb_state *mrb)
#define DEFAULT_GC_INTERVAL_RATIO 200
#define DEFAULT_GC_STEP_RATIO 200
#define DEFAULT_MAJOR_GC_INC_RATIO 200
-#define is_generational(mrb) (mrb->is_generational_gc_mode)
-#define is_major_gc(mrb) (is_generational(mrb) && mrb->gc_full)
-#define is_minor_gc(mrb) (is_generational(mrb) && !mrb->gc_full)
+#define is_generational(mrb) ((mrb)->is_generational_gc_mode)
+#define is_major_gc(mrb) (is_generational(mrb) && (mrb)->gc_full)
+#define is_minor_gc(mrb) (is_generational(mrb) && !(mrb)->gc_full)
void
mrb_init_heap(mrb_state *mrb)
diff --git a/src/hash.c b/src/hash.c
index 5fa3c1ef8..928407f67 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -150,13 +150,6 @@ mrb_hash_set(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value val) /* mr
}
mrb_value
-mrb_hash_freeze(mrb_value hash)
-{
- //return mrb_obj_freeze(hash);
- return (hash);
-}
-
-mrb_value
mrb_hash_dup(mrb_state *mrb, mrb_value hash)
{
struct RHash* ret;
diff --git a/src/kernel.c b/src/kernel.c
index de4e474b3..c37b58684 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -807,7 +807,7 @@ retry:
* end
* end
* k = Klass.new
- * k.methods[0..9] #=> [:kMethod, :freeze, :nil?, :is_a?,
+ * k.methods[0..9] #=> [:kMethod, :respond_to?, :nil?, :is_a?,
* # :class, :instance_variable_set,
* # :methods, :extend, :__send__, :instance_eval]
* k.methods.length #=> 42
diff --git a/src/range.c b/src/range.c
index 2cdc34f5c..2e9ec26ed 100644
--- a/src/range.c
+++ b/src/range.c
@@ -10,10 +10,6 @@
#include "mruby/string.h"
#include <string.h>
-#ifndef OTHER
-#define OTHER 2
-#endif
-
#define RANGE_CLASS (mrb_class_obj_get(mrb, "Range"))
static void
@@ -274,12 +270,14 @@ mrb_range_each(mrb_state *mrb, mrb_value range)
}
mrb_int
-mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_int err)
+mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len)
{
mrb_int beg, end, b, e;
struct RRange *r = mrb_range_ptr(range);
- if (mrb_type(range) != MRB_TT_RANGE) return FALSE;
+ if (mrb_type(range) != MRB_TT_RANGE) {
+ mrb_raise(mrb, E_TYPE_ERROR, "expected Range.");
+ }
beg = b = mrb_fixnum(r->edges->beg);
end = e = mrb_fixnum(r->edges->end);
@@ -288,10 +286,10 @@ mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp,
beg += len;
if (beg < 0) goto out_of_range;
}
- if (err == 0 || err == 2) {
- if (beg > len) goto out_of_range;
- if (end > len) end = len;
- }
+
+ if (beg > len) goto out_of_range;
+ if (end > len) end = len;
+
if (end < 0) end += len;
if (!r->excl && end < len) end++; /* include end point */
len = end - beg;
@@ -302,11 +300,7 @@ mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp,
return TRUE;
out_of_range:
- if (err) {
- mrb_raisef(mrb, E_RANGE_ERROR, "%ld..%s%ld out of range",
- b, r->excl? "." : "", e);
- }
- return OTHER;
+ return FALSE;
}
/* 15.2.14.4.12(x) */
diff --git a/src/string.c b/src/string.c
index 205c39876..7af0d1d59 100644
--- a/src/string.c
+++ b/src/string.c
@@ -759,23 +759,22 @@ num_index:
return mrb_str_dup(mrb, indx);
return mrb_nil_value();
- default:
+ case MRB_TT_RANGE:
/* check if indx is Range */
{
mrb_int beg, len;
mrb_value tmp;
len = RSTRING_LEN(str);
- switch (mrb_range_beg_len(mrb, indx, &beg, &len, len, 0)) {
- case FALSE:
- break;
- case 2/*OTHER*/:
- return mrb_nil_value();
- default:
- tmp = mrb_str_subseq(mrb, str, beg, len);
- return tmp;
+ if (mrb_range_beg_len(mrb, indx, &beg, &len, len)) {
+ tmp = mrb_str_subseq(mrb, str, beg, len);
+ return tmp;
+ }
+ else {
+ return mrb_nil_value();
}
}
+ default:
idx = mrb_fixnum(indx);
goto num_index;
}
diff --git a/src/struct.c b/src/struct.c
index 5026a6ab4..d7b63259e 100644
--- a/src/struct.c
+++ b/src/struct.c
@@ -251,7 +251,6 @@ make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass * k
long i, len;
struct RClass *c;
- //OBJ_FREEZE(members);
if (mrb_nil_p(name)) {
c = mrb_class_new(mrb, klass);
}
diff --git a/src/vm.c b/src/vm.c
index e4b283849..febb4dbd2 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -316,8 +316,13 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, int argc, mr
if (!mrb->jmp) {
jmp_buf c_jmp;
+ mrb_callinfo *old_ci = mrb->ci;
if (setjmp(c_jmp) != 0) { /* error */
+ while (old_ci != mrb->ci) {
+ mrb->stack = mrb->stbase + mrb->ci->stackidx;
+ cipop(mrb);
+ }
mrb->jmp = 0;
return mrb_nil_value();
}
diff --git a/test/t/exception.rb b/test/t/exception.rb
index 663c8f337..7ecc51fa8 100644
--- a/test/t/exception.rb
+++ b/test/t/exception.rb
@@ -321,19 +321,19 @@ end
# very deeply recursive function that stil returns albeit very deeply so
$test_infinite_recursion = 0
-TEST_INFINITE_RECURSION_MAX = 100000
+TEST_INFINITE_RECURSION_MAX = 1000000
def test_infinite_recursion
$test_infinite_recursion += 1
if $test_infinite_recursion > TEST_INFINITE_RECURSION_MAX
- return $test_infinite_recursion
+ return $test_infinite_recursion
end
- test_infinite_recursion
+ test_infinite_recursion
end
assert('Infinite recursion should result in an exception being raised') do
- a = begin
+ a = begin
test_infinite_recursion
- rescue
+ rescue
:ok
end
# OK if an exception was caught, otherwise a number will be stored in a