summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/mruby/irep.h10
-rw-r--r--mrblib/enum.rb21
-rw-r--r--src/cdump.c19
-rw-r--r--src/numeric.c3
-rw-r--r--src/proc.c7
-rw-r--r--src/state.c3
-rw-r--r--tools/mruby/mruby.c15
7 files changed, 51 insertions, 27 deletions
diff --git a/include/mruby/irep.h b/include/mruby/irep.h
index 0d8a05dbe..534590849 100644
--- a/include/mruby/irep.h
+++ b/include/mruby/irep.h
@@ -12,10 +12,10 @@ extern "C" {
#endif
typedef struct mrb_irep {
- int idx;
-
- int nlocals;
- int nregs;
+ int idx:16;
+ int nlocals:16;
+ int nregs:16;
+ int flags:8;
mrb_code *iseq;
mrb_value *pool;
@@ -28,6 +28,8 @@ typedef struct mrb_irep {
int ilen, plen, slen;
} mrb_irep;
+#define MRB_ISEQ_NO_FREE 1
+
void mrb_add_irep(mrb_state *mrb, int n);
#if defined(__cplusplus)
diff --git a/mrblib/enum.rb b/mrblib/enum.rb
index 2699a18af..29422716c 100644
--- a/mrblib/enum.rb
+++ b/mrblib/enum.rb
@@ -199,20 +199,31 @@ module Enumerable
#
# ISO 15.3.2.2.11
def inject(*args, &block)
- raise ArgumentError, "too many arguments" if args.size > 2
- flag = true # 1st element?
- result = nil
+ raise ArgumentError, "too many arguments" if args.size > 3
+ if Symbol === args[-1]
+ sym = args[-1]
+ block = ->(x,y){x.send(sym,y)}
+ args.pop
+ end
+ if args.empty?
+ flag = true # no initial argument
+ result = nil
+ else
+ flag = false
+ result = args[0]
+ end
self.each{|val|
if flag
- # 1st element
- result = (args.empty?)? val: block.call(args[0], val)
+ # push first element as initial
flag = false
+ result = val
else
result = block.call(result, val)
end
}
result
end
+ alias reduce inject
##
# Alias for collect
diff --git a/src/cdump.c b/src/cdump.c
index ba05a1899..c7597e12f 100644
--- a/src/cdump.c
+++ b/src/cdump.c
@@ -113,6 +113,7 @@ make_cdump_irep(mrb_state *mrb, int irep_no, FILE *f)
SOURCE_CODE0 (" ai = mrb->arena_idx;");
SOURCE_CODE0 (" irep = mrb->irep[idx] = mrb_malloc(mrb, sizeof(mrb_irep));");
+ SOURCE_CODE0 (" irep->flags = MRB_ISEQ_NO_FREE;");
SOURCE_CODE0 (" irep->idx = idx++;");
SOURCE_CODE (" irep->nlocals = %d;", irep->nlocals);
SOURCE_CODE (" irep->nregs = %d;", irep->nregs);
@@ -124,13 +125,19 @@ make_cdump_irep(mrb_state *mrb, int irep_no, FILE *f)
SOURCE_CODE (" irep->syms = mrb_malloc(mrb, sizeof(mrb_sym)*%d);", irep->slen);
for (n=0; n<irep->slen; n++)
if (irep->syms[n]) {
- SOURCE_CODE (" irep->syms[%d] = mrb_intern(mrb, \"%s\");", n, mrb_sym2name(mrb, irep->syms[n]));
+ const char *name;
+ int len;
+
+ name = mrb_sym2name_len(mrb, irep->syms[n], &len);
+ SOURCE_CODE (" irep->syms[%d] = mrb_intern2(mrb, \"%s\", %d);", n, name, len);
}
}
else
SOURCE_CODE0 (" irep->syms = NULL;");
- SOURCE_CODE (" irep->plen = %d;", irep->plen);
+ SOURCE_CODE0 (" irep->pool = NULL;");
+ SOURCE_CODE0 (" mrb->irep_len = idx;");
+ SOURCE_CODE0 (" irep->plen = 0;");
if(irep->plen > 0) {
SOURCE_CODE (" irep->pool = mrb_malloc(mrb, sizeof(mrb_value)*%d);", irep->plen);
for (n=0; n<irep->plen; n++) {
@@ -148,16 +155,16 @@ make_cdump_irep(mrb_state *mrb, int irep_no, FILE *f)
}
}
memset(buf, 0, buf_len);
- SOURCE_CODE(" irep->pool[%d] = mrb_str_new(mrb, \"%s\", %d);", n, str_to_format(irep->pool[n], buf), RSTRING_LEN(irep->pool[n])); break;
+ SOURCE_CODE(" irep->pool[%d] = mrb_str_new(mrb, \"%s\", %d);", n, str_to_format(irep->pool[n], buf), RSTRING_LEN(irep->pool[n]));
+ SOURCE_CODE0 (" mrb->arena_idx = ai;");
+ break;
/* TODO MRB_TT_REGEX */
default: break;
}
+ SOURCE_CODE0(" irep->plen++;");
}
}
else
- SOURCE_CODE0 (" irep->pool = NULL;");
- SOURCE_CODE0 (" mrb->irep_len = idx;");
- SOURCE_CODE0 (" mrb->arena_idx = ai;");
SOURCE_CODE0("");
return MRB_CDUMP_OK;
}
diff --git a/src/numeric.c b/src/numeric.c
index 6970869df..284d0a82e 100644
--- a/src/numeric.c
+++ b/src/numeric.c
@@ -949,8 +949,7 @@ fix_xor(mrb_state *mrb, mrb_value x)
static mrb_value
lshift(mrb_state *mrb, mrb_int val, unsigned long width)
{
- if (width > (sizeof(mrb_int)*CHAR_BIT-1)
- || ((unsigned long)abs(val))>>(sizeof(mrb_int)*CHAR_BIT-1-width) > 0) {
+ if (width > (sizeof(mrb_int)*CHAR_BIT-1)) {
mrb_raise(mrb, E_RANGE_ERROR, "width(%d) > (%d:sizeof(mrb_int)*CHAR_BIT-1)", width,
sizeof(mrb_int)*CHAR_BIT-1);
}
diff --git a/src/proc.c b/src/proc.c
index 0efc8d286..3321c2a91 100644
--- a/src/proc.c
+++ b/src/proc.c
@@ -9,6 +9,10 @@
#include "mruby/class.h"
#include "opcode.h"
+static mrb_code call_iseq[] = {
+ MKOP_A(OP_CALL, 0),
+};
+
struct RProc *
mrb_proc_new(mrb_state *mrb, mrb_irep *irep)
{
@@ -144,14 +148,13 @@ void
mrb_init_proc(mrb_state *mrb)
{
struct RProc *m;
- mrb_code *call_iseq = (mrb_code *)mrb_alloca(mrb, sizeof(mrb_code));
mrb_irep *call_irep = (mrb_irep *)mrb_alloca(mrb, sizeof(mrb_irep));
if ( call_iseq == NULL || call_irep == NULL )
return;
memset(call_irep, 0, sizeof(mrb_irep));
- *call_iseq = MKOP_A(OP_CALL, 0);
+ call_irep->flags = MRB_ISEQ_NO_FREE;
call_irep->idx = -1;
call_irep->iseq = call_iseq;
call_irep->ilen = 1;
diff --git a/src/state.c b/src/state.c
index 40d9bfc45..991be310e 100644
--- a/src/state.c
+++ b/src/state.c
@@ -92,7 +92,8 @@ mrb_close(mrb_state *mrb)
mrb_free(mrb, mrb->stbase);
mrb_free(mrb, mrb->cibase);
for (i=0; i<mrb->irep_len; i++) {
- mrb_free(mrb, mrb->irep[i]->iseq);
+ if (!(mrb->irep[i]->flags & MRB_ISEQ_NO_FREE))
+ mrb_free(mrb, mrb->irep[i]->iseq);
mrb_free(mrb, mrb->irep[i]->pool);
mrb_free(mrb, mrb->irep[i]->syms);
mrb_free(mrb, mrb->irep[i]->lines);
diff --git a/tools/mruby/mruby.c b/tools/mruby/mruby.c
index c1ac0d778..cbe170e7f 100644
--- a/tools/mruby/mruby.c
+++ b/tools/mruby/mruby.c
@@ -172,7 +172,7 @@ main(int argc, char **argv)
mrb_value ARGV;
if (mrb == NULL) {
- fprintf(stderr, "Invalid mrb_state, exiting mruby");
+ fprintf(stderr, "Invalid mrb_state, exiting mruby\n");
return EXIT_FAILURE;
}
@@ -191,12 +191,13 @@ main(int argc, char **argv)
if (args.mrbfile) {
n = mrb_load_irep(mrb, args.rfp);
- if (n >= 0) {
- if (!args.check_syntax) {
- mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb));
- if (mrb->exc) {
- p(mrb, mrb_obj_value(mrb->exc));
- }
+ if (n < 0) {
+ fprintf(stderr, "failed to load mrb file: %s\n", args.cmdline);
+ }
+ else if (!args.check_syntax) {
+ mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb));
+ if (mrb->exc) {
+ p(mrb, mrb_obj_value(mrb->exc));
}
}
}