Fixed register windows of OP_SENDs generated by NODE_{DREGX,REGX}; ref
MODIFY
mrbgems/mruby-compiler/core/codegen.c
mrbgems/mruby-compiler/core/codegen.c
@@ -2450,26 +2450,26 @@ codegen(codegen_scope *s, node *tree, int val)
genop(s, MKOP_ABx(OP_GETMCNST, cursp(), sym));
push();
genop(s, MKOP_ABx(OP_STRING, cursp(), off));
- if (p2 || p3) {
push();
- if (p2) {
+ if (p2 || p3) {
+ if (p2) { /* opt */
off = new_lit(s, mrb_str_new_cstr(s->mrb, p2));
genop(s, MKOP_ABx(OP_STRING, cursp(), off));
}
else {
genop(s, MKOP_A(OP_LOADNIL, cursp()));
}
- argc++;
- if (p3) {
push();
+ argc++;
+ if (p3) { /* enc */
off = new_lit(s, mrb_str_new(s->mrb, p3, 1));
genop(s, MKOP_ABx(OP_STRING, cursp(), off));
+ push();
argc++;
- pop();
}
- pop();
}
- pop();
+ push(); /* space for a block */
+ pop_n(argc+2);
sym = new_sym(s, mrb_intern_lit(s->mrb, "compile"));
genop(s, MKOP_ABC(OP_SEND, cursp(), sym, argc));
mrb_gc_arena_restore(s->mrb, ai);
@@ -2499,31 +2499,31 @@ codegen(codegen_scope *s, node *tree, int val)
n = n->cdr;
}
n = tree->cdr->cdr;
- if (n->car) {
+ if (n->car) { /* tail */
p = (char*)n->car;
off = new_lit(s, mrb_str_new_cstr(s->mrb, p));
codegen(s, tree->car, VAL);
genop(s, MKOP_ABx(OP_STRING, cursp(), off));
pop();
genop_peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL);
+ push();
}
- if (n->cdr->car) {
+ if (n->cdr->car) { /* opt */
char *p2 = (char*)n->cdr->car;
-
- push();
off = new_lit(s, mrb_str_new_cstr(s->mrb, p2));
genop(s, MKOP_ABx(OP_STRING, cursp(), off));
+ push();
argc++;
}
- if (n->cdr->cdr) {
+ if (n->cdr->cdr) { /* enc */
char *p2 = (char*)n->cdr->cdr;
-
- push();
off = new_lit(s, mrb_str_new_cstr(s->mrb, p2));
genop(s, MKOP_ABx(OP_STRING, cursp(), off));
+ push();
argc++;
}
- pop_n(argc);
+ push(); /* space for a block */
+ pop_n(argc+2);
sym = new_sym(s, mrb_intern_lit(s->mrb, "compile"));
genop(s, MKOP_ABC(OP_SEND, cursp(), sym, argc));
mrb_gc_arena_restore(s->mrb, ai);

MODIFY
test/t/codegen.rb
test/t/codegen.rb
@@ -171,6 +171,16 @@ assert('register window of calls (#3783)') do
# NODE_XSTR
assert_raise(NotImplementedError){ `static` }
+ # NODE_DREGX
+ class Regexp; end
+ assert_raise(NoMethodError){ /#{'dynamic'}tail/ }
+ assert_raise(NoMethodError){ /#{'dynamic'}tail/iu }
+
+ # NODE_REGX
+ assert_raise(NoMethodError){ /static/ }
+ assert_raise(NoMethodError){ /static/iu }
+ Object.remove_const :Regexp
+
# NODE_UNDEF
assert_nothing_raised do
class << Object.new

Fixed register windows of OP_SENDs generated by NODE_{DREGX,REGX}; ref #3783