summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/mruby/compile.h2
-rw-r--r--mrbgems/mruby-compiler/core/codegen.c28
-rw-r--r--mrbgems/mruby-compiler/core/parse.y9
-rw-r--r--src/gc.c30
-rw-r--r--src/numeric.c4
-rw-r--r--src/string.c8
-rw-r--r--test/t/codegen.rb28
7 files changed, 81 insertions, 28 deletions
diff --git a/include/mruby/compile.h b/include/mruby/compile.h
index 3ccaf9f6a..ad3f19db1 100644
--- a/include/mruby/compile.h
+++ b/include/mruby/compile.h
@@ -163,6 +163,7 @@ struct mrb_parser_state {
MRB_API struct mrb_parser_state* mrb_parser_new(mrb_state*);
MRB_API void mrb_parser_free(struct mrb_parser_state*);
MRB_API void mrb_parser_parse(struct mrb_parser_state*,mrbc_context*);
+MRB_API double mrb_float_read(const char*, char**);
MRB_API void mrb_parser_set_filename(struct mrb_parser_state*, char const*);
MRB_API char const* mrb_parser_get_filename(struct mrb_parser_state*, uint16_t idx);
@@ -174,6 +175,7 @@ MRB_API struct mrb_parser_state* mrb_parse_file(mrb_state*,FILE*,mrbc_context*);
MRB_API struct mrb_parser_state* mrb_parse_string(mrb_state*,const char*,mrbc_context*);
MRB_API struct mrb_parser_state* mrb_parse_nstring(mrb_state*,const char*,int,mrbc_context*);
MRB_API struct RProc* mrb_generate_code(mrb_state*, struct mrb_parser_state*);
+MRB_API mrb_value mrb_load_exec(mrb_state *mrb, struct mrb_parser_state *p, mrbc_context *c);
/* program load functions */
#ifndef MRB_DISABLE_STDIO
diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c
index b2cd12225..38da952b4 100644
--- a/mrbgems/mruby-compiler/core/codegen.c
+++ b/mrbgems/mruby-compiler/core/codegen.c
@@ -818,8 +818,6 @@ gen_values(codegen_scope *s, node *t, int val)
}
}
else {
- codegen(s, t->car->cdr, NOVAL);
- t = t->cdr;
while (t) {
codegen(s, t->car, NOVAL);
t = t->cdr;
@@ -2223,6 +2221,10 @@ codegen(codegen_scope *s, node *tree, int val)
{
nt = (intptr_t)tree->car;
tree = tree->cdr;
+ if (!val) {
+ codegen(s, tree, NOVAL);
+ break;
+ }
switch (nt) {
case NODE_FLOAT:
{
@@ -2560,13 +2562,31 @@ codegen(codegen_scope *s, node *tree, int val)
genop(s, MKOP_A(OP_TCLASS, cursp()));
push();
while (t) {
- int symbol = new_msym(s, sym(t->car));
+ int symbol;
+ if (num >= CALL_MAXARGS - 1) {
+ pop_n(num);
+ genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), num));
+ while (t) {
+ symbol = new_msym(s, sym(t->car));
+ push();
+ genop(s, MKOP_ABx(OP_LOADSYM, cursp(), symbol));
+ pop();
+ genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1));
+ t = t->cdr;
+ }
+ num = CALL_MAXARGS;
+ break;
+ }
+ symbol = new_msym(s, sym(t->car));
genop(s, MKOP_ABx(OP_LOADSYM, cursp(), symbol));
push();
t = t->cdr;
num++;
}
- pop_n(num + 1);
+ pop();
+ if (num < CALL_MAXARGS) {
+ pop_n(num);
+ }
genop(s, MKOP_ABC(OP_SEND, cursp(), undef, num));
if (val) {
push();
diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y
index 05b948f8e..ee3373fbf 100644
--- a/mrbgems/mruby-compiler/core/parse.y
+++ b/mrbgems/mruby-compiler/core/parse.y
@@ -3946,6 +3946,7 @@ parse_string(parser_state *p)
}
}
if ((len-1 == hinf->term_len) && (strncmp(s, hinf->term, len-1) == 0)) {
+ if (c < 0) p->parsing_heredoc = NULL;
return tHEREDOC_END;
}
}
@@ -5692,8 +5693,8 @@ mrb_parse_string(mrb_state *mrb, const char *s, mrbc_context *c)
return mrb_parse_nstring(mrb, s, strlen(s), c);
}
-static mrb_value
-load_exec(mrb_state *mrb, parser_state *p, mrbc_context *c)
+MRB_API mrb_value
+mrb_load_exec(mrb_state *mrb, struct mrb_parser_state *p, mrbc_context *c)
{
struct RClass *target = mrb->object_class;
struct RProc *proc;
@@ -5752,7 +5753,7 @@ load_exec(mrb_state *mrb, parser_state *p, mrbc_context *c)
MRB_API mrb_value
mrb_load_file_cxt(mrb_state *mrb, FILE *f, mrbc_context *c)
{
- return load_exec(mrb, mrb_parse_file(mrb, f, c), c);
+ return mrb_load_exec(mrb, mrb_parse_file(mrb, f, c), c);
}
MRB_API mrb_value
@@ -5765,7 +5766,7 @@ mrb_load_file(mrb_state *mrb, FILE *f)
MRB_API mrb_value
mrb_load_nstring_cxt(mrb_state *mrb, const char *s, int len, mrbc_context *c)
{
- return load_exec(mrb, mrb_parse_nstring(mrb, s, len, c), c);
+ return mrb_load_exec(mrb, mrb_parse_nstring(mrb, s, len, c), c);
}
MRB_API mrb_value
diff --git a/src/gc.c b/src/gc.c
index 3e52b3433..c75a0f9aa 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -453,7 +453,7 @@ mrb_gc_unregister(mrb_state *mrb, mrb_value obj)
mrb_sym root = mrb_intern_lit(mrb, GC_ROOT_NAME);
mrb_value table = mrb_gv_get(mrb, root);
struct RArray *a;
- mrb_int i, len;
+ mrb_int i;
if (mrb_nil_p(table)) return;
if (mrb_type(table) != MRB_TT_ARRAY) {
@@ -462,14 +462,13 @@ mrb_gc_unregister(mrb_state *mrb, mrb_value obj)
}
a = mrb_ary_ptr(table);
mrb_ary_modify(mrb, a);
- len = a->len-1;
- for (i=0; i<len; i++) {
+ for (i = 0; i < a->len; i++) {
if (mrb_obj_eq(mrb, a->ptr[i], obj)) {
- memmove(&a->ptr[i], &a->ptr[i+1], len-i);
+ a->len--;
+ memmove(&a->ptr[i], &a->ptr[i + 1], (a->len - i) * sizeof(a->ptr[i]));
break;
}
}
- a->len--;
}
MRB_API struct RBasic*
@@ -742,10 +741,12 @@ obj_free(mrb_state *mrb, struct RBasic *obj)
{
struct REnv *e = (struct REnv*)obj;
- if (!MRB_ENV_STACK_SHARED_P(e)) {
- mrb_free(mrb, e->stack);
- e->stack = NULL;
+ if (MRB_ENV_STACK_SHARED_P(e)) {
+ /* cannot be freed */
+ return;
}
+ mrb_free(mrb, e->stack);
+ e->stack = NULL;
}
break;
@@ -1019,15 +1020,20 @@ incremental_sweep_phase(mrb_state *mrb, mrb_gc *gc, size_t limit)
if (is_dead(gc, &p->as.basic)) {
if (p->as.basic.tt != MRB_TT_FREE) {
obj_free(mrb, &p->as.basic);
- p->as.free.next = page->freelist;
- page->freelist = (struct RBasic*)p;
- freed++;
+ if (p->as.basic.tt == MRB_TT_FREE) {
+ p->as.free.next = page->freelist;
+ page->freelist = (struct RBasic*)p;
+ freed++;
+ }
+ else {
+ dead_slot = FALSE;
+ }
}
}
else {
if (!is_generational(gc))
paint_partial_white(gc, &p->as.basic); /* next gc target */
- dead_slot = 0;
+ dead_slot = FALSE;
}
p++;
}
diff --git a/src/numeric.c b/src/numeric.c
index 25a411de8..a9a2a641b 100644
--- a/src/numeric.c
+++ b/src/numeric.c
@@ -357,7 +357,11 @@ flo_shift(mrb_state *mrb, mrb_value x, mrb_int width)
while (width++) {
val /= 2;
}
+#if defined(_ISOC99_SOURCE)
val = trunc(val);
+#else
+ val = val > 0 ? floor(val) : ceil(val);
+#endif
if (val == 0 && mrb_float(x) < 0) {
return mrb_fixnum_value(-1);
}
diff --git a/src/string.c b/src/string.c
index a9351619b..a4f8085ec 100644
--- a/src/string.c
+++ b/src/string.c
@@ -2770,14 +2770,6 @@ mrb_init_string(mrb_state *mrb)
#include <ctype.h>
#include <errno.h>
-#ifndef __STDC__
-# ifdef __GNUC__
-# define const __const__
-# else
-# define const
-# endif
-#endif
-
static const int maxExponent = 511; /* Largest possible base 10 exponent. Any
* exponent larger than this will already
* produce underflow or overflow, so there's
diff --git a/test/t/codegen.rb b/test/t/codegen.rb
index bb0f5c306..709902741 100644
--- a/test/t/codegen.rb
+++ b/test/t/codegen.rb
@@ -63,3 +63,31 @@ assert('splat in case splat') do
assert_equal [1], a
end
+
+assert('undef with 127 or more arguments') do
+ assert_raise NameError do
+ undef
+ a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a,
+ a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a,
+ a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a,
+ a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a
+ end
+end
+
+assert('next in normal loop with 127 arguments') do
+ assert_raise NameError do
+ while true
+ next A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A
+ end
+ end
+end
+
+assert('negate literal register alignment') do
+ a = *case
+ when 0
+ -0.0
+ 2
+ end
+
+ assert_equal [2], a
+end