summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c4
-rw-r--r--mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c2
-rw-r--r--mrbgems/mruby-string-ext/mrblib/string.rb46
-rw-r--r--mrbgems/mruby-string-ext/src/string.c92
-rw-r--r--mrbgems/mruby-string-ext/test/string.rb20
-rw-r--r--src/backtrace.c1
-rw-r--r--src/codedump.c3
-rw-r--r--src/gc.c5
-rw-r--r--src/kernel.c11
-rw-r--r--src/string.c2
-rw-r--r--src/vm.c28
-rw-r--r--test/t/kernel.rb7
12 files changed, 153 insertions, 68 deletions
diff --git a/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c b/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c
index 218aeda90..27f27a05a 100644
--- a/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c
+++ b/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c
@@ -43,7 +43,7 @@ check_lineno( mrb_irep_debug_info_file *info_file, uint16_t lineno )
}
static int32_t
-get_break_index( mrb_debug_context *dbg, int32_t bpno )
+get_break_index( mrb_debug_context *dbg, uint32_t bpno )
{
uint32_t i;
int32_t index;
@@ -296,7 +296,7 @@ mrb_debug_get_break_all( mrb_state *mrb, mrb_debug_context *dbg, uint32_t size,
int32_t
mrb_debug_get_break( mrb_state *mrb, mrb_debug_context *dbg, uint32_t bpno, mrb_debug_breakpoint *bp )
{
- uint32_t index;
+ int32_t index;
if((mrb == NULL) || (dbg == NULL) || (bp == NULL)) {
return MRB_DEBUG_INVALID_ARGUMENT;
diff --git a/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c b/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c
index 1c77d1ef8..33e9575bf 100644
--- a/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c
+++ b/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c
@@ -71,7 +71,7 @@ dirname(mrb_state *mrb, const char *path)
}
p = strrchr(path, '/');
- len = p != NULL ? p - path : strlen(path);
+ len = p != NULL ? (size_t)(p - path) : strlen(path);
dir = mrb_malloc(mrb, len + 1);
strncpy(dir, path, len);
diff --git a/mrbgems/mruby-string-ext/mrblib/string.rb b/mrbgems/mruby-string-ext/mrblib/string.rb
index 6e5f3c73d..610a462a7 100644
--- a/mrbgems/mruby-string-ext/mrblib/string.rb
+++ b/mrbgems/mruby-string-ext/mrblib/string.rb
@@ -263,52 +263,6 @@ class String
self
end
- ##
- # call-seq:
- # str.ljust(integer, padstr=' ') -> new_str
- #
- # If <i>integer</i> is greater than the length of <i>str</i>, returns a new
- # <code>String</code> of length <i>integer</i> with <i>str</i> left justified
- # and padded with <i>padstr</i>; otherwise, returns <i>str</i>.
- #
- # "hello".ljust(4) #=> "hello"
- # "hello".ljust(20) #=> "hello "
- # "hello".ljust(20, '1234') #=> "hello123412341234123"
- def ljust(idx, padstr = ' ')
- if idx <= self.size
- return self
- end
- newstr = self.dup
- newstr << padstr
- while newstr.size <= idx
- newstr << padstr
- end
- return newstr.slice(0,idx)
- end
-
- ##
- # call-seq:
- # str.rjust(integer, padstr=' ') -> new_str
- #
- # If <i>integer</i> is greater than the length of <i>str</i>, returns a new
- # <code>String</code> of length <i>integer</i> with <i>str</i> right justified
- # and padded with <i>padstr</i>; otherwise, returns <i>str</i>.
- #
- # "hello".rjust(4) #=> "hello"
- # "hello".rjust(20) #=> " hello"
- # "hello".rjust(20, '1234') #=> "123412341234123hello"
- def rjust(idx, padstr = ' ')
- if idx <= self.size
- return self
- end
- padsize = idx - self.size
- newstr = padstr.dup
- while newstr.size <= padsize
- newstr << padstr
- end
- return newstr.slice(0,padsize) + self
- end
-
# str.upto(other_str, exclusive=false) {|s| block } -> str
# str.upto(other_str, exclusive=false) -> an_enumerator
#
diff --git a/mrbgems/mruby-string-ext/src/string.c b/mrbgems/mruby-string-ext/src/string.c
index 7e87b3db4..45d406f6f 100644
--- a/mrbgems/mruby-string-ext/src/string.c
+++ b/mrbgems/mruby-string-ext/src/string.c
@@ -5,6 +5,9 @@
#include <mruby/string.h>
#include <mruby/range.h>
+#define MAX(a,b) ((a)>(b) ? (a) : (b))
+#define MIN(a,b) ((a)<(b) ? (a) : (b))
+
static mrb_value
mrb_str_getbyte(mrb_state *mrb, mrb_value str)
{
@@ -509,6 +512,93 @@ mrb_str_ord(mrb_state* mrb, mrb_value str)
}
#endif
+static mrb_value
+mrb_str_just(mrb_state* mrb, mrb_value str, mrb_bool right_just)
+{
+ mrb_value new_str;
+ mrb_int idx = 0, i = 0, bytes_to_copy = 0, start_pos = 0, final_pos = 0,
+ pad_str_length = 0;
+ mrb_int str_length = RSTRING_LEN(str);
+ const char *pad_str = NULL;
+ char *new_str_ptr = NULL;
+
+ mrb_get_args(mrb, "i|s!", &idx, &pad_str, &pad_str_length);
+
+ if (pad_str == NULL)
+ {
+ pad_str = " ";
+ pad_str_length = 1;
+ }
+
+ if (pad_str_length == 0)
+ {
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "zero width padding");
+ }
+
+ if (idx <= str_length)
+ {
+ return str;
+ }
+
+ new_str = mrb_str_dup(mrb, str);
+ mrb_str_resize(mrb, new_str, idx);
+
+ new_str_ptr = RSTRING_PTR(new_str);
+
+ if (right_just)
+ {
+ memcpy(new_str_ptr + idx - str_length, RSTRING_PTR(str), str_length);
+ }
+
+ start_pos = right_just ? 0 : str_length;
+ final_pos = idx - (right_just ? str_length : 0);
+
+ for (i = start_pos; i < final_pos; i += pad_str_length)
+ {
+ bytes_to_copy = idx - i - (right_just ? str_length : 0);
+ bytes_to_copy = MIN(pad_str_length, bytes_to_copy);
+ memcpy(new_str_ptr + i, pad_str, bytes_to_copy);
+ }
+
+ return new_str;
+}
+
+/*
+ * call-seq:
+ * str.ljust(integer, padstr=' ') -> new_str
+ *
+ * If <i>integer</i> is greater than the length of <i>str</i>, returns a new
+ * <code>String</code> of length <i>integer</i> with <i>str</i> left justified
+ * and padded with <i>padstr</i>; otherwise, returns <i>str</i>.
+ *
+ * "hello".ljust(4) #=> "hello"
+ * "hello".ljust(20) #=> "hello "
+ * "hello".ljust(20, '1234') #=> "hello123412341234123"
+ */
+static mrb_value
+mrb_str_ljust(mrb_state* mrb, mrb_value str)
+{
+ return mrb_str_just(mrb, str, FALSE);
+}
+
+/*
+ * call-seq:
+ * str.rjust(integer, padstr=' ') -> new_str
+ *
+ * If <i>integer</i> is greater than the length of <i>str</i>, returns a new
+ * <code>String</code> of length <i>integer</i> with <i>str</i> right justified
+ * and padded with <i>padstr</i>; otherwise, returns <i>str</i>.
+ *
+ * "hello".rjust(4) #=> "hello"
+ * "hello".rjust(20) #=> " hello"
+ * "hello".rjust(20, '1234') #=> "123412341234123hello"
+ */
+static mrb_value
+mrb_str_rjust(mrb_state* mrb, mrb_value str)
+{
+ return mrb_str_just(mrb, str, TRUE);
+}
+
void
mrb_mruby_string_ext_gem_init(mrb_state* mrb)
{
@@ -530,6 +620,8 @@ mrb_mruby_string_ext_gem_init(mrb_state* mrb)
mrb_define_method(mrb, s, "lines", mrb_str_lines, MRB_ARGS_NONE());
mrb_define_method(mrb, s, "succ", mrb_str_succ, MRB_ARGS_NONE());
mrb_define_method(mrb, s, "succ!", mrb_str_succ_bang, MRB_ARGS_NONE());
+ mrb_define_method(mrb, s, "ljust", mrb_str_ljust, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1));
+ mrb_define_method(mrb, s, "rjust", mrb_str_rjust, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1));
mrb_alias_method(mrb, s, mrb_intern_lit(mrb, "next"), mrb_intern_lit(mrb, "succ"));
mrb_alias_method(mrb, s, mrb_intern_lit(mrb, "next!"), mrb_intern_lit(mrb, "succ!"));
mrb_define_method(mrb, s, "ord", mrb_str_ord, MRB_ARGS_NONE());
diff --git a/mrbgems/mruby-string-ext/test/string.rb b/mrbgems/mruby-string-ext/test/string.rb
index 228a236af..2b2c02b8b 100644
--- a/mrbgems/mruby-string-ext/test/string.rb
+++ b/mrbgems/mruby-string-ext/test/string.rb
@@ -444,6 +444,26 @@ assert('String#rjust') do
assert_equal "hello", "hello".rjust(-3)
end
+assert('String#ljust should not change string') do
+ a = "hello"
+ a.ljust(20)
+ assert_equal "hello", a
+end
+
+assert('String#rjust should not change string') do
+ a = "hello"
+ a.rjust(20)
+ assert_equal "hello", a
+end
+
+assert('String#ljust should raise on zero width padding') do
+ assert_raise(ArgumentError) { "foo".ljust(10, '') }
+end
+
+assert('String#rjust should raise on zero width padding') do
+ assert_raise(ArgumentError) { "foo".rjust(10, '') }
+end
+
assert('String#upto') do
a = "aa"
start = "aa"
diff --git a/src/backtrace.c b/src/backtrace.c
index b499cee5a..051d5d4e0 100644
--- a/src/backtrace.c
+++ b/src/backtrace.c
@@ -118,6 +118,7 @@ each_backtrace(mrb_state *mrb, mrb_int ciidx, mrb_code *pc0, each_backtrace_func
if (MRB_PROC_CFUNC_P(ci->proc)) continue;
irep = ci->proc->body.irep;
+ if (!irep) continue;
if (mrb->c->cibase[i].err) {
pc = mrb->c->cibase[i].err;
diff --git a/src/codedump.c b/src/codedump.c
index 4b13d4361..59ba4fdae 100644
--- a/src/codedump.c
+++ b/src/codedump.c
@@ -416,8 +416,7 @@ codedump(mrb_state *mrb, mrb_irep *irep)
print_lv(mrb, irep, c, RA);
break;
case OP_POPERR:
- printf("OP_POPERR\t%d\t\t", GETARG_A(c));
- print_lv(mrb, irep, c, RA);
+ printf("OP_POPERR\t%d\t\t\n", GETARG_A(c));
break;
case OP_EPOP:
printf("OP_EPOP\t%d\n", GETARG_A(c));
diff --git a/src/gc.c b/src/gc.c
index 88d157d9c..1608dbcb2 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -857,7 +857,12 @@ root_scan_phase(mrb_state *mrb, mrb_gc *gc)
mrb_gc_mark(mrb, (struct RBasic*)mrb->top_self);
/* mark exception */
mrb_gc_mark(mrb, (struct RBasic*)mrb->exc);
+ /* mark backtrace */
mrb_gc_mark(mrb, (struct RBasic*)mrb->backtrace.exc);
+ e = (size_t)mrb->backtrace.n;
+ for (i=0; i<e; i++) {
+ mrb_gc_mark(mrb, (struct RBasic*)mrb->backtrace.entries[i].klass);
+ }
/* mark pre-allocated exception */
mrb_gc_mark(mrb, (struct RBasic*)mrb->nomem_err);
#ifdef MRB_GC_FIXED_ARENA
diff --git a/src/kernel.c b/src/kernel.c
index 5ca1736c3..8b00d701b 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -6,6 +6,7 @@
#include <mruby.h>
#include <mruby/array.h>
+#include <mruby/hash.h>
#include <mruby/class.h>
#include <mruby/proc.h>
#include <mruby/string.h>
@@ -1106,8 +1107,8 @@ mrb_obj_ceqq(mrb_state *mrb, mrb_value self)
static mrb_value
mrb_local_variables(mrb_state *mrb, mrb_value self)
{
- mrb_value ret;
struct RProc *proc;
+ mrb_value vars;
struct mrb_irep *irep;
size_t i;
@@ -1121,10 +1122,10 @@ mrb_local_variables(mrb_state *mrb, mrb_value self)
if (!irep->lv) {
return mrb_ary_new(mrb);
}
- ret = mrb_ary_new_capa(mrb, irep->nlocals - 1);
+ vars = mrb_hash_new(mrb);
for (i = 0; i + 1 < irep->nlocals; ++i) {
if (irep->lv[i].name) {
- mrb_ary_push(mrb, ret, mrb_symbol_value(irep->lv[i].name));
+ mrb_hash_set(mrb, vars, mrb_symbol_value(irep->lv[i].name), mrb_true_value());
}
}
if (proc->env) {
@@ -1137,7 +1138,7 @@ mrb_local_variables(mrb_state *mrb, mrb_value self)
if (irep->lv) {
for (i = 0; i + 1 < irep->nlocals; ++i) {
if (irep->lv[i].name) {
- mrb_ary_push(mrb, ret, mrb_symbol_value(irep->lv[i].name));
+ mrb_hash_set(mrb, vars, mrb_symbol_value(irep->lv[i].name), mrb_true_value());
}
}
}
@@ -1146,7 +1147,7 @@ mrb_local_variables(mrb_state *mrb, mrb_value self)
}
}
- return ret;
+ return mrb_hash_keys(mrb, vars);
}
void
diff --git a/src/string.c b/src/string.c
index 7a75bb63e..c370e0723 100644
--- a/src/string.c
+++ b/src/string.c
@@ -2644,7 +2644,7 @@ mrb_str_inspect(mrb_state *mrb, mrb_value str)
}
#endif
c = *p;
- if (c == '"'|| c == '\\' || (c == '#' && IS_EVSTR(p, pend))) {
+ if (c == '"'|| c == '\\' || (c == '#' && IS_EVSTR(p+1, pend))) {
buf[0] = '\\'; buf[1] = c;
mrb_str_cat(mrb, result, buf, 2);
continue;
diff --git a/src/vm.c b/src/vm.c
index 0c0f5a4bb..e734775e2 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -1309,7 +1309,9 @@ RETRY_TRY_BLOCK:
else {
stack_extend(mrb, irep->nregs, ci->argc+2);
}
- regs[0] = m->env->stack[0];
+ if(m->env) {
+ regs[0] = m->env->stack[0];
+ }
pc = irep->iseq;
JUMP;
}
@@ -1364,11 +1366,22 @@ RETRY_TRY_BLOCK:
ci->mid = mid;
ci->proc = m;
ci->stackent = mrb->c->stack;
- if (n == CALL_MAXARGS) {
- ci->argc = -1;
- }
- else {
- ci->argc = n;
+ {
+ int bidx;
+ mrb_value blk;
+
+ if (n == CALL_MAXARGS) {
+ ci->argc = -1;
+ bidx = a+2;
+ }
+ else {
+ ci->argc = n;
+ bidx = a+n+1;
+ }
+ blk = regs[bidx];
+ if (!mrb_nil_p(blk) && mrb_type(blk) != MRB_TT_PROC) {
+ regs[bidx] = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc");
+ }
}
ci->target_class = c;
ci->pc = pc + 1;
@@ -1705,9 +1718,10 @@ RETRY_TRY_BLOCK:
mrb->jmp = prev_jmp;
return v;
}
- cipop(mrb);
+ ci = mrb->c->ci;
acc = ci->acc;
mrb->c->stack = ci->stackent;
+ cipop(mrb);
if (acc == CI_ACC_SKIP) {
mrb->jmp = prev_jmp;
return v;
diff --git a/test/t/kernel.rb b/test/t/kernel.rb
index ca4b73907..aff2dd461 100644
--- a/test/t/kernel.rb
+++ b/test/t/kernel.rb
@@ -549,11 +549,10 @@ assert('Kernel.local_variables', '15.3.1.2.7') do
vars = Kernel.local_variables.sort
assert_equal [:a, :b, :vars], vars
- Proc.new {
+ assert_equal [:a, :b, :c, :vars], Proc.new { |a, b|
c = 2
- vars = Kernel.local_variables.sort
- assert_equal [:a, :b, :c, :vars], vars
- }.call
+ Kernel.local_variables.sort
+ }.call(-1, -2)
end
assert('Kernel#!=') do