summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/mruby.h1
-rw-r--r--include/mruby/compile.h2
-rw-r--r--mrbgems/mruby-bin-mirb/tools/mirb/mirb.c15
-rw-r--r--mrbgems/mruby-bin-mruby/tools/mruby/mruby.c2
-rw-r--r--mrbgems/mruby-fiber/src/fiber.c21
-rw-r--r--mrbgems/mruby-random/src/random.c140
-rw-r--r--mrbgems/mruby-random/test/random.rb30
-rw-r--r--src/codegen.c44
-rw-r--r--src/gc.c3
-rw-r--r--src/load.c4
-rw-r--r--src/parse.y15
-rw-r--r--src/vm.c10
-rw-r--r--tools/mrbc/mrbc.c2
13 files changed, 197 insertions, 92 deletions
diff --git a/include/mruby.h b/include/mruby.h
index b3dc59a08..445bc5e11 100644
--- a/include/mruby.h
+++ b/include/mruby.h
@@ -261,6 +261,7 @@ void mrb_close(mrb_state*);
mrb_value mrb_top_self(mrb_state *);
mrb_value mrb_run(mrb_state*, struct RProc*, mrb_value);
+mrb_value mrb_context_run(mrb_state*, struct RProc*, mrb_value, unsigned int);
void mrb_p(mrb_state*, mrb_value);
mrb_int mrb_obj_id(mrb_value obj);
diff --git a/include/mruby/compile.h b/include/mruby/compile.h
index a75694f55..0cbeb0f03 100644
--- a/include/mruby/compile.h
+++ b/include/mruby/compile.h
@@ -165,7 +165,7 @@ struct mrb_parser_state* mrb_parse_file(mrb_state*,FILE*,mrbc_context*);
#endif
struct mrb_parser_state* mrb_parse_string(mrb_state*,const char*,mrbc_context*);
struct mrb_parser_state* mrb_parse_nstring(mrb_state*,const char*,int,mrbc_context*);
-int mrb_generate_code(mrb_state*, struct mrb_parser_state*);
+struct RProc* mrb_generate_code(mrb_state*, struct mrb_parser_state*);
/* program load functions */
#ifdef ENABLE_STDIO
diff --git a/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c b/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c
index ad6a913c7..f5e5900f0 100644
--- a/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c
+++ b/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c
@@ -255,6 +255,8 @@ main(int argc, char **argv)
int n;
int code_block_open = FALSE;
int ai;
+ int first_command = 1;
+ unsigned int nregs;
/* new interpreter instance */
mrb = mrb_open();
@@ -361,13 +363,15 @@ main(int argc, char **argv)
}
else {
/* generate bytecode */
- n = mrb_generate_code(mrb, parser);
+ struct RProc *proc = mrb_generate_code(mrb, parser);
+ /* pass a proc for evaulation */
+ nregs = first_command ? 0: proc->body.irep->nregs;
/* evaluate the bytecode */
- result = mrb_run(mrb,
- /* pass a proc for evaulation */
- mrb_proc_new(mrb, mrb->irep[n]),
- mrb_top_self(mrb));
+ result = mrb_context_run(mrb,
+ proc,
+ mrb_top_self(mrb),
+ nregs);
/* did an exception occur? */
if (mrb->exc) {
p(mrb, mrb_obj_value(mrb->exc), 0);
@@ -387,6 +391,7 @@ main(int argc, char **argv)
}
mrb_parser_free(parser);
cxt->lineno++;
+ first_command = 0;
}
mrbc_context_free(mrb, cxt);
mrb_close(mrb);
diff --git a/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c b/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c
index baeb95993..290f9e25d 100644
--- a/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c
+++ b/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c
@@ -203,7 +203,7 @@ main(int argc, char **argv)
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));
+ mrb_context_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb), 0);
n = 0;
if (mrb->exc) {
mrb_print_error(mrb);
diff --git a/mrbgems/mruby-fiber/src/fiber.c b/mrbgems/mruby-fiber/src/fiber.c
index c764b4786..757eb235d 100644
--- a/mrbgems/mruby-fiber/src/fiber.c
+++ b/mrbgems/mruby-fiber/src/fiber.c
@@ -232,6 +232,26 @@ fiber_yield(mrb_state *mrb, mrb_value self)
return fiber_result(mrb, a, len);
}
+/*
+ * call-seq:
+ * Fiber.current() -> fiber
+ *
+ * Returns the current fiber. You need to <code>require 'fiber'</code>
+ * before using this method. If you are not running in the context of
+ * a fiber this method will return the root fiber.
+ */
+static mrb_value
+fiber_current(mrb_state *mrb, mrb_value self)
+{
+ if (!mrb->c->fib) {
+ struct RFiber *f = (struct RFiber*)mrb_obj_alloc(mrb, MRB_TT_FIBER, mrb_class_ptr(self));
+
+ f->cxt = mrb->c;
+ mrb->c->fib = f;
+ }
+ return mrb_obj_value(mrb->c->fib);
+}
+
void
mrb_mruby_fiber_gem_init(mrb_state* mrb)
{
@@ -245,6 +265,7 @@ mrb_mruby_fiber_gem_init(mrb_state* mrb)
mrb_define_method(mrb, c, "alive?", fiber_alive_p, MRB_ARGS_NONE());
mrb_define_class_method(mrb, c, "yield", fiber_yield, MRB_ARGS_ANY());
+ mrb_define_class_method(mrb, c, "current", fiber_current, MRB_ARGS_NONE());
}
void
diff --git a/mrbgems/mruby-random/src/random.c b/mrbgems/mruby-random/src/random.c
index 47977b393..d3f244910 100644
--- a/mrbgems/mruby-random/src/random.c
+++ b/mrbgems/mruby-random/src/random.c
@@ -6,6 +6,7 @@
#include "mruby.h"
#include "mruby/variable.h"
+#include "mruby/class.h"
#include "mruby/data.h"
#include "mruby/array.h"
#include "mt19937ar.h"
@@ -19,23 +20,11 @@
#define INSTANCE_RAND_SEED_KEY_CSTR_LEN 16
#define MT_STATE_KEY "$mrb_i_mt_state"
-#define MT_STATE_KEY_CSTR_LEN 15
static const struct mrb_data_type mt_state_type = {
MT_STATE_KEY, mrb_free,
};
-static mt_state *mrb_mt_get_context(mrb_state *mrb, mrb_value self)
-{
- mt_state *t;
- mrb_value context;
-
- context = mrb_iv_get(mrb, self, mrb_intern2(mrb, MT_STATE_KEY, MT_STATE_KEY_CSTR_LEN));
- t = DATA_GET_PTR(mrb, context, &mt_state_type, mt_state);
-
- return t;
-}
-
static void mt_g_srand(unsigned long seed)
{
init_genrand(seed);
@@ -51,7 +40,8 @@ static double mt_g_rand_real()
return genrand_real1();
}
-static mrb_value mrb_random_mt_g_srand(mrb_state *mrb, mrb_value seed)
+static mrb_value
+mrb_random_mt_g_srand(mrb_state *mrb, mrb_value seed)
{
if (mrb_nil_p(seed)) {
seed = mrb_fixnum_value(time(NULL) + mt_g_rand());
@@ -65,35 +55,41 @@ static mrb_value mrb_random_mt_g_srand(mrb_state *mrb, mrb_value seed)
return seed;
}
-static mrb_value mrb_random_mt_g_rand(mrb_state *mrb, mrb_value max)
+static mrb_value
+mrb_random_mt_g_rand(mrb_state *mrb, mrb_value max)
{
mrb_value value;
if (mrb_fixnum(max) == 0) {
value = mrb_float_value(mrb, mt_g_rand_real());
- } else {
+ }
+ else {
value = mrb_fixnum_value(mt_g_rand() % mrb_fixnum(max));
}
return value;
}
-static void mt_srand(mt_state *t, unsigned long seed)
+static void
+mt_srand(mt_state *t, unsigned long seed)
{
mrb_random_init_genrand(t, seed);
}
-static unsigned long mt_rand(mt_state *t)
+static unsigned long
+mt_rand(mt_state *t)
{
return mrb_random_genrand_int32(t);
}
-static double mt_rand_real(mt_state *t)
+static double
+mt_rand_real(mt_state *t)
{
return mrb_random_genrand_real1(t);
}
-static mrb_value mrb_random_mt_srand(mrb_state *mrb, mt_state *t, mrb_value seed)
+static mrb_value
+mrb_random_mt_srand(mrb_state *mrb, mt_state *t, mrb_value seed)
{
if (mrb_nil_p(seed)) {
seed = mrb_fixnum_value(time(NULL) + mt_rand(t));
@@ -107,20 +103,23 @@ static mrb_value mrb_random_mt_srand(mrb_state *mrb, mt_state *t, mrb_value seed
return seed;
}
-static mrb_value mrb_random_mt_rand(mrb_state *mrb, mt_state *t, mrb_value max)
+static mrb_value
+mrb_random_mt_rand(mrb_state *mrb, mt_state *t, mrb_value max)
{
mrb_value value;
if (mrb_fixnum(max) == 0) {
value = mrb_float_value(mrb, mt_rand_real(t));
- } else {
+ }
+ else {
value = mrb_fixnum_value(mt_rand(t) % mrb_fixnum(max));
}
return value;
}
-static mrb_value get_opt(mrb_state* mrb)
+static mrb_value
+get_opt(mrb_state* mrb)
{
mrb_value arg;
@@ -139,20 +138,29 @@ static mrb_value get_opt(mrb_state* mrb)
return arg;
}
-static mrb_value mrb_random_g_rand(mrb_state *mrb, mrb_value self)
+static void
+mrb_random_g_rand_seed(mrb_state *mrb)
{
- mrb_value max;
mrb_value seed;
-
- max = get_opt(mrb);
+
seed = mrb_gv_get(mrb, mrb_intern2(mrb, GLOBAL_RAND_SEED_KEY, GLOBAL_RAND_SEED_KEY_CSTR_LEN));
if (mrb_nil_p(seed)) {
mrb_random_mt_g_srand(mrb, mrb_nil_value());
}
+}
+
+static mrb_value
+mrb_random_g_rand(mrb_state *mrb, mrb_value self)
+{
+ mrb_value max;
+
+ max = get_opt(mrb);
+ mrb_random_g_rand_seed(mrb);
return mrb_random_mt_g_rand(mrb, max);
}
-static mrb_value mrb_random_g_srand(mrb_state *mrb, mrb_value self)
+static mrb_value
+mrb_random_g_srand(mrb_state *mrb, mrb_value self)
{
mrb_value seed;
mrb_value old_seed;
@@ -164,41 +172,62 @@ static mrb_value mrb_random_g_srand(mrb_state *mrb, mrb_value self)
return old_seed;
}
-static mrb_value mrb_random_init(mrb_state *mrb, mrb_value self)
+static mrb_value
+mrb_random_init(mrb_state *mrb, mrb_value self)
{
mrb_value seed;
+ mt_state *t;
+
+ DATA_TYPE(self) = &mt_state_type;
+ DATA_PTR(self) = NULL;
+
+ /* avoid memory leaks */
+ t = (mt_state*)DATA_PTR(self);
+ if (t) {
+ mrb_free(mrb, t);
+ }
-
- mt_state *t = (mt_state *)mrb_malloc(mrb, sizeof(mt_state));
+ t = (mt_state *)mrb_malloc(mrb, sizeof(mt_state));
t->mti = N + 1;
seed = get_opt(mrb);
seed = mrb_random_mt_srand(mrb, t, seed);
mrb_iv_set(mrb, self, mrb_intern2(mrb, INSTANCE_RAND_SEED_KEY, INSTANCE_RAND_SEED_KEY_CSTR_LEN), seed);
- mrb_iv_set(mrb, self, mrb_intern2(mrb, MT_STATE_KEY, MT_STATE_KEY_CSTR_LEN),
- mrb_obj_value(Data_Wrap_Struct(mrb, mrb->object_class, &mt_state_type, (void*) t)));
+
+ DATA_PTR(self) = t;
+
return self;
}
-static mrb_value mrb_random_rand(mrb_state *mrb, mrb_value self)
+static void
+mrb_random_rand_seed(mrb_state *mrb, mrb_value self)
{
- mrb_value max;
mrb_value seed;
- mt_state *t = mrb_mt_get_context(mrb, self);
-
- max = get_opt(mrb);
+ mt_state *t = DATA_PTR(self);
+
seed = mrb_iv_get(mrb, self, mrb_intern2(mrb, INSTANCE_RAND_SEED_KEY, INSTANCE_RAND_SEED_KEY_CSTR_LEN));
if (mrb_nil_p(seed)) {
mrb_random_mt_srand(mrb, t, mrb_nil_value());
}
+}
+
+static mrb_value
+mrb_random_rand(mrb_state *mrb, mrb_value self)
+{
+ mrb_value max;
+ mt_state *t = DATA_PTR(self);
+
+ max = get_opt(mrb);
+ mrb_random_rand_seed(mrb, self);
return mrb_random_mt_rand(mrb, t, max);
}
-static mrb_value mrb_random_srand(mrb_state *mrb, mrb_value self)
+static mrb_value
+mrb_random_srand(mrb_state *mrb, mrb_value self)
{
mrb_value seed;
mrb_value old_seed;
- mt_state *t = mrb_mt_get_context(mrb, self);
+ mt_state *t = DATA_PTR(self);
seed = get_opt(mrb);
seed = mrb_random_mt_srand(mrb, t, seed);
@@ -219,17 +248,31 @@ static mrb_value
mrb_ary_shuffle_bang(mrb_state *mrb, mrb_value ary)
{
mrb_int i;
- mrb_value seed;
-
- seed = mrb_gv_get(mrb, mrb_intern2(mrb, GLOBAL_RAND_SEED_KEY, GLOBAL_RAND_SEED_KEY_CSTR_LEN));
- if (mrb_nil_p(seed)) {
- mrb_random_mt_g_srand(mrb, mrb_nil_value());
- }
+ mrb_value random = mrb_nil_value();
if (RARRAY_LEN(ary) > 1) {
+ mrb_get_args(mrb, "|o", &random);
+
+ if (mrb_nil_p(random)) {
+ mrb_random_g_rand_seed(mrb);
+ }
+ else {
+ mrb_data_check_type(mrb, random, &mt_state_type);
+ mrb_random_rand_seed(mrb, random);
+ }
+
mrb_ary_modify(mrb, mrb_ary_ptr(ary));
+
for (i = RARRAY_LEN(ary) - 1; i > 0; i--) {
- mrb_int j = mrb_fixnum(mrb_random_mt_g_rand(mrb, mrb_fixnum_value(RARRAY_LEN(ary))));
+ mrb_int j;
+
+ if (mrb_nil_p(random)) {
+ j = mrb_fixnum(mrb_random_mt_g_rand(mrb, mrb_fixnum_value(RARRAY_LEN(ary))));
+ }
+ else {
+ j = mrb_fixnum(mrb_random_mt_rand(mrb, DATA_PTR(random), mrb_fixnum_value(RARRAY_LEN(ary))));
+ }
+
mrb_value t = RARRAY_PTR(ary)[i];
RARRAY_PTR(ary)[i] = RARRAY_PTR(ary)[j];
RARRAY_PTR(ary)[j] = t;
@@ -264,6 +307,7 @@ void mrb_mruby_random_gem_init(mrb_state *mrb)
mrb_define_method(mrb, mrb->kernel_module, "srand", mrb_random_g_srand, MRB_ARGS_OPT(1));
random = mrb_define_class(mrb, "Random", mrb->object_class);
+ MRB_SET_INSTANCE_TT(random, MRB_TT_DATA);
mrb_define_class_method(mrb, random, "rand", mrb_random_g_rand, MRB_ARGS_OPT(1));
mrb_define_class_method(mrb, random, "srand", mrb_random_g_srand, MRB_ARGS_OPT(1));
@@ -271,8 +315,8 @@ void mrb_mruby_random_gem_init(mrb_state *mrb)
mrb_define_method(mrb, random, "rand", mrb_random_rand, MRB_ARGS_OPT(1));
mrb_define_method(mrb, random, "srand", mrb_random_srand, MRB_ARGS_OPT(1));
- mrb_define_method(mrb, array, "shuffle", mrb_ary_shuffle, MRB_ARGS_NONE());
- mrb_define_method(mrb, array, "shuffle!", mrb_ary_shuffle_bang, MRB_ARGS_NONE());
+ mrb_define_method(mrb, array, "shuffle", mrb_ary_shuffle, MRB_ARGS_OPT(1));
+ mrb_define_method(mrb, array, "shuffle!", mrb_ary_shuffle_bang, MRB_ARGS_OPT(1));
}
void mrb_mruby_random_gem_final(mrb_state *mrb)
diff --git a/mrbgems/mruby-random/test/random.rb b/mrbgems/mruby-random/test/random.rb
index b35acaafd..c4e4082ad 100644
--- a/mrbgems/mruby-random/test/random.rb
+++ b/mrbgems/mruby-random/test/random.rb
@@ -43,4 +43,34 @@ assert('Array#shuffle!') do
ary.shuffle!
ary != [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and 10.times { |x| ary.include? x }
+end
+
+assert("Array#shuffle(random)") do
+ assert_raise(TypeError) do
+ # this will cause an exception due to the wrong argument
+ [1, 2].shuffle "Not a Random instance"
+ end
+
+ # verify that the same seed causes the same results
+ ary1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+ shuffle1 = ary1.shuffle Random.new 345
+ ary2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+ shuffle2 = ary2.shuffle Random.new 345
+
+ ary1 != shuffle1 and 10.times { |x| shuffle1.include? x } and shuffle1 == shuffle2
+end
+
+assert('Array#shuffle!(random)') do
+ assert_raise(TypeError) do
+ # this will cause an exception due to the wrong argument
+ [1, 2].shuffle! "Not a Random instance"
+ end
+
+ # verify that the same seed causes the same results
+ ary1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+ ary1.shuffle! Random.new 345
+ ary2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+ ary2.shuffle! Random.new 345
+
+ ary1 != [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and 10.times { |x| ary1.include? x } and ary1 == ary2
end \ No newline at end of file
diff --git a/src/codegen.c b/src/codegen.c
index 578fb96ac..548d8d8f8 100644
--- a/src/codegen.c
+++ b/src/codegen.c
@@ -9,7 +9,7 @@
#include <string.h>
#include "mruby.h"
#include "mruby/compile.h"
-#include "mruby/irep.h"
+#include "mruby/proc.h"
#include "mruby/numeric.h"
#include "mruby/string.h"
#include "mruby/debug.h"
@@ -67,8 +67,6 @@ typedef struct scope {
int nregs;
int ai;
- int idx;
-
int debug_start_pos;
uint16_t filename_index;
parser_state* parser;
@@ -500,7 +498,7 @@ static void
for_body(codegen_scope *s, node *tree)
{
codegen_scope *prev = s;
- int idx, base = s->idx;
+ int idx, base = s->irep->idx;
struct loopinfo *lp;
node *n2;
mrb_code c;
@@ -509,7 +507,7 @@ for_body(codegen_scope *s, node *tree)
codegen(s, tree->cdr->car, VAL);
// generate loop-block
s = scope_new(s->mrb, s, tree->car);
- idx = s->idx;
+ idx = s->irep->idx;
lp = loop_push(s, LOOP_FOR);
lp->pc1 = new_label(s);
@@ -543,11 +541,11 @@ for_body(codegen_scope *s, node *tree)
static int
lambda_body(codegen_scope *s, node *tree, int blk)
{
- int idx, base = s->idx;
+ int idx, base = s->irep->idx;
mrb_code c;
s = scope_new(s->mrb, s, tree->car);
- idx = s->idx;
+ idx = s->irep->idx;
s->mscope = !blk;
if (blk) {
@@ -634,7 +632,7 @@ static int
scope_body(codegen_scope *s, node *tree)
{
codegen_scope *scope = scope_new(s->mrb, s, tree->car);
- int idx = scope->idx;
+ int idx = scope->irep->idx;
codegen(scope, tree->cdr, VAL);
if (!s->iseq) {
@@ -652,8 +650,9 @@ scope_body(codegen_scope *s, node *tree)
}
}
scope_finish(scope);
-
- return idx - s->idx;
+ if (s->irep)
+ return idx - s->irep->idx;
+ return 0;
}
static mrb_bool
@@ -2361,7 +2360,6 @@ scope_new(mrb_state *mrb, codegen_scope *prev, node *lv)
p->mscope = 0;
p->irep = mrb_add_irep(mrb);
- p->idx = p->irep->idx;
p->icapa = 1024;
p->iseq = (mrb_code*)mrb_malloc(mrb, sizeof(mrb_code)*p->icapa);
@@ -2509,16 +2507,15 @@ loop_pop(codegen_scope *s, int val)
}
static void
-codedump(mrb_state *mrb, int n)
+codedump(mrb_state *mrb, mrb_irep *irep)
{
#ifdef ENABLE_STDIO
- mrb_irep *irep = mrb->irep[n];
uint32_t i;
int ai;
mrb_code c;
if (!irep) return;
- printf("irep %d nregs=%d nlocals=%d pools=%d syms=%d\n", n,
+ printf("irep %d nregs=%d nlocals=%d pools=%d syms=%d\n", irep->idx,
irep->nregs, irep->nlocals, (int)irep->plen, (int)irep->slen);
for (i=0; i<irep->ilen; i++) {
ai = mrb_gc_arena_save(mrb);
@@ -2787,7 +2784,7 @@ codedump(mrb_state *mrb, int n)
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]));
break;
case OP_EXEC:
- printf("OP_EXEC\tR%d\tI(%d)\n", GETARG_A(c), n+GETARG_Bx(c));
+ printf("OP_EXEC\tR%d\tI(%d)\n", GETARG_A(c), irep->idx+GETARG_Bx(c));
break;
case OP_SCLASS:
printf("OP_SCLASS\tR%d\tR%d\n", GETARG_A(c), GETARG_B(c));
@@ -2799,7 +2796,7 @@ codedump(mrb_state *mrb, int n)
printf("OP_ERR\tL(%d)\n", GETARG_Bx(c));
break;
case OP_EPUSH:
- printf("OP_EPUSH\t:I(%d)\n", n+GETARG_Bx(c));
+ printf("OP_EPUSH\t:I(%d)\n", irep->idx+GETARG_Bx(c));
break;
case OP_ONERR:
printf("OP_ONERR\t%03d\n", i+GETARG_sBx(c));
@@ -2829,14 +2826,16 @@ codedump(mrb_state *mrb, int n)
}
void
-codedump_all(mrb_state *mrb, int start)
+codedump_all(mrb_state *mrb, struct RProc *proc)
{
size_t i;
+ mrb_irep *irep = proc->body.irep;
- for (i=start; i<mrb->irep_len; i++) {
- codedump(mrb, i);
+ for (i=irep->idx; i<mrb->irep_len; i++) {
+ codedump(mrb, mrb->irep[i]);
}
}
+
static int
codegen_start(mrb_state *mrb, parser_state *p)
{
@@ -2860,14 +2859,13 @@ codegen_start(mrb_state *mrb, parser_state *p)
}
}
-int
+struct RProc*
mrb_generate_code(mrb_state *mrb, parser_state *p)
{
int start = mrb->irep_len;
int n;
n = codegen_start(mrb, p);
- if (n < 0) return n;
-
- return start;
+ if (n < 0) return NULL;
+ return mrb_proc_new(mrb, mrb->irep[start]);
}
diff --git a/src/gc.c b/src/gc.c
index 361024af3..ccd925da8 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -619,7 +619,8 @@ obj_free(mrb_state *mrb, struct RBasic *obj)
{
struct mrb_context *c = ((struct RFiber*)obj)->cxt;
- mrb_free_context(mrb, c);
+ if (c != mrb->root_c)
+ mrb_free_context(mrb, c);
}
break;
diff --git a/src/load.c b/src/load.c
index e2f74d504..d6397d652 100644
--- a/src/load.c
+++ b/src/load.c
@@ -510,7 +510,7 @@ mrb_load_irep(mrb_state *mrb, const uint8_t *bin)
irep_error(mrb, n);
return mrb_nil_value();
}
- return mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb));
+ return mrb_context_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb), 0);
}
#ifdef ENABLE_STDIO
@@ -760,6 +760,6 @@ mrb_load_irep_file(mrb_state *mrb, FILE* fp)
irep_error(mrb, n);
return mrb_nil_value();
}
- return mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb));
+ return mrb_context_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb), 0);
}
#endif /* ENABLE_STDIO */
diff --git a/src/parse.y b/src/parse.y
index c382c633c..b60316cee 100644
--- a/src/parse.y
+++ b/src/parse.y
@@ -5161,7 +5161,7 @@ parser_update_cxt(parser_state *p, mrbc_context *cxt)
}
}
-void codedump_all(mrb_state*, int);
+void codedump_all(mrb_state*, struct RProc*);
void parser_dump(mrb_state *mrb, node *tree, int offset);
void
@@ -5352,7 +5352,6 @@ load_exec(mrb_state *mrb, parser_state *p, mrbc_context *c)
{
struct RClass *target = mrb->object_class;
struct RProc *proc;
- int n;
mrb_value v;
if (!p) {
@@ -5361,6 +5360,7 @@ load_exec(mrb_state *mrb, parser_state *p, mrbc_context *c)
if (!p->tree || p->nerr) {
if (p->capture_errors) {
char buf[256];
+ int n;
n = snprintf(buf, sizeof(buf), "line %d: %s\n",
p->error_buffer[0].lineno, p->error_buffer[0].message);
@@ -5375,26 +5375,25 @@ load_exec(mrb_state *mrb, parser_state *p, mrbc_context *c)
return mrb_undef_value();
}
}
- n = mrb_generate_code(mrb, p);
+ proc = mrb_generate_code(mrb, p);
mrb_parser_free(p);
- if (n < 0) {
+ if (proc == NULL) {
static const char msg[] = "codegen error";
mrb->exc = mrb_obj_ptr(mrb_exc_new(mrb, E_SCRIPT_ERROR, msg, sizeof(msg) - 1));
return mrb_nil_value();
}
if (c) {
- if (c->dump_result) codedump_all(mrb, n);
- if (c->no_exec) return mrb_fixnum_value(n);
+ if (c->dump_result) codedump_all(mrb, proc);
+ if (c->no_exec) return mrb_fixnum_value(0);
if (c->target_class) {
target = c->target_class;
}
}
- proc = mrb_proc_new(mrb, mrb->irep[n]);
proc->target_class = target;
if (mrb->c->ci) {
mrb->c->ci->target_class = target;
}
- v = mrb_run(mrb, proc, mrb_top_self(mrb));
+ v = mrb_context_run(mrb, proc, mrb_top_self(mrb), 0);
if (mrb->exc) return mrb_nil_value();
return v;
}
diff --git a/src/vm.c b/src/vm.c
index 1099db8a1..d35ab59f2 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -547,7 +547,7 @@ void mrb_gv_val_set(mrb_state *mrb, mrb_sym sym, mrb_value val);
#define CALL_MAXARGS 127
mrb_value
-mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
+mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep)
{
/* mrb_assert(mrb_proc_cfunc_p(proc)) */
mrb_irep *irep = proc->body.irep;
@@ -595,7 +595,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
if (!mrb->c->stack) {
stack_init(mrb);
}
- stack_extend(mrb, irep->nregs, mrb->c->ci->argc + 2); /* argc + 2 (receiver and block) */
+ stack_extend(mrb, irep->nregs, stack_keep);
mrb->c->ci->err = pc;
mrb->c->ci->proc = proc;
mrb->c->ci->nregs = irep->nregs + 1;
@@ -2145,6 +2145,12 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
END_DISPATCH;
}
+mrb_value
+mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
+{
+ return mrb_context_run(mrb, proc, self, mrb->c->ci->argc + 2); /* argc + 2 (receiver and block) */
+}
+
void
mrb_longjmp(mrb_state *mrb)
{
diff --git a/tools/mrbc/mrbc.c b/tools/mrbc/mrbc.c
index 8ba424fd4..e985dcdd3 100644
--- a/tools/mrbc/mrbc.c
+++ b/tools/mrbc/mrbc.c
@@ -274,7 +274,7 @@ main(int argc, char **argv)
return EXIT_FAILURE;
}
if (args.check_syntax) {
- printf("%s:%s:Syntax OK", args.prog, argv[n]);
+ printf("%s:%s:Syntax OK\n", args.prog, argv[n]);
}
if (args.check_syntax) {