yarv-diff:233
From: ko1 atdot.net
Date: 13 Feb 2006 12:24:09 -0000
Subject: [yarv-diff:233] r394 - trunk
Author: ko1
Date: 2006-02-13 21:24:09 +0900 (Mon, 13 Feb 2006)
New Revision: 394
Modified:
trunk/
trunk/ChangeLog
trunk/compile.c
trunk/test.rb
Log:
r580@leremita: ko1 | 2006-02-13 21:23:32 +0900
* compile.c : fix indent
* compile.c : fix to prohibit "redo" from eval expression
Property changes on: trunk
___________________________________________________________________
Name: svk:merge
- 81cd9672-7512-7e48-ae48-6936450e977d:/local/yarv/trunk:579
+ 81cd9672-7512-7e48-ae48-6936450e977d:/local/yarv/trunk:580
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2006-02-13 12:23:53 UTC (rev 393)
+++ trunk/ChangeLog 2006-02-13 12:24:09 UTC (rev 394)
@@ -4,6 +4,13 @@
# from Mon, 03 May 2004 01:24:19 +0900
#
+2006-02-13(Mon) 21:20:57 +0900 Koichi Sasada <ko1 atdot.net>
+
+ * compile.c : fix indent
+
+ * compile.c : fix to prohibit "redo" from eval expression
+
+
2006-02-13(Mon) 20:36:06 +0900 Koichi Sasada <ko1 atdot.net>
* vm.c : fix constant search bug ([yarv-dev:788])
Modified: trunk/compile.c
===================================================================
--- trunk/compile.c 2006-02-13 12:23:53 UTC (rev 393)
+++ trunk/compile.c 2006-02-13 12:24:09 UTC (rev 394)
@@ -2164,22 +2164,22 @@
LINK_ANCHOR *pref, LINK_ANCHOR *body)
{
switch (nd_type(node)) {
- case NODE_CONST:
+ case NODE_CONST:
debugi("compile_colon2 - colon", node->nd_vid);
ADD_INSN1(body, nd_line(node), getconstant, ID2SYM(node->nd_vid));
break;
- case NODE_COLON3:
+ case NODE_COLON3:
debugi("compile_colon2 - colon3", node->nd_mid);
ADD_INSN(body, nd_line(node), pop);
ADD_INSN1(body, nd_line(node), putobject, rb_cObject);
ADD_INSN1(body, nd_line(node), getconstant, ID2SYM(node->nd_mid));
break;
- case NODE_COLON2:
+ case NODE_COLON2:
compile_colon2(iseq, node->nd_head, pref, body);
debugi("compile_colon2 - colon2", node->nd_mid);
ADD_INSN1(body, nd_line(node), getconstant, ID2SYM(node->nd_mid));
break;
- default:
+ default:
COMPILE(pref, "const colon2 prefix", node);
break;
}
@@ -2195,55 +2195,55 @@
switch (nd_type(node)) {
/* easy literals */
- case NODE_NIL:
+ case NODE_NIL:
estr = "nil";
break;
- case NODE_SELF:
+ case NODE_SELF:
estr = "self";
break;
- case NODE_TRUE:
+ case NODE_TRUE:
estr = "true";
break;
- case NODE_FALSE:
+ case NODE_FALSE:
estr = "false";
break;
- case NODE_STR:
- case NODE_LIT:
+ case NODE_STR:
+ case NODE_LIT:
estr = "expression";
break;
/* variables */
- case NODE_LVAR:
+ case NODE_LVAR:
estr = "local-variable";
break;
- case NODE_DVAR:
+ case NODE_DVAR:
estr = "local-variable(in-block)";
break;
- case NODE_IVAR:
+ case NODE_IVAR:
ADD_INSN(ret, nd_line(node), putnil);
ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_IVAR),
ID2SYM(node->nd_vid), needstr);
return 1;
- case NODE_GVAR:
+ case NODE_GVAR:
ADD_INSN(ret, nd_line(node), putnil);
ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_GVAR),
((VALUE)node->nd_entry) | 1, needstr);
return 1;
- case NODE_CVAR:
+ case NODE_CVAR:
ADD_INSN(ret, nd_line(node), putnil);
ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_CVAR),
ID2SYM(node->nd_vid), needstr);
return 1;
- case NODE_CONST:
+ case NODE_CONST:
ADD_INSN(ret, nd_line(node), putnil);
ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_CONST),
ID2SYM(node->nd_vid), needstr);
return 1;
- case NODE_COLON2:
+ case NODE_COLON2:
if (rb_is_const_id(node->nd_mid)) {
LABEL *lcont = NEW_LABEL(nd_line(node));
defined_expr(iseq, ret, node->nd_head, lfinish, Qfalse);
@@ -2271,16 +2271,16 @@
ID2SYM(node->nd_mid), needstr);
}
return 1;
- case NODE_COLON3:
+ case NODE_COLON3:
ADD_INSN1(ret, nd_line(node), putobject, rb_cObject);
ADD_INSN3(ret, nd_line(node), defined,
INT2FIX(DEFINED_CONST), ID2SYM(node->nd_mid), needstr);
return 1;
/* method dispatch */
- case NODE_CALL:
- case NODE_VCALL:
- case NODE_FCALL:
+ case NODE_CALL:
+ case NODE_VCALL:
+ case NODE_FCALL:
if (nd_type(node) == NODE_CALL) {
LABEL *lcont = NEW_LABEL(nd_line(node));
@@ -2301,51 +2301,51 @@
}
return 1;
- case NODE_YIELD:
+ case NODE_YIELD:
ADD_INSN(ret, nd_line(node), putnil);
ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_YIELD), 0,
needstr);
return 1;
- case NODE_NTH_REF:
+ case NODE_NTH_REF:
ADD_INSN(ret, nd_line(node), putnil);
ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_REF), 0,
needstr);
return 1;
- case NODE_ZSUPER:
+ case NODE_ZSUPER:
ADD_INSN(ret, nd_line(node), putnil);
ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_ZSUPER), 0,
needstr);
return 1;
- default:{
- LABEL *lstart = NEW_LABEL(nd_line(node));
- LABEL *lend = NEW_LABEL(nd_line(node));
- LABEL *ldefed = NEW_LABEL(nd_line(node));
- VALUE str = rb_str_new2("expression");
- VALUE tmp;
- VALUE ensure = NEW_CHILD_ISEQVAL(NEW_NIL(),
- rb_str_concat(rb_str_new2
- ("defined guard in "),
- iseq->name),
- ISEQ_TYPE_DEFINED_GUARD);
+ default:{
+ LABEL *lstart = NEW_LABEL(nd_line(node));
+ LABEL *lend = NEW_LABEL(nd_line(node));
+ LABEL *ldefed = NEW_LABEL(nd_line(node));
+ VALUE str = rb_str_new2("expression");
+ VALUE tmp;
+ VALUE ensure = NEW_CHILD_ISEQVAL(NEW_NIL(),
+ rb_str_concat(rb_str_new2
+ ("defined guard in "),
+ iseq->name),
+ ISEQ_TYPE_DEFINED_GUARD);
- iseq_add_mark_object_compile_time(iseq, str);
+ iseq_add_mark_object_compile_time(iseq, str);
- ADD_LABEL(ret, lstart);
- COMPILE(ret, "defined expr (others)", node);
- ADD_INSNL(ret, nd_line(node), if, ldefed) ;
- ADD_INSN(ret, nd_line(node), putnil);
- ADD_INSNL(ret, nd_line(node), jump, lend);
- ADD_LABEL(ret, ldefed);
- ADD_INSN1(ret, nd_line(node), putobject, str);
- ADD_LABEL(ret, lend);
+ ADD_LABEL(ret, lstart);
+ COMPILE(ret, "defined expr (others)", node);
+ ADD_INSNL(ret, nd_line(node), if, ldefed) ;
+ ADD_INSN(ret, nd_line(node), putnil);
+ ADD_INSNL(ret, nd_line(node), jump, lend);
+ ADD_LABEL(ret, ldefed);
+ ADD_INSN1(ret, nd_line(node), putobject, str);
+ ADD_LABEL(ret, lend);
- ADD_CATCH_ENTRY(CATCH_TYPE_ENSURE, lstart, lend, ensure, lfinish);
- return 1;
- // rb_bug("unimplemented defined: %s", node_name(nd_type(node)));
- } /* end of default */
+ ADD_CATCH_ENTRY(CATCH_TYPE_ENSURE, lstart, lend, ensure, lfinish);
+ return 1;
+ // rb_bug("unimplemented defined: %s", node_name(nd_type(node)));
+ } /* end of default */
}
if (estr != 0) {
@@ -2473,728 +2473,737 @@
switch (type) {
- case NODE_METHOD:{
- /* OK */
- COMPILE_ERROR(("BUG: unknown node: NODE_METHOD"));
- break;
- }
- case NODE_FBODY:{
- /* OK */
- COMPILE_ERROR(("BUG: unknown node: NODE_FBODY"));
- break;
- }
- case NODE_CFUNC:{
- /* OK */
- COMPILE_ERROR(("BUG: unknown node: NODE_CFUNC"));
- break;
- }
- case NODE_SCOPE:{
- /* OK */
- COMPILE_ERROR(("BUG: shouldn't reach: NODE_SCOPE"));
- break;
- }
- case NODE_BLOCK:{
- while (node && nd_type(node) == NODE_BLOCK) {
- COMPILE_(ret, "BLOCK body", node->nd_head,
- (node->nd_next == 0 && poped == 0) ? 0 : 1);
- node = node->nd_next;
- }
- if (node) {
- COMPILE_(ret, "BLOCK next", node->nd_next, poped);
- }
- break;
- }
- case NODE_IF:{
- DECL_ANCHOR(cond_seq);
- DECL_ANCHOR(then_seq);
- DECL_ANCHOR(else_seq);
- LABEL *then_label, *else_label, *end_label;
+ case NODE_METHOD:{
+ /* OK */
+ COMPILE_ERROR(("BUG: unknown node: NODE_METHOD"));
+ break;
+ }
+ case NODE_FBODY:{
+ /* OK */
+ COMPILE_ERROR(("BUG: unknown node: NODE_FBODY"));
+ break;
+ }
+ case NODE_CFUNC:{
+ /* OK */
+ COMPILE_ERROR(("BUG: unknown node: NODE_CFUNC"));
+ break;
+ }
+ case NODE_SCOPE:{
+ /* OK */
+ COMPILE_ERROR(("BUG: shouldn't reach: NODE_SCOPE"));
+ break;
+ }
+ case NODE_BLOCK:{
+ while (node && nd_type(node) == NODE_BLOCK) {
+ COMPILE_(ret, "BLOCK body", node->nd_head,
+ (node->nd_next == 0 && poped == 0) ? 0 : 1);
+ node = node->nd_next;
+ }
+ if (node) {
+ COMPILE_(ret, "BLOCK next", node->nd_next, poped);
+ }
+ break;
+ }
+ case NODE_IF:{
+ DECL_ANCHOR(cond_seq);
+ DECL_ANCHOR(then_seq);
+ DECL_ANCHOR(else_seq);
+ LABEL *then_label, *else_label, *end_label;
- then_label = NEW_LABEL(nd_line(node));
- else_label = NEW_LABEL(nd_line(node));
- end_label = NEW_LABEL(nd_line(node));
+ then_label = NEW_LABEL(nd_line(node));
+ else_label = NEW_LABEL(nd_line(node));
+ end_label = NEW_LABEL(nd_line(node));
- compile_branch_condition(iseq, cond_seq, node->nd_cond,
- then_label, else_label);
- COMPILE_(then_seq, "then", node->nd_body, poped);
- COMPILE_(else_seq, "else", node->nd_else, poped);
+ compile_branch_condition(iseq, cond_seq, node->nd_cond,
+ then_label, else_label);
+ COMPILE_(then_seq, "then", node->nd_body, poped);
+ COMPILE_(else_seq, "else", node->nd_else, poped);
- ADD_SEQ(ret, cond_seq);
+ ADD_SEQ(ret, cond_seq);
- ADD_LABEL(ret, then_label);
- ADD_SEQ(ret, then_seq);
- ADD_INSNL(ret, nd_line(node), jump, end_label);
+ ADD_LABEL(ret, then_label);
+ ADD_SEQ(ret, then_seq);
+ ADD_INSNL(ret, nd_line(node), jump, end_label);
- ADD_LABEL(ret, else_label);
- ADD_SEQ(ret, else_seq);
+ ADD_LABEL(ret, else_label);
+ ADD_SEQ(ret, else_seq);
- ADD_LABEL(ret, end_label);
+ ADD_LABEL(ret, end_label);
- break;
- }
- case NODE_CASE:{
- NODE *vals;
- NODE *val;
- NODE *tempnode = node;
- LABEL *endlabel, *elselabel;
- DECL_ANCHOR(head);
- DECL_ANCHOR(body_seq);
- DECL_ANCHOR(cond_seq);
- VALUE special_literals = rb_ary_new();
+ break;
+ }
+ case NODE_CASE:{
+ NODE *vals;
+ NODE *val;
+ NODE *tempnode = node;
+ LABEL *endlabel, *elselabel;
+ DECL_ANCHOR(head);
+ DECL_ANCHOR(body_seq);
+ DECL_ANCHOR(cond_seq);
+ VALUE special_literals = rb_ary_new();
- COMPILE(head, "case base", node->nd_head);
+ COMPILE(head, "case base", node->nd_head);
- node = node->nd_body;
- type = nd_type(node);
+ node = node->nd_body;
+ type = nd_type(node);
- if (type != NODE_WHEN) {
- COMPILE_ERROR(("NODE_CASE: unexpected node. must be NODE_WHEN, but %s", node_name(type)));
- }
+ if (type != NODE_WHEN) {
+ COMPILE_ERROR(("NODE_CASE: unexpected node. must be NODE_WHEN, but %s", node_name(type)));
+ }
- endlabel = NEW_LABEL(nd_line(node));
- elselabel = NEW_LABEL(nd_line(node));
+ endlabel = NEW_LABEL(nd_line(node));
+ elselabel = NEW_LABEL(nd_line(node));
- ADD_SEQ(ret, head); /* case VAL */
+ ADD_SEQ(ret, head); /* case VAL */
- while (type == NODE_WHEN) {
- LABEL *l1;
+ while (type == NODE_WHEN) {
+ LABEL *l1;
- l1 = NEW_LABEL(nd_line(node));
- ADD_LABEL(body_seq, l1);
- ADD_INSN(body_seq, nd_line(node), pop);
- COMPILE_(body_seq, "when body", node->nd_body, poped);
- ADD_INSNL(body_seq, nd_line(node), jump, endlabel);
+ l1 = NEW_LABEL(nd_line(node));
+ ADD_LABEL(body_seq, l1);
+ ADD_INSN(body_seq, nd_line(node), pop);
+ COMPILE_(body_seq, "when body", node->nd_body, poped);
+ ADD_INSNL(body_seq, nd_line(node), jump, endlabel);
- vals = node->nd_head;
- if (vals && nd_type(vals) == NODE_ARRAY) {
- while (vals) {
- VALUE lit;
- val = vals->nd_head;
+ vals = node->nd_head;
+ if (vals && nd_type(vals) == NODE_ARRAY) {
+ while (vals) {
+ VALUE lit;
+ val = vals->nd_head;
- if ((lit = case_when_optimizable_literal(val))
- && special_literals) {
- rb_ary_push(special_literals,
- rb_ary_new3(2, lit, (VALUE)(l1) | 1));
- }
- else {
- special_literals = Qfalse;
- }
+ if ((lit = case_when_optimizable_literal(val))
+ && special_literals) {
+ rb_ary_push(special_literals,
+ rb_ary_new3(2, lit, (VALUE)(l1) | 1));
+ }
+ else {
+ special_literals = Qfalse;
+ }
- if (nd_type(val) == NODE_WHEN) { // && nd_type(val->nd_head) != NODE_ARRAY){
- COMPILE(cond_seq, "when/cond specail?",
- val->nd_head);
- ADD_INSN1(cond_seq, nd_line(node),
- checkincludearray, Qtrue);
- /* for stack caching */
- ADD_INSN(cond_seq, nd_line(node), putnil);
- ADD_INSN(cond_seq, nd_line(node), pop);
- }
- else {
- COMPILE(cond_seq, "when cond", val);
- ADD_INSN1(cond_seq, nd_line(node), topn,
- INT2FIX(1));
- ADD_SEND(cond_seq, nd_line(node), ID2SYM(idEqq),
- INT2FIX(1));
- }
- ADD_INSNL(cond_seq, nd_line(node), if, l1) ;
- vals = vals->nd_next;
- }
- }
- else {
- COMPILE_ERROR(("NODE_CASAE: must be NODE_ARRAY, but %s\n",
- node_name(nd_type(vals))));
- }
+ if (nd_type(val) == NODE_WHEN) { // && nd_type(val->nd_head) != NODE_ARRAY){
+ COMPILE(cond_seq, "when/cond specail?",
+ val->nd_head);
+ ADD_INSN1(cond_seq, nd_line(node),
+ checkincludearray, Qtrue);
+ /* for stack caching */
+ ADD_INSN(cond_seq, nd_line(node), putnil);
+ ADD_INSN(cond_seq, nd_line(node), pop);
+ }
+ else {
+ COMPILE(cond_seq, "when cond", val);
+ ADD_INSN1(cond_seq, nd_line(node), topn,
+ INT2FIX(1));
+ ADD_SEND(cond_seq, nd_line(node), ID2SYM(idEqq),
+ INT2FIX(1));
+ }
+ ADD_INSNL(cond_seq, nd_line(node), if, l1) ;
+ vals = vals->nd_next;
+ }
+ }
+ else {
+ COMPILE_ERROR(("NODE_CASAE: must be NODE_ARRAY, but %s\n",
+ node_name(nd_type(vals))));
+ }
- node = node->nd_next;
- if (!node) {
- break;
- }
- type = nd_type(node);
- }
- /* else */
- if (node) {
- ADD_LABEL(cond_seq, elselabel);
- ADD_INSN(cond_seq, nd_line(node), pop);
- COMPILE_(cond_seq, "else", node, poped);
- ADD_INSNL(cond_seq, nd_line(node), jump, endlabel);
- }
- else {
- debugs("== else (implicit)\n");
- ADD_LABEL(cond_seq, elselabel);
- ADD_INSN(cond_seq, nd_line(tempnode), pop);
- if (!poped) {
- ADD_INSN(cond_seq, nd_line(tempnode), putnil);
- }
- ADD_INSNL(cond_seq, nd_line(tempnode), jump, endlabel);
- }
+ node = node->nd_next;
+ if (!node) {
+ break;
+ }
+ type = nd_type(node);
+ }
+ /* else */
+ if (node) {
+ ADD_LABEL(cond_seq, elselabel);
+ ADD_INSN(cond_seq, nd_line(node), pop);
+ COMPILE_(cond_seq, "else", node, poped);
+ ADD_INSNL(cond_seq, nd_line(node), jump, endlabel);
+ }
+ else {
+ debugs("== else (implicit)\n");
+ ADD_LABEL(cond_seq, elselabel);
+ ADD_INSN(cond_seq, nd_line(tempnode), pop);
+ if (!poped) {
+ ADD_INSN(cond_seq, nd_line(tempnode), putnil);
+ }
+ ADD_INSNL(cond_seq, nd_line(tempnode), jump, endlabel);
+ }
- if (special_literals) {
- special_literals = (VALUE)NEW_WHILE(special_literals, 0, 0);
- ADD_INSN(ret, nd_line(tempnode), dup);
- ADD_INSN2(ret, nd_line(tempnode), opt_case_dispatch,
- special_literals, elselabel);
- iseq_add_mark_object_compile_time(iseq, special_literals);
- }
+ if (special_literals) {
+ special_literals = (VALUE)NEW_WHILE(special_literals, 0, 0);
+ ADD_INSN(ret, nd_line(tempnode), dup);
+ ADD_INSN2(ret, nd_line(tempnode), opt_case_dispatch,
+ special_literals, elselabel);
+ iseq_add_mark_object_compile_time(iseq, special_literals);
+ }
- ADD_SEQ(ret, cond_seq);
- ADD_SEQ(ret, body_seq);
- ADD_LABEL(ret, endlabel);
- break;
- }
- case NODE_WHEN:{
- NODE *vals;
- NODE *val;
- NODE *orig_node = node;
- LABEL *endlabel;
- DECL_ANCHOR(body_seq);
+ ADD_SEQ(ret, cond_seq);
+ ADD_SEQ(ret, body_seq);
+ ADD_LABEL(ret, endlabel);
+ break;
+ }
+ case NODE_WHEN:{
+ NODE *vals;
+ NODE *val;
+ NODE *orig_node = node;
+ LABEL *endlabel;
+ DECL_ANCHOR(body_seq);
- endlabel = NEW_LABEL(nd_line(node));
+ endlabel = NEW_LABEL(nd_line(node));
- while (node && nd_type(node) == NODE_WHEN) {
- LABEL *l1 = NEW_LABEL(nd_line(node));
- ADD_LABEL(body_seq, l1);
- COMPILE_(body_seq, "when", node->nd_body, poped);
- ADD_INSNL(body_seq, nd_line(node), jump, endlabel);
+ while (node && nd_type(node) == NODE_WHEN) {
+ LABEL *l1 = NEW_LABEL(nd_line(node));
+ ADD_LABEL(body_seq, l1);
+ COMPILE_(body_seq, "when", node->nd_body, poped);
+ ADD_INSNL(body_seq, nd_line(node), jump, endlabel);
- vals = node->nd_head;
- if (vals && nd_type(vals) == NODE_ARRAY) {
- while (vals) {
- val = vals->nd_head;
- if (nd_type(val) == NODE_WHEN) {
- ADD_INSN(ret, nd_line(val), putnil);
- COMPILE(ret, "when2/splat", val->nd_head);
- ADD_INSN1(ret, nd_line(val), checkincludearray,
- Qfalse);
- ADD_INSN(ret, nd_line(val), pop);
- ADD_INSNL(ret, nd_line(val), if, l1) ;
- }
- else {
- COMPILE(ret, "when2", val);
- ADD_INSNL(ret, nd_line(val), if, l1) ;
- }
- vals = vals->nd_next;
- }
- }
- else {
- rb_bug("err");
- }
- node = node->nd_next;
- }
- /* else */
- COMPILE_(ret, "else", node, poped);
- ADD_INSNL(ret, nd_line(orig_node), jump, endlabel);
+ vals = node->nd_head;
+ if (vals && nd_type(vals) == NODE_ARRAY) {
+ while (vals) {
+ val = vals->nd_head;
+ if (nd_type(val) == NODE_WHEN) {
+ ADD_INSN(ret, nd_line(val), putnil);
+ COMPILE(ret, "when2/splat", val->nd_head);
+ ADD_INSN1(ret, nd_line(val), checkincludearray,
+ Qfalse);
+ ADD_INSN(ret, nd_line(val), pop);
+ ADD_INSNL(ret, nd_line(val), if, l1) ;
+ }
+ else {
+ COMPILE(ret, "when2", val);
+ ADD_INSNL(ret, nd_line(val), if, l1) ;
+ }
+ vals = vals->nd_next;
+ }
+ }
+ else {
+ rb_bug("err");
+ }
+ node = node->nd_next;
+ }
+ /* else */
+ COMPILE_(ret, "else", node, poped);
+ ADD_INSNL(ret, nd_line(orig_node), jump, endlabel);
- ADD_SEQ(ret, body_seq);
- ADD_LABEL(ret, endlabel);
+ ADD_SEQ(ret, body_seq);
+ ADD_LABEL(ret, endlabel);
- break;
- }
- case NODE_OPT_N:
- case NODE_WHILE:
- case NODE_UNTIL:{
- LABEL *prev_start_label = iseq->compile_data->start_label;
- LABEL *prev_end_label = iseq->compile_data->end_label;
- LABEL *prev_redo_label = iseq->compile_data->redo_label;
- VALUE prev_loopval_popped = iseq->compile_data->loopval_popped;
+ break;
+ }
+ case NODE_OPT_N:
+ case NODE_WHILE:
+ case NODE_UNTIL:{
+ LABEL *prev_start_label = iseq->compile_data->start_label;
+ LABEL *prev_end_label = iseq->compile_data->end_label;
+ LABEL *prev_redo_label = iseq->compile_data->redo_label;
+ VALUE prev_loopval_popped = iseq->compile_data->loopval_popped;
- struct iseq_compile_data_ensure_node_stack *enlp =
- iseq->compile_data->ensure_node_stack;
+ struct iseq_compile_data_ensure_node_stack *enlp =
+ iseq->compile_data->ensure_node_stack;
- LABEL *next_label = iseq->compile_data->start_label = NEW_LABEL(nd_line(node)); /* next */
- LABEL *redo_label = iseq->compile_data->redo_label = NEW_LABEL(nd_line(node)); /* redo */
- LABEL *break_label = iseq->compile_data->end_label = NEW_LABEL(nd_line(node)); /* break */
- LABEL *end_label = NEW_LABEL(nd_line(node));
+ LABEL *next_label = iseq->compile_data->start_label = NEW_LABEL(nd_line(node)); /* next */
+ LABEL *redo_label = iseq->compile_data->redo_label = NEW_LABEL(nd_line(node)); /* redo */
+ LABEL *break_label = iseq->compile_data->end_label = NEW_LABEL(nd_line(node)); /* break */
+ LABEL *end_label = NEW_LABEL(nd_line(node));
- iseq->compile_data->loopval_popped = 0;
- iseq->compile_data->ensure_node_stack = 0;
+ iseq->compile_data->loopval_popped = 0;
+ iseq->compile_data->ensure_node_stack = 0;
- if (type == NODE_OPT_N || node->nd_state) {
- ADD_INSNL(ret, nd_line(node), jump, next_label);
- }
+ if (type == NODE_OPT_N || node->nd_state) {
+ ADD_INSNL(ret, nd_line(node), jump, next_label);
+ }
- ADD_LABEL(ret, redo_label);
- COMPILE_POPED(ret, "while body", node->nd_body);
- ADD_LABEL(ret, next_label); /* next */
+ ADD_LABEL(ret, redo_label);
+ COMPILE_POPED(ret, "while body", node->nd_body);
+ ADD_LABEL(ret, next_label); /* next */
- if (type == NODE_WHILE) {
- compile_branch_condition(iseq, ret, node->nd_cond,
- redo_label, end_label);
- }
- else if (type == NODE_UNTIL) {
- /* untile */
- compile_branch_condition(iseq, ret, node->nd_cond,
- end_label, redo_label);
- }
- else {
- ADD_INSN(ret, nd_line(node), putself);
- ADD_CALL(ret, nd_line(node), ID2SYM(idGets), INT2FIX(0));
- ADD_INSNL(ret, nd_line(node), if, redo_label) ;
- /* opt_n */
- }
+ if (type == NODE_WHILE) {
+ compile_branch_condition(iseq, ret, node->nd_cond,
+ redo_label, end_label);
+ }
+ else if (type == NODE_UNTIL) {
+ /* untile */
+ compile_branch_condition(iseq, ret, node->nd_cond,
+ end_label, redo_label);
+ }
+ else {
+ ADD_INSN(ret, nd_line(node), putself);
+ ADD_CALL(ret, nd_line(node), ID2SYM(idGets), INT2FIX(0));
+ ADD_INSNL(ret, nd_line(node), if, redo_label) ;
+ /* opt_n */
+ }
- ADD_LABEL(ret, end_label);
+ ADD_LABEL(ret, end_label);
- if (node->nd_state == Qundef) {
- ADD_INSN(ret, nd_line(node), putundef);
- }
- else {
- ADD_INSN(ret, nd_line(node), putnil);
- }
+ if (node->nd_state == Qundef) {
+ ADD_INSN(ret, nd_line(node), putundef);
+ }
+ else {
+ ADD_INSN(ret, nd_line(node), putnil);
+ }
- ADD_LABEL(ret, break_label); /* braek */
+ ADD_LABEL(ret, break_label); /* braek */
- if (poped) {
- ADD_INSN(ret, nd_line(node), pop);
- }
+ if (poped) {
+ ADD_INSN(ret, nd_line(node), pop);
+ }
- ADD_CATCH_ENTRY(CATCH_TYPE_BREAK, redo_label, break_label,
- 0, break_label);
- ADD_CATCH_ENTRY(CATCH_TYPE_NEXT | 0x10000, redo_label,
- break_label, 0, iseq->compile_data->start_label);
- ADD_CATCH_ENTRY(CATCH_TYPE_REDO, redo_label, break_label, 0,
- iseq->compile_data->redo_label);
+ ADD_CATCH_ENTRY(CATCH_TYPE_BREAK, redo_label, break_label,
+ 0, break_label);
+ ADD_CATCH_ENTRY(CATCH_TYPE_NEXT | 0x10000, redo_label,
+ break_label, 0, iseq->compile_data->start_label);
+ ADD_CATCH_ENTRY(CATCH_TYPE_REDO, redo_label, break_label, 0,
+ iseq->compile_data->redo_label);
- iseq->compile_data->start_label = prev_start_label;
- iseq->compile_data->end_label = prev_end_label;
- iseq->compile_data->redo_label = prev_redo_label;
- iseq->compile_data->loopval_popped = prev_loopval_popped;
- iseq->compile_data->ensure_node_stack = enlp;
- break;
- }
- case NODE_ITER:
- case NODE_FOR:{
- VALUE prevblock = iseq->compile_data->current_block;
- LABEL *retry_label = NEW_LABEL(nd_line(node));
- LABEL *retry_end_l = NEW_LABEL(nd_line(node));
- ID mid = 0;
+ iseq->compile_data->start_label = prev_start_label;
+ iseq->compile_data->end_label = prev_end_label;
+ iseq->compile_data->redo_label = prev_redo_label;
+ iseq->compile_data->loopval_popped = prev_loopval_popped;
+ iseq->compile_data->ensure_node_stack = enlp;
+ break;
+ }
+ case NODE_ITER:
+ case NODE_FOR:{
+ VALUE prevblock = iseq->compile_data->current_block;
+ LABEL *retry_label = NEW_LABEL(nd_line(node));
+ LABEL *retry_end_l = NEW_LABEL(nd_line(node));
+ ID mid = 0;
- ADD_LABEL(ret, retry_label);
- if (nd_type(node) == NODE_FOR) {
- COMPILE(ret, "iter caller (for)", node->nd_iter);
+ ADD_LABEL(ret, retry_label);
+ if (nd_type(node) == NODE_FOR) {
+ COMPILE(ret, "iter caller (for)", node->nd_iter);
- iseq->compile_data->current_block =
- NEW_CHILD_ISEQVAL(node, make_name_for_block(iseq),
- ISEQ_TYPE_BLOCK);
+ iseq->compile_data->current_block =
+ NEW_CHILD_ISEQVAL(node, make_name_for_block(iseq),
+ ISEQ_TYPE_BLOCK);
- mid = idEach;
- ADD_SEND_R(ret, nd_line(node), ID2SYM(idEach), INT2FIX(0),
- iseq->compile_data->current_block, INT2FIX(0));
- if (poped) {
- ADD_INSN(ret, nd_line(node), pop);
- }
- }
- else {
- iseq->compile_data->current_block =
- NEW_CHILD_ISEQVAL(node, make_name_for_block(iseq),
- ISEQ_TYPE_BLOCK);
- COMPILE_(ret, "iter caller", node->nd_iter, poped);
- }
- ADD_LABEL(ret, retry_end_l);
- iseq->compile_data->current_block = prevblock;
+ mid = idEach;
+ ADD_SEND_R(ret, nd_line(node), ID2SYM(idEach), INT2FIX(0),
+ iseq->compile_data->current_block, INT2FIX(0));
+ if (poped) {
+ ADD_INSN(ret, nd_line(node), pop);
+ }
+ }
+ else {
+ iseq->compile_data->current_block =
+ NEW_CHILD_ISEQVAL(node, make_name_for_block(iseq),
+ ISEQ_TYPE_BLOCK);
+ COMPILE_(ret, "iter caller", node->nd_iter, poped);
+ }
+ ADD_LABEL(ret, retry_end_l);
+ iseq->compile_data->current_block = prevblock;
- ADD_CATCH_ENTRY(CATCH_TYPE_RETRY, retry_label, retry_end_l, 0,
- retry_label);
- break;
- }
- case NODE_BREAK:{
- unsigned long level = 0;
+ ADD_CATCH_ENTRY(CATCH_TYPE_RETRY, retry_label, retry_end_l, 0,
+ retry_label);
+ break;
+ }
+ case NODE_BREAK:{
+ unsigned long level = 0;
- if (iseq->compile_data->redo_label != 0) {
- /* while/until */
- add_ensure_iseq(ret, iseq);
- COMPILE_(ret, "break val (while/until)", node->nd_stts,
- iseq->compile_data->loopval_popped);
- ADD_INSNL(ret, nd_line(node), jump,
- iseq->compile_data->end_label);
- }
- else if (iseq->type == ISEQ_TYPE_BLOCK) {
- break_by_insn:
- /* escape from block */
- COMPILE(ret, "break val (block)", node->nd_stts);
- ADD_INSN1(ret, nd_line(node), throw,
- INT2FIX(level | 0x02) /* TAG_BREAK */ );
- }
- else if (iseq->type == ISEQ_TYPE_EVAL) {
- COMPILE_ERROR(("Can't escape from eval with break"));
- }
- else {
- yarv_iseq_t *ip = iseq->parent_iseq;
- while (ip) {
- level++;
- if (ip->compile_data->redo_label != 0) {
- level = 0x8000;
- if (ip->compile_data->loopval_popped == 0) {
- /* need value */
- level |= 0x4000;
- }
- goto break_by_insn;
- }
- else if (ip->type == ISEQ_TYPE_BLOCK) {
- level <<= 16;
- goto break_by_insn;
- }
- ip = ip->parent_iseq;
- }
- COMPILE_ERROR(("Illegal break"));
- }
- break;
- }
- case NODE_NEXT:{
- unsigned long level = 0;
+ if (iseq->compile_data->redo_label != 0) {
+ /* while/until */
+ add_ensure_iseq(ret, iseq);
+ COMPILE_(ret, "break val (while/until)", node->nd_stts,
+ iseq->compile_data->loopval_popped);
+ ADD_INSNL(ret, nd_line(node), jump,
+ iseq->compile_data->end_label);
+ }
+ else if (iseq->type == ISEQ_TYPE_BLOCK) {
+ break_by_insn:
+ /* escape from block */
+ COMPILE(ret, "break val (block)", node->nd_stts);
+ ADD_INSN1(ret, nd_line(node), throw,
+ INT2FIX(level | 0x02) /* TAG_BREAK */ );
+ }
+ else if (iseq->type == ISEQ_TYPE_EVAL) {
+ COMPILE_ERROR(("Can't escape from eval with break"));
+ }
+ else {
+ yarv_iseq_t *ip = iseq->parent_iseq;
+ while (ip) {
+ level++;
+ if (ip->compile_data->redo_label != 0) {
+ level = 0x8000;
+ if (ip->compile_data->loopval_popped == 0) {
+ /* need value */
+ level |= 0x4000;
+ }
+ goto break_by_insn;
+ }
+ else if (ip->type == ISEQ_TYPE_BLOCK) {
+ level <<= 16;
+ goto break_by_insn;
+ }
+ ip = ip->parent_iseq;
+ }
+ COMPILE_ERROR(("Illegal break"));
+ }
+ break;
+ }
+ case NODE_NEXT:{
+ unsigned long level = 0;
- if (iseq->compile_data->redo_label != 0) {
- add_ensure_iseq(ret, iseq);
- ADD_INSNL(ret, nd_line(node), jump,
- iseq->compile_data->start_label);
- }
- else if (iseq->compile_data->end_label) {
- COMPILE(ret, "next val", node->nd_stts);
- add_ensure_iseq(ret, iseq);
- ADD_INSNL(ret, nd_line(node), jump,
- iseq->compile_data->end_label);
- }
- else if (iseq->type == ISEQ_TYPE_EVAL) {
- COMPILE_ERROR(("Can't escape from eval with next"));
- }
- else {
- yarv_iseq_t *ip = iseq->parent_iseq;
- while (ip) {
- level = 0x8000;
- if (ip->type == ISEQ_TYPE_BLOCK) {
- level |= 0x4000;
- break;
- }
- else if (ip->compile_data->redo_label != 0) {
- break;
- }
- ip = ip->parent_iseq;
- }
- if (ip != 0) {
- COMPILE(ret, "next val", node->nd_stts);
- add_ensure_iseq(ret, iseq);
- ADD_INSN1(ret, nd_line(node), throw,
- INT2FIX(level | 0x03) /* TAG_NEXT */ );
- }
- else {
- COMPILE_ERROR(("Illegal next"));
- }
- }
- break;
- }
- case NODE_REDO:{
- if (iseq->compile_data->redo_label) {
- add_ensure_iseq(ret, iseq);
- ADD_INSNL(ret, nd_line(node), jump,
- iseq->compile_data->redo_label);
- }
- else if (iseq->compile_data->start_label) {
- ADD_INSNL(ret, nd_line(node), jump,
- iseq->compile_data->start_label);
- }
- else {
- yarv_iseq_t *ip = iseq->parent_iseq;
- unsigned long level = 0x8000 | 0x4000;
- while (ip) {
- if (ip->type == ISEQ_TYPE_BLOCK) {
- break;
- }
- else if (ip->compile_data->redo_label != 0) {
- break;
- }
- ip = ip->parent_iseq;
- }
- if (ip != 0) {
- add_ensure_iseq(ret, iseq);
- ADD_INSN1(ret, nd_line(node), throw,
- INT2FIX(level | 0x05) /* TAG_REDO */ );
- }
- else {
- COMPILE_ERROR(("Illegal redo"));
- }
- }
- break;
- }
- case NODE_RETRY:{
- if (iseq->type == ISEQ_TYPE_BLOCK ||
- iseq->type == ISEQ_TYPE_RESCUE) {
- ADD_INSN(ret, nd_line(node), putnil);
- ADD_INSN1(ret, nd_line(node), throw,
- INT2FIX(0x04) /* TAG_RETRY */ );
- }
- else {
- COMPILE_ERROR(("Illegal retry"));
- }
- break;
- }
- case NODE_BEGIN:{
- COMPILE_(ret, "NODE_BEGIN", node->nd_body, poped);
- break;
- }
- case NODE_RESCUE:{
- LABEL *lstart = NEW_LABEL(nd_line(node));
- LABEL *lend = NEW_LABEL(nd_line(node));
- LABEL *lcont = NEW_LABEL(nd_line(node));
- VALUE rescue = NEW_CHILD_ISEQVAL(node->nd_resq,
- rb_str_concat(rb_str_new2
- ("rescue in "),
- iseq->name),
- ISEQ_TYPE_RESCUE);
+ if (iseq->compile_data->redo_label != 0) {
+ add_ensure_iseq(ret, iseq);
+ ADD_INSNL(ret, nd_line(node), jump,
+ iseq->compile_data->start_label);
+ }
+ else if (iseq->compile_data->end_label) {
+ COMPILE(ret, "next val", node->nd_stts);
+ add_ensure_iseq(ret, iseq);
+ ADD_INSNL(ret, nd_line(node), jump,
+ iseq->compile_data->end_label);
+ }
+ else if (iseq->type == ISEQ_TYPE_EVAL) {
+ COMPILE_ERROR(("Can't escape from eval with next"));
+ }
+ else {
+ yarv_iseq_t *ip = iseq->parent_iseq;
+ while (ip) {
+ level = 0x8000;
+ if (ip->type == ISEQ_TYPE_BLOCK) {
+ level |= 0x4000;
+ break;
+ }
+ else if (ip->type == ISEQ_TYPE_EVAL) {
+ COMPILE_ERROR(("Can't escape from eval with eval"));
+ }
+ else if (ip->compile_data->redo_label != 0) {
+ break;
+ }
+ ip = ip->parent_iseq;
+ }
+ if (ip != 0) {
+ COMPILE(ret, "next val", node->nd_stts);
+ add_ensure_iseq(ret, iseq);
+ ADD_INSN1(ret, nd_line(node), throw,
+ INT2FIX(level | 0x03) /* TAG_NEXT */ );
+ }
+ else {
+ COMPILE_ERROR(("Illegal next"));
+ }
+ }
+ break;
+ }
+ case NODE_REDO:{
+ if (iseq->compile_data->redo_label) {
+ add_ensure_iseq(ret, iseq);
+ ADD_INSNL(ret, nd_line(node), jump,
+ iseq->compile_data->redo_label);
+ }
+ else if (iseq->type == ISEQ_TYPE_EVAL) {
+ COMPILE_ERROR(("Can't escape from eval with redo"));
+ }
+ else if (iseq->compile_data->start_label) {
+ ADD_INSNL(ret, nd_line(node), jump,
+ iseq->compile_data->start_label);
+ }
+ else {
+ yarv_iseq_t *ip = iseq->parent_iseq;
+ unsigned long level = 0x8000 | 0x4000;
+ while (ip) {
+ if (ip->type == ISEQ_TYPE_BLOCK) {
+ break;
+ }
+ else if (ip->type == ISEQ_TYPE_EVAL) {
+ COMPILE_ERROR(("Can't escape from eval with redo"));
+ }
+ else if (ip->compile_data->redo_label != 0) {
+ break;
+ }
+ ip = ip->parent_iseq;
+ }
+ if (ip != 0) {
+ add_ensure_iseq(ret, iseq);
+ ADD_INSN1(ret, nd_line(node), throw,
+ INT2FIX(level | 0x05) /* TAG_REDO */ );
+ }
+ else {
+ COMPILE_ERROR(("Illegal redo"));
+ }
+ }
+ break;
+ }
+ case NODE_RETRY:{
+ if (iseq->type == ISEQ_TYPE_BLOCK ||
+ iseq->type == ISEQ_TYPE_RESCUE) {
+ ADD_INSN(ret, nd_line(node), putnil);
+ ADD_INSN1(ret, nd_line(node), throw,
+ INT2FIX(0x04) /* TAG_RETRY */ );
+ }
+ else {
+ COMPILE_ERROR(("Illegal retry"));
+ }
+ break;
+ }
+ case NODE_BEGIN:{
+ COMPILE_(ret, "NODE_BEGIN", node->nd_body, poped);
+ break;
+ }
+ case NODE_RESCUE:{
+ LABEL *lstart = NEW_LABEL(nd_line(node));
+ LABEL *lend = NEW_LABEL(nd_line(node));
+ LABEL *lcont = NEW_LABEL(nd_line(node));
+ VALUE rescue = NEW_CHILD_ISEQVAL(node->nd_resq,
+ rb_str_concat(rb_str_new2
+ ("rescue in "),
+ iseq->name),
+ ISEQ_TYPE_RESCUE);
- ADD_LABEL(ret, lstart);
- COMPILE(ret, "rescue head", node->nd_head);
- ADD_LABEL(ret, lend);
- if (node->nd_else) {
- ADD_INSN(ret, nd_line(node), pop);
- COMPILE(ret, "rescue else", node->nd_else);
- }
- ADD_INSN(ret, nd_line(node), nop);
- ADD_LABEL(ret, lcont);
+ ADD_LABEL(ret, lstart);
+ COMPILE(ret, "rescue head", node->nd_head);
+ ADD_LABEL(ret, lend);
+ if (node->nd_else) {
+ ADD_INSN(ret, nd_line(node), pop);
+ COMPILE(ret, "rescue else", node->nd_else);
+ }
+ ADD_INSN(ret, nd_line(node), nop);
+ ADD_LABEL(ret, lcont);
- if (poped) {
- ADD_INSN(ret, nd_line(node), pop);
- }
+ if (poped) {
+ ADD_INSN(ret, nd_line(node), pop);
+ }
- /* resgister catch entry */
- ADD_CATCH_ENTRY(CATCH_TYPE_RESCUE, lstart, lend, rescue, lcont);
- ADD_CATCH_ENTRY(CATCH_TYPE_RETRY, lend, lcont, 0, lstart);
- break;
- }
- case NODE_RESBODY:{
- NODE *resq = node;
- NODE *narg;
- LABEL *label_miss, *label_hit;
+ /* resgister catch entry */
+ ADD_CATCH_ENTRY(CATCH_TYPE_RESCUE, lstart, lend, rescue, lcont);
+ ADD_CATCH_ENTRY(CATCH_TYPE_RETRY, lend, lcont, 0, lstart);
+ break;
+ }
+ case NODE_RESBODY:{
+ NODE *resq = node;
+ NODE *narg;
+ LABEL *label_miss, *label_hit;
- while (resq) {
- label_miss = NEW_LABEL(nd_line(node));
- label_hit = NEW_LABEL(nd_line(node));
+ while (resq) {
+ label_miss = NEW_LABEL(nd_line(node));
+ label_hit = NEW_LABEL(nd_line(node));
- narg = resq->nd_args;
- while (narg) {
- COMPILE(ret, "rescue arg", narg->nd_head);
- ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(1),
- INT2FIX(0));
- ADD_SEND(ret, nd_line(node), ID2SYM(idEqq), INT2FIX(1));
- ADD_INSNL(ret, nd_line(node), if, label_hit) ;
- narg = narg->nd_next;
- }
- if (resq->nd_args == 0) {
- ADD_INSN1(ret, nd_line(node), putobject,
- rb_eStandardError);
- ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(1),
- INT2FIX(0));
- ADD_SEND(ret, nd_line(node), ID2SYM(idEqq), INT2FIX(1));
- ADD_INSNL(ret, nd_line(node), if, label_hit) ;
- }
- ADD_INSNL(ret, nd_line(node), jump, label_miss);
- ADD_LABEL(ret, label_hit);
- COMPILE(ret, "resbody body", resq->nd_body);
- ADD_INSN(ret, nd_line(node), end);
- ADD_LABEL(ret, label_miss);
- resq = resq->nd_head;
- }
- break;
- }
- case NODE_ENSURE:{
- DECL_ANCHOR(ensr);
- VALUE ensure = NEW_CHILD_ISEQVAL(node->nd_ensr,
- rb_str_concat(rb_str_new2
- ("ensure in "),
- iseq->name),
- ISEQ_TYPE_ENSURE);
- LABEL *lstart = NEW_LABEL(nd_line(node));
- LABEL *lend = NEW_LABEL(nd_line(node));
- LABEL *lcont = NEW_LABEL(nd_line(node));
- struct ensure_range er = { lstart, lend, 0 };
- struct iseq_compile_data_ensure_node_stack enl = {
- node->nd_ensr,
- iseq->compile_data->ensure_node_stack, /* prev */
- &er,
- };
- struct ensure_range *erange;
+ narg = resq->nd_args;
+ while (narg) {
+ COMPILE(ret, "rescue arg", narg->nd_head);
+ ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(1),
+ INT2FIX(0));
+ ADD_SEND(ret, nd_line(node), ID2SYM(idEqq), INT2FIX(1));
+ ADD_INSNL(ret, nd_line(node), if, label_hit) ;
+ narg = narg->nd_next;
+ }
+ if (resq->nd_args == 0) {
+ ADD_INSN1(ret, nd_line(node), putobject,
+ rb_eStandardError);
+ ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(1),
+ INT2FIX(0));
+ ADD_SEND(ret, nd_line(node), ID2SYM(idEqq), INT2FIX(1));
+ ADD_INSNL(ret, nd_line(node), if, label_hit) ;
+ }
+ ADD_INSNL(ret, nd_line(node), jump, label_miss);
+ ADD_LABEL(ret, label_hit);
+ COMPILE(ret, "resbody body", resq->nd_body);
+ ADD_INSN(ret, nd_line(node), end);
+ ADD_LABEL(ret, label_miss);
+ resq = resq->nd_head;
+ }
+ break;
+ }
+ case NODE_ENSURE:{
+ DECL_ANCHOR(ensr);
+ VALUE ensure = NEW_CHILD_ISEQVAL(node->nd_ensr,
+ rb_str_concat(rb_str_new2
+ ("ensure in "),
+ iseq->name),
+ ISEQ_TYPE_ENSURE);
+ LABEL *lstart = NEW_LABEL(nd_line(node));
+ LABEL *lend = NEW_LABEL(nd_line(node));
+ LABEL *lcont = NEW_LABEL(nd_line(node));
+ struct ensure_range er = { lstart, lend, 0 };
+ struct iseq_compile_data_ensure_node_stack enl = {
+ node->nd_ensr,
+ iseq->compile_data->ensure_node_stack, /* prev */
+ &er,
+ };
+ struct ensure_range *erange;
- COMPILE_POPED(ensr, "ensure ensr", node->nd_ensr);
+ COMPILE_POPED(ensr, "ensure ensr", node->nd_ensr);
- iseq->compile_data->ensure_node_stack = &enl;
+ iseq->compile_data->ensure_node_stack = &enl;
- ADD_LABEL(ret, lstart);
- COMPILE_(ret, "ensure head", node->nd_head, poped);
- ADD_LABEL(ret, lend);
- if (ensr->anchor.next == 0) {
- ADD_INSN(ret, nd_line(node), nop);
- }
- else {
- ADD_SEQ(ret, ensr);
- }
- ADD_LABEL(ret, lcont);
+ ADD_LABEL(ret, lstart);
+ COMPILE_(ret, "ensure head", node->nd_head, poped);
+ ADD_LABEL(ret, lend);
+ if (ensr->anchor.next == 0) {
+ ADD_INSN(ret, nd_line(node), nop);
+ }
+ else {
+ ADD_SEQ(ret, ensr);
+ }
+ ADD_LABEL(ret, lcont);
- erange = iseq->compile_data->ensure_node_stack->erange;
- while (erange) {
- ADD_CATCH_ENTRY(CATCH_TYPE_ENSURE, erange->begin, erange->end,
- ensure, lcont);
- erange = erange->next;
- }
- iseq->compile_data->ensure_node_stack = enl.prev;
- break;
- }
+ erange = iseq->compile_data->ensure_node_stack->erange;
+ while (erange) {
+ ADD_CATCH_ENTRY(CATCH_TYPE_ENSURE, erange->begin, erange->end,
+ ensure, lcont);
+ erange = erange->next;
+ }
+ iseq->compile_data->ensure_node_stack = enl.prev;
+ break;
+ }
- case NODE_AND:
- case NODE_OR:{
- LABEL *end_label = NEW_LABEL(nd_line(node));
- COMPILE(ret, "nd_1st", node->nd_1st);
- if (!poped) {
- ADD_INSN(ret, nd_line(node), dup);
- }
- if (type == NODE_AND) {
- ADD_INSNL(ret, nd_line(node), unless, end_label);
- }
- else {
- ADD_INSNL(ret, nd_line(node), if, end_label) ;
- }
- if (!poped) {
- ADD_INSN(ret, nd_line(node), pop);
- }
- COMPILE_(ret, "nd_2nd", node->nd_2nd, poped);
- ADD_LABEL(ret, end_label);
- break;
- }
- case NODE_NOT:{
- COMPILE(ret, "value", node->nd_body);
- ADD_INSN(ret, nd_line(node), putnot);
- if (poped) {
- ADD_INSN(ret, nd_line(node), pop);
- }
- break;
- }
+ case NODE_AND:
+ case NODE_OR:{
+ LABEL *end_label = NEW_LABEL(nd_line(node));
+ COMPILE(ret, "nd_1st", node->nd_1st);
+ if (!poped) {
+ ADD_INSN(ret, nd_line(node), dup);
+ }
+ if (type == NODE_AND) {
+ ADD_INSNL(ret, nd_line(node), unless, end_label);
+ }
+ else {
+ ADD_INSNL(ret, nd_line(node), if, end_label) ;
+ }
+ if (!poped) {
+ ADD_INSN(ret, nd_line(node), pop);
+ }
+ COMPILE_(ret, "nd_2nd", node->nd_2nd, poped);
+ ADD_LABEL(ret, end_label);
+ break;
+ }
+ case NODE_NOT:{
+ COMPILE(ret, "value", node->nd_body);
+ ADD_INSN(ret, nd_line(node), putnot);
+ if (poped) {
+ ADD_INSN(ret, nd_line(node), pop);
+ }
+ break;
+ }
- case NODE_MASGN:{
- compile_massign(iseq, ret, node->nd_value, /* rhsn */
- node->nd_args, /* splat */
- node->nd_head, /* lhsn */
- 0);
- if (!poped) {
- ADD_INSN1(ret, nd_line(node), putobject, Qtrue);
- }
- break;
- }
+ case NODE_MASGN:{
+ compile_massign(iseq, ret, node->nd_value, /* rhsn */
+ node->nd_args, /* splat */
+ node->nd_head, /* lhsn */
+ 0);
+ if (!poped) {
+ ADD_INSN1(ret, nd_line(node), putobject, Qtrue);
+ }
+ break;
+ }
- case NODE_LASGN:{
- int idx = iseq->local_iseq->local_size + 2 - node->nd_cnt;
- debugs("lvar: %d\n", idx);
- COMPILE(ret, "lvalue", node->nd_value);
+ case NODE_LASGN:{
+ int idx = iseq->local_iseq->local_size + 2 - node->nd_cnt;
+ debugs("lvar: %d\n", idx);
+ COMPILE(ret, "lvalue", node->nd_value);
- if (!poped) {
- ADD_INSN(ret, nd_line(node), dup);
- }
- ADD_INSN1(ret, nd_line(node), setlocal, INT2FIX(idx));
+ if (!poped) {
+ ADD_INSN(ret, nd_line(node), dup);
+ }
+ ADD_INSN1(ret, nd_line(node), setlocal, INT2FIX(idx));
- break;
- }
- case NODE_DASGN:
- case NODE_DASGN_CURR:{
- int idx, lv, ls;
- COMPILE(ret, "dvalue", node->nd_value);
- debugp_param("dassn id", rb_str_new2(rb_id2name(node->nd_vid)));
+ break;
+ }
+ case NODE_DASGN:
+ case NODE_DASGN_CURR:{
+ int idx, lv, ls;
+ COMPILE(ret, "dvalue", node->nd_value);
+ debugp_param("dassn id", rb_str_new2(rb_id2name(node->nd_vid)));
- if (!poped) {
- ADD_INSN(ret, nd_line(node), dup);
- }
- idx = get_dyna_var_idx(iseq, node->nd_vid, &lv, &ls);
- if (nd_type(node) == NODE_DASGN_CURR &&
- lv > 0 &&
- iseq->type != ISEQ_TYPE_RESCUE &&
- iseq->compile_data->for_iseq != 1) {
+ if (!poped) {
+ ADD_INSN(ret, nd_line(node), dup);
+ }
+ idx = get_dyna_var_idx(iseq, node->nd_vid, &lv, &ls);
+ if (nd_type(node) == NODE_DASGN_CURR &&
+ lv > 0 &&
+ iseq->type != ISEQ_TYPE_RESCUE &&
+ iseq->compile_data->for_iseq != 1) {
- dpi(node->nd_vid);
- rb_bug("NODE_DASGN_CURR, but lv == %d (line: %d)", lv,
- nd_line(node));
- }
+ dpi(node->nd_vid);
+ rb_bug("NODE_DASGN_CURR, but lv == %d (line: %d)", lv,
+ nd_line(node));
+ }
- if (idx < 0) {
- debugi("unknown id", node->nd_vid);
- COMPILE_ERROR(("NODE_DASGN error"));
- }
- ADD_INSN2(ret, nd_line(node), setdynamic,
- INT2FIX(ls - idx), INT2FIX(lv));
- break;
- }
- case NODE_GASGN:{
- COMPILE(ret, "lvalue", node->nd_value);
+ if (idx < 0) {
+ debugi("unknown id", node->nd_vid);
+ COMPILE_ERROR(("NODE_DASGN error"));
+ }
+ ADD_INSN2(ret, nd_line(node), setdynamic,
+ INT2FIX(ls - idx), INT2FIX(lv));
+ break;
+ }
+ case NODE_GASGN:{
+ COMPILE(ret, "lvalue", node->nd_value);
- if (!poped) {
- ADD_INSN(ret, nd_line(node), dup);
- }
- ADD_INSN1(ret, nd_line(node), setglobal,
- (((long)node->nd_entry) | 1));
- break;
- }
- case NODE_IASGN:{
- COMPILE(ret, "lvalue", node->nd_value);
- if (!poped) {
- ADD_INSN(ret, nd_line(node), dup);
- }
- ADD_INSN1(ret, nd_line(node), setinstancevariable,
- ID2SYM(node->nd_vid));
- break;
- }
- case NODE_CDECL:{
- COMPILE(ret, "lvalue", node->nd_value);
+ if (!poped) {
+ ADD_INSN(ret, nd_line(node), dup);
+ }
+ ADD_INSN1(ret, nd_line(node), setglobal,
+ (((long)node->nd_entry) | 1));
+ break;
+ }
+ case NODE_IASGN:{
+ COMPILE(ret, "lvalue", node->nd_value);
+ if (!poped) {
+ ADD_INSN(ret, nd_line(node), dup);
+ }
+ ADD_INSN1(ret, nd_line(node), setinstancevariable,
+ ID2SYM(node->nd_vid));
+ break;
+ }
+ case NODE_CDECL:{
+ COMPILE(ret, "lvalue", node->nd_value);
- if (!poped) {
- ADD_INSN(ret, nd_line(node), dup);
- }
+ if (!poped) {
+ ADD_INSN(ret, nd_line(node), dup);
+ }
- if (node->nd_vid) {
- ADD_INSN(ret, nd_line(node), putnil);
- ADD_INSN1(ret, nd_line(node), setconstant,
- ID2SYM(node->nd_vid));
- }
- else {
- COMPILE(ret, "nd_else->nd_head", node->nd_else->nd_head);
- ADD_INSN1(ret, nd_line(node), setconstant,
- ID2SYM(node->nd_else->nd_mid));
- }
- break;
- }
- case NODE_CVASGN:
- case NODE_CVDECL:{
- COMPILE(ret, "cvasgn val", node->nd_value);
- if (!poped) {
- ADD_INSN(ret, nd_line(node), dup);
- }
- ADD_INSN2(ret, nd_line(node), setclassvariable,
- ID2SYM(node->nd_vid),
- nd_type(node) == NODE_CVDECL ? Qtrue : Qfalse);
- break;
- }
- case NODE_OP_ASGN1:{
- DECL_ANCHOR(args);
- int argc;
- ID id = node->nd_mid;
+ if (node->nd_vid) {
+ ADD_INSN(ret, nd_line(node), putnil);
+ ADD_INSN1(ret, nd_line(node), setconstant,
+ ID2SYM(node->nd_vid));
+ }
+ else {
+ COMPILE(ret, "nd_else->nd_head", node->nd_else->nd_head);
+ ADD_INSN1(ret, nd_line(node), setconstant,
+ ID2SYM(node->nd_else->nd_mid));
+ }
+ break;
+ }
+ case NODE_CVASGN:
+ case NODE_CVDECL:{
+ COMPILE(ret, "cvasgn val", node->nd_value);
+ if (!poped) {
+ ADD_INSN(ret, nd_line(node), dup);
+ }
+ ADD_INSN2(ret, nd_line(node), setclassvariable,
+ ID2SYM(node->nd_vid),
+ nd_type(node) == NODE_CVDECL ? Qtrue : Qfalse);
+ break;
+ }
+ case NODE_OP_ASGN1:{
+ DECL_ANCHOR(args);
+ int argc;
+ ID id = node->nd_mid;
- /*
- * a[x] (op)= y
- *
- * eval a # a
- * eval x # a x
- * dupn 2 # a x a x
- * send :[] # a x a[x]
- * eval y # a x a[x] y
- * send op # a x a[x]+y
- * send []= # ret
- */
- COMPILE(ret, "NODE_OP_ASGN1 recv", node->nd_recv);
+ /*
+ * a[x] (op)= y
+ *
+ * eval a # a
+ * eval x # a x
+ * dupn 2 # a x a x
+ * send :[] # a x a[x]
+ * eval y # a x a[x] y
+ * send op # a x a[x]+y
+ * send []= # ret
+ */
+ COMPILE(ret, "NODE_OP_ASGN1 recv", node->nd_recv);
- compile_array(iseq, args, node->nd_args->nd_next, Qfalse);
- POP_ELEMENT(args);
- POP_ELEMENT(args);
- argc = node->nd_args->nd_alen - 2;
+ compile_array(iseq, args, node->nd_args->nd_next, Qfalse);
+ POP_ELEMENT(args);
+ POP_ELEMENT(args);
+ argc = node->nd_args->nd_alen - 2;
- ADD_SEQ(ret, args);
- ADD_INSN1(ret, nd_line(node), dupn, INT2FIX(argc + 1));
- ADD_SEND(ret, nd_line(node), ID2SYM(idAREF), INT2FIX(argc));
+ ADD_SEQ(ret, args);
+ ADD_INSN1(ret, nd_line(node), dupn, INT2FIX(argc + 1));
+ ADD_SEND(ret, nd_line(node), ID2SYM(idAREF), INT2FIX(argc));
- if (id == 0 || id == 1) {
- /* 0: or, 1: and
+ if (id == 0 || id == 1) {
+ /* 0: or, 1: and
a[x] ||= y
unless/if a[x]
@@ -3202,59 +3211,59 @@
else
nil
end
- */
- LABEL *label = NEW_LABEL(nd_line(node));
- LABEL *lfin = NEW_LABEL(nd_line(node));
+ */
+ LABEL *label = NEW_LABEL(nd_line(node));
+ LABEL *lfin = NEW_LABEL(nd_line(node));
- if (id == 0) {
- /* or */
- ADD_INSN(ret, nd_line(node), dup);
- ADD_INSNL(ret, nd_line(node), if, label) ;
- ADD_INSN(ret, nd_line(node), pop);
- }
- else {
- /* and */
- ADD_INSNL(ret, nd_line(node), unless, label);
- }
+ if (id == 0) {
+ /* or */
+ ADD_INSN(ret, nd_line(node), dup);
+ ADD_INSNL(ret, nd_line(node), if, label) ;
+ ADD_INSN(ret, nd_line(node), pop);
+ }
+ else {
+ /* and */
+ ADD_INSNL(ret, nd_line(node), unless, label);
+ }
- COMPILE(ret, "NODE_OP_ASGN1 args->head: ",
- node->nd_args->nd_head);
- ADD_SEND(ret, nd_line(node), ID2SYM(idASET),
- INT2FIX(argc + 1));
- ADD_INSNL(ret, nd_line(node), jump, lfin);
- ADD_LABEL(ret, label);
- if (id == 0) { /* or */
- ADD_INSN(ret, nd_line(node), swap);
- ADD_INSN(ret, nd_line(node), pop);
- ADD_INSN(ret, nd_line(node), swap);
- ADD_INSN(ret, nd_line(node), pop);
- }
- else if (id == 1) { /* and */
- ADD_INSN(ret, nd_line(node), pop);
- ADD_INSN(ret, nd_line(node), pop);
- ADD_INSN(ret, nd_line(node), putnil);
- }
- ADD_LABEL(ret, lfin);
- }
- else {
- COMPILE(ret, "NODE_OP_ASGN1 args->head: ",
- node->nd_args->nd_head);
- ADD_SEND(ret, nd_line(node), ID2SYM(id), INT2FIX(1));
- ADD_SEND(ret, nd_line(node), ID2SYM(idASET),
- INT2FIX(argc + 1));
- }
+ COMPILE(ret, "NODE_OP_ASGN1 args->head: ",
+ node->nd_args->nd_head);
+ ADD_SEND(ret, nd_line(node), ID2SYM(idASET),
+ INT2FIX(argc + 1));
+ ADD_INSNL(ret, nd_line(node), jump, lfin);
+ ADD_LABEL(ret, label);
+ if (id == 0) { /* or */
+ ADD_INSN(ret, nd_line(node), swap);
+ ADD_INSN(ret, nd_line(node), pop);
+ ADD_INSN(ret, nd_line(node), swap);
+ ADD_INSN(ret, nd_line(node), pop);
+ }
+ else if (id == 1) { /* and */
+ ADD_INSN(ret, nd_line(node), pop);
+ ADD_INSN(ret, nd_line(node), pop);
+ ADD_INSN(ret, nd_line(node), putnil);
+ }
+ ADD_LABEL(ret, lfin);
+ }
+ else {
+ COMPILE(ret, "NODE_OP_ASGN1 args->head: ",
+ node->nd_args->nd_head);
+ ADD_SEND(ret, nd_line(node), ID2SYM(id), INT2FIX(1));
+ ADD_SEND(ret, nd_line(node), ID2SYM(idASET),
+ INT2FIX(argc + 1));
+ }
- if (poped) {
- ADD_INSN(ret, nd_line(node), pop);
- }
+ if (poped) {
+ ADD_INSN(ret, nd_line(node), pop);
+ }
- break;
- }
- case NODE_OP_ASGN2:{
- ID atype = node->nd_next->nd_mid;
- LABEL *lfin = NEW_LABEL(nd_line(node));
- LABEL *lcfin = NEW_LABEL(nd_line(node));
- /*
+ break;
+ }
+ case NODE_OP_ASGN2:{
+ ID atype = node->nd_next->nd_mid;
+ LABEL *lfin = NEW_LABEL(nd_line(node));
+ LABEL *lcfin = NEW_LABEL(nd_line(node));
+ /*
class C; attr_accessor :c; end
r = C.new
r.a &&= v # asgn2
@@ -3290,1096 +3299,1096 @@
send ?? # r w
send a= # w
- */
+ */
- COMPILE(ret, "NODE_OP_ASGN2#recv", node->nd_recv);
- ADD_INSN(ret, nd_line(node), dup);
- ADD_SEND(ret, nd_line(node), ID2SYM(node->nd_next->nd_vid),
- INT2FIX(0));
+ COMPILE(ret, "NODE_OP_ASGN2#recv", node->nd_recv);
+ ADD_INSN(ret, nd_line(node), dup);
+ ADD_SEND(ret, nd_line(node), ID2SYM(node->nd_next->nd_vid),
+ INT2FIX(0));
- if (atype == 0 || atype == 1) { /* 0: OR or 1: AND */
- ADD_INSN(ret, nd_line(node), dup);
- if (atype == 0) {
- ADD_INSNL(ret, nd_line(node), if, lcfin) ;
- }
- else {
- ADD_INSNL(ret, nd_line(node), unless, lcfin);
- }
- ADD_INSN(ret, nd_line(node), pop);
- COMPILE(ret, "NODE_OP_ASGN2 val", node->nd_value);
- ADD_SEND(ret, nd_line(node), ID2SYM(node->nd_next->nd_aid),
- INT2FIX(1));
- ADD_INSNL(ret, nd_line(node), jump, lfin);
+ if (atype == 0 || atype == 1) { /* 0: OR or 1: AND */
+ ADD_INSN(ret, nd_line(node), dup);
+ if (atype == 0) {
+ ADD_INSNL(ret, nd_line(node), if, lcfin) ;
+ }
+ else {
+ ADD_INSNL(ret, nd_line(node), unless, lcfin);
+ }
+ ADD_INSN(ret, nd_line(node), pop);
+ COMPILE(ret, "NODE_OP_ASGN2 val", node->nd_value);
+ ADD_SEND(ret, nd_line(node), ID2SYM(node->nd_next->nd_aid),
+ INT2FIX(1));
+ ADD_INSNL(ret, nd_line(node), jump, lfin);
- ADD_LABEL(ret, lcfin);
- ADD_INSN(ret, nd_line(node), swap);
- ADD_INSN(ret, nd_line(node), pop);
+ ADD_LABEL(ret, lcfin);
+ ADD_INSN(ret, nd_line(node), swap);
+ ADD_INSN(ret, nd_line(node), pop);
- ADD_LABEL(ret, lfin);
- }
- else {
- COMPILE(ret, "NODE_OP_ASGN2 val", node->nd_value);
- ADD_SEND(ret, nd_line(node), ID2SYM(node->nd_next->nd_mid),
- INT2FIX(1));
- ADD_SEND(ret, nd_line(node), ID2SYM(node->nd_next->nd_aid),
- INT2FIX(1));
- }
+ ADD_LABEL(ret, lfin);
+ }
+ else {
+ COMPILE(ret, "NODE_OP_ASGN2 val", node->nd_value);
+ ADD_SEND(ret, nd_line(node), ID2SYM(node->nd_next->nd_mid),
+ INT2FIX(1));
+ ADD_SEND(ret, nd_line(node), ID2SYM(node->nd_next->nd_aid),
+ INT2FIX(1));
+ }
- if (poped) {
- /* we can apply more optimize */
- ADD_INSN(ret, nd_line(node), pop);
- }
- break;
- }
- case NODE_OP_ASGN_AND:
- case NODE_OP_ASGN_OR:{
- LABEL *lfin = NEW_LABEL(nd_line(node));
+ if (poped) {
+ /* we can apply more optimize */
+ ADD_INSN(ret, nd_line(node), pop);
+ }
+ break;
+ }
+ case NODE_OP_ASGN_AND:
+ case NODE_OP_ASGN_OR:{
+ LABEL *lfin = NEW_LABEL(nd_line(node));
- COMPILE(ret, "NODE_OP_ASGN_AND#nd_head", node->nd_head);
- ADD_INSN(ret, nd_line(node), dup);
- if (nd_type(node) == NODE_OP_ASGN_AND) {
- ADD_INSNL(ret, nd_line(node), unless, lfin);
- }
- else {
- ADD_INSNL(ret, nd_line(node), if, lfin) ;
- }
- ADD_INSN(ret, nd_line(node), pop);
- COMPILE(ret, "NODE_OP_ASGN_AND#nd_value", node->nd_value);
- ADD_LABEL(ret, lfin);
+ COMPILE(ret, "NODE_OP_ASGN_AND#nd_head", node->nd_head);
+ ADD_INSN(ret, nd_line(node), dup);
+ if (nd_type(node) == NODE_OP_ASGN_AND) {
+ ADD_INSNL(ret, nd_line(node), unless, lfin);
+ }
+ else {
+ ADD_INSNL(ret, nd_line(node), if, lfin) ;
+ }
+ ADD_INSN(ret, nd_line(node), pop);
+ COMPILE(ret, "NODE_OP_ASGN_AND#nd_value", node->nd_value);
+ ADD_LABEL(ret, lfin);
- if (poped) {
- /* we can apply more optimize */
- ADD_INSN(ret, nd_line(node), pop);
- }
- break;
- }
- case NODE_CALL:
- case NODE_FCALL:
- case NODE_VCALL:{ /* VCALL: variable or call */
- /*
+ if (poped) {
+ /* we can apply more optimize */
+ ADD_INSN(ret, nd_line(node), pop);
+ }
+ break;
+ }
+ case NODE_CALL:
+ case NODE_FCALL:
+ case NODE_VCALL:{ /* VCALL: variable or call */
+ /*
call: obj.method(...)
fcall: func(...)
vcall: func
- */
- DECL_ANCHOR(recv);
- DECL_ANCHOR(args);
- ID mid = node->nd_mid;
- VALUE argc;
- VALUE flag = 0;
- VALUE block = 0;
- VALUE parent_blockval = iseq->compile_data->current_block;
- iseq->compile_data->current_block = Qfalse;
+ */
+ DECL_ANCHOR(recv);
+ DECL_ANCHOR(args);
+ ID mid = node->nd_mid;
+ VALUE argc;
+ VALUE flag = 0;
+ VALUE block = 0;
+ VALUE parent_blockval = iseq->compile_data->current_block;
+ iseq->compile_data->current_block = Qfalse;
#if SUPPORT_JOKE
- if (nd_type(node) == NODE_VCALL) {
- if (mid == idBitblt) {
- ADD_INSN(ret, nd_line(node), bitblt);
- break;
- }
- else if (mid == idAnswer) {
- ADD_INSN(ret, nd_line(node), answer);
- break;
- }
- }
- /* only joke */
- {
- static ID goto_id;
- static ID label_id;
- VALUE label;
- VALUE label_sym;
+ if (nd_type(node) == NODE_VCALL) {
+ if (mid == idBitblt) {
+ ADD_INSN(ret, nd_line(node), bitblt);
+ break;
+ }
+ else if (mid == idAnswer) {
+ ADD_INSN(ret, nd_line(node), answer);
+ break;
+ }
+ }
+ /* only joke */
+ {
+ static ID goto_id;
+ static ID label_id;
+ VALUE label;
+ VALUE label_sym;
- if (goto_id == 0) {
- goto_id = rb_intern("__goto__");
- label_id = rb_intern("__label__");
- }
+ if (goto_id == 0) {
+ goto_id = rb_intern("__goto__");
+ label_id = rb_intern("__label__");
+ }
- if (nd_type(node) == NODE_FCALL &&
- (mid == goto_id || mid == label_id)) {
- if (nd_type(node->nd_args->nd_head) == NODE_LIT &&
- SYMBOL_P(node->nd_args->nd_head->nd_lit)) {
+ if (nd_type(node) == NODE_FCALL &&
+ (mid == goto_id || mid == label_id)) {
+ if (nd_type(node->nd_args->nd_head) == NODE_LIT &&
+ SYMBOL_P(node->nd_args->nd_head->nd_lit)) {
- label_sym = label = node->nd_args->nd_head->nd_lit;
- if ((label =
- rb_hash_aref(iseq->compile_data,
- label_sym)) == Qnil) {
- rb_hash_aset(iseq->compile_data, label_sym,
- label = NEW_LABEL(nd_line(node)));
- }
- }
- else {
- rb_bug("illegal goto/label format");
- }
+ label_sym = label = node->nd_args->nd_head->nd_lit;
+ if ((label =
+ rb_hash_aref(iseq->compile_data,
+ label_sym)) == Qnil) {
+ rb_hash_aset(iseq->compile_data, label_sym,
+ label = NEW_LABEL(nd_line(node)));
+ }
+ }
+ else {
+ rb_bug("illegal goto/label format");
+ }
- if (mid == goto_id) {
- ADD_INSNL(ret, nd_line(node), jump, label);
- }
- else {
- ADD_LABEL(ret, label);
- }
- break;
- }
- }
+ if (mid == goto_id) {
+ ADD_INSNL(ret, nd_line(node), jump, label);
+ }
+ else {
+ ADD_LABEL(ret, label);
+ }
+ break;
+ }
+ }
#endif
- /* reciever */
- if (type == NODE_CALL) {
- COMPILE(recv, "recv", node->nd_recv);
- }
- else if (type == NODE_FCALL || type == NODE_VCALL) {
- ADD_INSN(recv, nd_line(node), putself);
- }
+ /* reciever */
+ if (type == NODE_CALL) {
+ COMPILE(recv, "recv", node->nd_recv);
+ }
+ else if (type == NODE_FCALL || type == NODE_VCALL) {
+ ADD_INSN(recv, nd_line(node), putself);
+ }
- /* args */
- if (type != NODE_VCALL && node->nd_args) {
- if (nd_type(node->nd_args) == NODE_SPLAT) {
- COMPILE(args, "args(splat)", node->nd_args->nd_head);
- argc = INT2FIX(1);
- flag |= VM_CALL_ARGS_SPLAT_BIT;
- }
- else if (nd_type(node->nd_args) == NODE_ARGSCAT) {
- NODE *t = node->nd_args->nd_head;
- for (argc = 0; t; argc++, t = t->nd_next) {
- /* */
- }
- argc = INT2FIX(argc + 1);
+ /* args */
+ if (type != NODE_VCALL && node->nd_args) {
+ if (nd_type(node->nd_args) == NODE_SPLAT) {
+ COMPILE(args, "args(splat)", node->nd_args->nd_head);
+ argc = INT2FIX(1);
+ flag |= VM_CALL_ARGS_SPLAT_BIT;
+ }
+ else if (nd_type(node->nd_args) == NODE_ARGSCAT) {
+ NODE *t = node->nd_args->nd_head;
+ for (argc = 0; t; argc++, t = t->nd_next) {
+ /* */
+ }
+ argc = INT2FIX(argc + 1);
- compile_array(iseq, args, node->nd_args->nd_head, Qfalse);
- POP_ELEMENT(args);
+ compile_array(iseq, args, node->nd_args->nd_head, Qfalse);
+ POP_ELEMENT(args);
- // argc = INT2FIX(LIST_SIZE(args) + 1);
- COMPILE(args, "args(cat: splat)", node->nd_args->nd_body);
+ // argc = INT2FIX(LIST_SIZE(args) + 1);
+ COMPILE(args, "args(cat: splat)", node->nd_args->nd_body);
- flag |= VM_CALL_ARGS_SPLAT_BIT;
- }
- else {
- compile_array(iseq, args, node->nd_args, Qfalse);
- argc = OPERAND_AT(POP_ELEMENT(args), 0);
- }
- }
- else {
- argc = INT2FIX(0);
- }
+ flag |= VM_CALL_ARGS_SPLAT_BIT;
+ }
+ else {
+ compile_array(iseq, args, node->nd_args, Qfalse);
+ argc = OPERAND_AT(POP_ELEMENT(args), 0);
+ }
+ }
+ else {
+ argc = INT2FIX(0);
+ }
- ADD_SEQ(ret, recv);
- ADD_SEQ(ret, args);
+ ADD_SEQ(ret, recv);
+ ADD_SEQ(ret, args);
- /* block */
- if (parent_blockval) {
- if (parent_blockval & 1) {
- flag |= VM_CALL_ARGS_BLOCKARG_BIT;
- ADD_SEQ(ret, (LINK_ANCHOR *)(parent_blockval & (~1)));
- }
- else {
- block = parent_blockval;
- }
- }
+ /* block */
+ if (parent_blockval) {
+ if (parent_blockval & 1) {
+ flag |= VM_CALL_ARGS_BLOCKARG_BIT;
+ ADD_SEQ(ret, (LINK_ANCHOR *)(parent_blockval & (~1)));
+ }
+ else {
+ block = parent_blockval;
+ }
+ }
- debugp_param("call args argc", argc);
- debugp_param("call method", ID2SYM(mid));
+ debugp_param("call args argc", argc);
+ debugp_param("call method", ID2SYM(mid));
- switch (nd_type(node)) {
+ switch (nd_type(node)) {
case NODE_VCALL:
- flag |= VM_CALL_VCALL_BIT;
- /* VCALL is funcall, so fall through */
+ flag |= VM_CALL_VCALL_BIT;
+ /* VCALL is funcall, so fall through */
case NODE_FCALL:
- flag |= VM_CALL_FCALL_BIT;
- }
+ flag |= VM_CALL_FCALL_BIT;
+ }
- ADD_SEND_R(ret, nd_line(node), ID2SYM(mid), argc,
- block, INT2FIX(flag));
+ ADD_SEND_R(ret, nd_line(node), ID2SYM(mid), argc,
+ block, INT2FIX(flag));
- if (poped) {
- ADD_INSN(ret, nd_line(node), pop);
- }
- break;
- }
- case NODE_SUPER:
- case NODE_ZSUPER:{
- DECL_ANCHOR(args);
- VALUE argc;
- VALUE flag = 0;
- VALUE block = 0;
- VALUE parent_block = iseq->compile_data->current_block;
- iseq->compile_data->current_block = Qfalse;
+ if (poped) {
+ ADD_INSN(ret, nd_line(node), pop);
+ }
+ break;
+ }
+ case NODE_SUPER:
+ case NODE_ZSUPER:{
+ DECL_ANCHOR(args);
+ VALUE argc;
+ VALUE flag = 0;
+ VALUE block = 0;
+ VALUE parent_block = iseq->compile_data->current_block;
+ iseq->compile_data->current_block = Qfalse;
- if (nd_type(node) == NODE_SUPER) {
- /* args */
- if (type != NODE_VCALL && node->nd_args) {
- if (nd_type(node->nd_args) == NODE_SPLAT) {
- COMPILE(args, "args(splat)", node->nd_args->nd_head);
- argc = INT2FIX(1);
- flag |= VM_CALL_ARGS_SPLAT_BIT;
- }
- else if (nd_type(node->nd_args) == NODE_ARGSCAT) {
- compile_array(iseq, args, node->nd_args->nd_head,
- Qfalse);
- POP_ELEMENT(args);
+ if (nd_type(node) == NODE_SUPER) {
+ /* args */
+ if (type != NODE_VCALL && node->nd_args) {
+ if (nd_type(node->nd_args) == NODE_SPLAT) {
+ COMPILE(args, "args(splat)", node->nd_args->nd_head);
+ argc = INT2FIX(1);
+ flag |= VM_CALL_ARGS_SPLAT_BIT;
+ }
+ else if (nd_type(node->nd_args) == NODE_ARGSCAT) {
+ compile_array(iseq, args, node->nd_args->nd_head,
+ Qfalse);
+ POP_ELEMENT(args);
- argc = INT2FIX(LIST_SIZE(args) + 1);
- COMPILE(args, "args(cat: splat)",
- node->nd_args->nd_body);
- flag |= VM_CALL_ARGS_SPLAT_BIT;
- }
- else {
- compile_array(iseq, args, node->nd_args, Qfalse);
- argc = OPERAND_AT(POP_ELEMENT(args), 0);
- }
- }
- else {
- argc = INT2FIX(0);
- }
- }
- else {
- /* NODE_ZSUPER */
- int i;
- yarv_iseq_t *liseq = iseq->local_iseq;
+ argc = INT2FIX(LIST_SIZE(args) + 1);
+ COMPILE(args, "args(cat: splat)",
+ node->nd_args->nd_body);
+ flag |= VM_CALL_ARGS_SPLAT_BIT;
+ }
+ else {
+ compile_array(iseq, args, node->nd_args, Qfalse);
+ argc = OPERAND_AT(POP_ELEMENT(args), 0);
+ }
+ }
+ else {
+ argc = INT2FIX(0);
+ }
+ }
+ else {
+ /* NODE_ZSUPER */
+ int i;
+ yarv_iseq_t *liseq = iseq->local_iseq;
- argc = INT2FIX(liseq->argc);
+ argc = INT2FIX(liseq->argc);
- /* normal arguments */
- for (i = 0; i < liseq->argc; i++) {
- int idx = liseq->local_size - i;
- ADD_INSN1(args, nd_line(node), getlocal, INT2FIX(idx));
- }
- if (!liseq->arg_simple) {
- if (liseq->arg_opts) {
- /* optional arguments */
- int j;
- for (j = 0; j < liseq->arg_opts - 1; j++) {
- int idx = liseq->local_size - (i + j);
- ADD_INSN1(args, nd_line(node), getlocal,
- INT2FIX(idx));
- }
- i += j;
- argc = INT2FIX(i);
- }
- if (liseq->arg_rest) {
- /* rest arguments */
- int idx = liseq->local_size - liseq->arg_rest + 1;
- ADD_INSN1(args, nd_line(node), getlocal,
- INT2FIX(idx));
- argc = INT2FIX(liseq->arg_rest);
- flag |= VM_CALL_ARGS_SPLAT_BIT;
- }
- }
- }
+ /* normal arguments */
+ for (i = 0; i < liseq->argc; i++) {
+ int idx = liseq->local_size - i;
+ ADD_INSN1(args, nd_line(node), getlocal, INT2FIX(idx));
+ }
+ if (!liseq->arg_simple) {
+ if (liseq->arg_opts) {
+ /* optional arguments */
+ int j;
+ for (j = 0; j < liseq->arg_opts - 1; j++) {
+ int idx = liseq->local_size - (i + j);
+ ADD_INSN1(args, nd_line(node), getlocal,
+ INT2FIX(idx));
+ }
+ i += j;
+ argc = INT2FIX(i);
+ }
+ if (liseq->arg_rest) {
+ /* rest arguments */
+ int idx = liseq->local_size - liseq->arg_rest + 1;
+ ADD_INSN1(args, nd_line(node), getlocal,
+ INT2FIX(idx));
+ argc = INT2FIX(liseq->arg_rest);
+ flag |= VM_CALL_ARGS_SPLAT_BIT;
+ }
+ }
+ }
- /* dummy reciever */
- if (nd_type(node) == NODE_ZSUPER) {
- ADD_INSN1(ret, nd_line(node), putobject, Qfalse);
- }
- else {
- ADD_INSN1(ret, nd_line(node), putobject, Qtrue);
- }
- ADD_SEQ(ret, args);
+ /* dummy reciever */
+ if (nd_type(node) == NODE_ZSUPER) {
+ ADD_INSN1(ret, nd_line(node), putobject, Qfalse);
+ }
+ else {
+ ADD_INSN1(ret, nd_line(node), putobject, Qtrue);
+ }
+ ADD_SEQ(ret, args);
- /* block */
- if (parent_block) {
- if (parent_block & 1) {
- flag |= VM_CALL_ARGS_BLOCKARG_BIT;
- //dump_disasm_list((LINK_ANCHOR *)(parent_block & (~1)));
- ADD_SEQ(ret, (LINK_ANCHOR *)(parent_block & (~1)));
- }
- else {
- block = parent_block;
- }
- }
+ /* block */
+ if (parent_block) {
+ if (parent_block & 1) {
+ flag |= VM_CALL_ARGS_BLOCKARG_BIT;
+ //dump_disasm_list((LINK_ANCHOR *)(parent_block & (~1)));
+ ADD_SEQ(ret, (LINK_ANCHOR *)(parent_block & (~1)));
+ }
+ else {
+ block = parent_block;
+ }
+ }
- ADD_INSN3(ret, nd_line(node), super, argc, block, INT2FIX(flag));
+ ADD_INSN3(ret, nd_line(node), super, argc, block, INT2FIX(flag));
- if (poped) {
- ADD_INSN(ret, nd_line(node), pop);
- }
- break;
- }
- case NODE_ARRAY:{
- compile_array(iseq, ret, node, Qtrue);
- if (poped) {
- ADD_INSN(ret, nd_line(node), pop);
- }
- break;
- }
- case NODE_ZARRAY:{
- if (!poped) {
- ADD_INSN1(ret, nd_line(node), newarray, INT2FIX(0));
- }
- break;
- }
- case NODE_VALUES:{
- NODE *n = node;
- while (n) {
- COMPILE(ret, "values item", n->nd_head);
- n = n->nd_next;
- }
- ADD_INSN1(ret, nd_line(node), newarray, INT2FIX(node->nd_alen));
- if (poped) {
- ADD_INSN(ret, nd_line(node), pop);
- }
- break;
- }
- case NODE_HASH:{
- DECL_ANCHOR(list);
- VALUE size = 0;
- int type = node->nd_head ? nd_type(node->nd_head) : NODE_ZARRAY;
+ if (poped) {
+ ADD_INSN(ret, nd_line(node), pop);
+ }
+ break;
+ }
+ case NODE_ARRAY:{
+ compile_array(iseq, ret, node, Qtrue);
+ if (poped) {
+ ADD_INSN(ret, nd_line(node), pop);
+ }
+ break;
+ }
+ case NODE_ZARRAY:{
+ if (!poped) {
+ ADD_INSN1(ret, nd_line(node), newarray, INT2FIX(0));
+ }
+ break;
+ }
+ case NODE_VALUES:{
+ NODE *n = node;
+ while (n) {
+ COMPILE(ret, "values item", n->nd_head);
+ n = n->nd_next;
+ }
+ ADD_INSN1(ret, nd_line(node), newarray, INT2FIX(node->nd_alen));
+ if (poped) {
+ ADD_INSN(ret, nd_line(node), pop);
+ }
+ break;
+ }
+ case NODE_HASH:{
+ DECL_ANCHOR(list);
+ VALUE size = 0;
+ int type = node->nd_head ? nd_type(node->nd_head) : NODE_ZARRAY;
- switch (type) {
+ switch (type) {
case NODE_ARRAY:{
- compile_array(iseq, list, node->nd_head, Qfalse);
- size = OPERAND_AT(POP_ELEMENT(list), 0);
- ADD_SEQ(ret, list);
- break;
- }
+ compile_array(iseq, list, node->nd_head, Qfalse);
+ size = OPERAND_AT(POP_ELEMENT(list), 0);
+ ADD_SEQ(ret, list);
+ break;
+ }
case NODE_ZARRAY:
- size = INT2FIX(0);
- break;
+ size = INT2FIX(0);
+ break;
default:
- COMPILE_ERROR(("can't make hash with this node: %s",
- node_name(type)));
- }
+ COMPILE_ERROR(("can't make hash with this node: %s",
+ node_name(type)));
+ }
- ADD_INSN1(ret, nd_line(node), newhash, size);
+ ADD_INSN1(ret, nd_line(node), newhash, size);
- if (poped) {
- ADD_INSN(ret, nd_line(node), pop);
- }
- break;
- }
- case NODE_RETURN:{
- yarv_iseq_t *is = iseq;
+ if (poped) {
+ ADD_INSN(ret, nd_line(node), pop);
+ }
+ break;
+ }
+ case NODE_RETURN:{
+ yarv_iseq_t *is = iseq;
- while (is) {
- if (is->type == ISEQ_TYPE_TOP || is->type == ISEQ_TYPE_CLASS) {
- COMPILE_ERROR(("Illegal return"));
- break;
- }
- else {
- if (is->type == ISEQ_TYPE_METHOD) {
- ADD_INSN(ret, nd_line(node), emptstack);
- }
+ while (is) {
+ if (is->type == ISEQ_TYPE_TOP || is->type == ISEQ_TYPE_CLASS) {
+ COMPILE_ERROR(("Illegal return"));
+ break;
+ }
+ else {
+ if (is->type == ISEQ_TYPE_METHOD) {
+ ADD_INSN(ret, nd_line(node), emptstack);
+ }
- COMPILE(ret, "return nd_stts (return val)",
- node->nd_stts);
+ COMPILE(ret, "return nd_stts (return val)",
+ node->nd_stts);
- if (is->type == ISEQ_TYPE_METHOD) {
- add_ensure_iseq(ret, iseq);
- ADD_INSN(ret, nd_line(node), end);
- }
- else {
- ADD_INSN1(ret, nd_line(node), throw,
- INT2FIX(0x01) /* TAG_RETURN */ );
- }
- break;
- }
- }
+ if (is->type == ISEQ_TYPE_METHOD) {
+ add_ensure_iseq(ret, iseq);
+ ADD_INSN(ret, nd_line(node), end);
+ }
+ else {
+ ADD_INSN1(ret, nd_line(node), throw,
+ INT2FIX(0x01) /* TAG_RETURN */ );
+ }
+ break;
+ }
+ }
- break;
- }
- case NODE_YIELD:{
- DECL_ANCHOR(args);
- int argc;
- unsigned long flag = 0;
+ break;
+ }
+ case NODE_YIELD:{
+ DECL_ANCHOR(args);
+ int argc;
+ unsigned long flag = 0;
- if (iseq->type == ISEQ_TYPE_TOP || iseq->type == ISEQ_TYPE_CLASS) {
- COMPILE_ERROR(("Illegal yield"));
- }
+ if (iseq->type == ISEQ_TYPE_TOP || iseq->type == ISEQ_TYPE_CLASS) {
+ COMPILE_ERROR(("Illegal yield"));
+ }
- if (node->nd_head) {
- if (nd_type(node->nd_head) == NODE_ARRAY) {
- NODE *p;
- for (argc = 0, p = node->nd_head; p;
- p = p->nd_next, argc++) {
- /* count argc */
- }
- if (argc == 1) {
- COMPILE(args, "yield with an arg", node->nd_head);
- }
- else {
- compile_array(iseq, args, node->nd_head, Qfalse);
- POP_ELEMENT(args);
- }
- debugs("argc: %d\n", argc);
- }
- else {
- if (nd_type(node->nd_head) == NODE_ARGSCAT) {
- if (node->nd_state == 2) {
- flag |= VM_CALL_ARGS_SPLAT_BIT;
- }
+ if (node->nd_head) {
+ if (nd_type(node->nd_head) == NODE_ARRAY) {
+ NODE *p;
+ for (argc = 0, p = node->nd_head; p;
+ p = p->nd_next, argc++) {
+ /* count argc */
+ }
+ if (argc == 1) {
+ COMPILE(args, "yield with an arg", node->nd_head);
+ }
+ else {
+ compile_array(iseq, args, node->nd_head, Qfalse);
+ POP_ELEMENT(args);
+ }
+ debugs("argc: %d\n", argc);
+ }
+ else {
+ if (nd_type(node->nd_head) == NODE_ARGSCAT) {
+ if (node->nd_state == 2) {
+ flag |= VM_CALL_ARGS_SPLAT_BIT;
+ }
- compile_array(iseq, args, node->nd_head->nd_head,
- Qfalse);
- POP_ELEMENT(args);
- argc = LIST_SIZE(args) + 1;
+ compile_array(iseq, args, node->nd_head->nd_head,
+ Qfalse);
+ POP_ELEMENT(args);
+ argc = LIST_SIZE(args) + 1;
- COMPILE(args, "args(cat: splat)",
- node->nd_head->nd_body);
- }
- else if (nd_type(node->nd_head) == NODE_SPLAT) {
- if (node->nd_state == 2) {
- flag |= VM_CALL_ARGS_SPLAT_BIT;
- }
+ COMPILE(args, "args(cat: splat)",
+ node->nd_head->nd_body);
+ }
+ else if (nd_type(node->nd_head) == NODE_SPLAT) {
+ if (node->nd_state == 2) {
+ flag |= VM_CALL_ARGS_SPLAT_BIT;
+ }
- argc = 1;
- COMPILE(args, "splat", node->nd_head->nd_head);
- }
- else {
- COMPILE(args, "nd_head(1)", node->nd_head);
- argc = 1;
- }
- }
- }
- else {
- argc = 0;
- }
- ADD_SEQ(ret, args);
- ADD_INSN2(ret, nd_line(node), yield, INT2FIX(argc),
- INT2FIX(flag));
+ argc = 1;
+ COMPILE(args, "splat", node->nd_head->nd_head);
+ }
+ else {
+ COMPILE(args, "nd_head(1)", node->nd_head);
+ argc = 1;
+ }
+ }
+ }
+ else {
+ argc = 0;
+ }
+ ADD_SEQ(ret, args);
+ ADD_INSN2(ret, nd_line(node), yield, INT2FIX(argc),
+ INT2FIX(flag));
- if (poped) {
- ADD_INSN(ret, nd_line(node), pop);
- }
- break;
- }
- case NODE_LVAR:{
- if (!poped) {
- int idx = iseq->local_iseq->local_size + 2 - node->nd_cnt;
- debugs("idx: %d\n", idx);
- ADD_INSN1(ret, nd_line(node), getlocal, INT2FIX(idx));
- }
- break;
- }
- case NODE_DVAR:{
- int lv, idx, ls;
- debugi("nd_vid", node->nd_vid);
- if (!poped) {
- idx = get_dyna_var_idx(iseq, node->nd_vid, &lv, &ls);
- if (idx < 0) {
- rb_bug("unknown dvar (%s)", rb_id2name(node->nd_vid));
- }
- ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(ls - idx),
- INT2FIX(lv));
- }
- break;
- }
- case NODE_GVAR:{
- ADD_INSN1(ret, nd_line(node), getglobal,
- (((long)node->nd_entry) | 1));
- if (poped) {
- ADD_INSN(ret, nd_line(node), pop);
- }
- break;
- }
- case NODE_IVAR:{
- debugi("nd_vid", node->nd_vid);
- if (!poped) {
- ADD_INSN1(ret, nd_line(node), getinstancevariable,
- ID2SYM(node->nd_vid));
- }
- break;
- }
- case NODE_CONST:{
- LABEL *lstart = NEW_LABEL(nd_line(node));
- LABEL *lend = NEW_LABEL(nd_line(node));
- debugi("nd_vid", node->nd_vid);
+ if (poped) {
+ ADD_INSN(ret, nd_line(node), pop);
+ }
+ break;
+ }
+ case NODE_LVAR:{
+ if (!poped) {
+ int idx = iseq->local_iseq->local_size + 2 - node->nd_cnt;
+ debugs("idx: %d\n", idx);
+ ADD_INSN1(ret, nd_line(node), getlocal, INT2FIX(idx));
+ }
+ break;
+ }
+ case NODE_DVAR:{
+ int lv, idx, ls;
+ debugi("nd_vid", node->nd_vid);
+ if (!poped) {
+ idx = get_dyna_var_idx(iseq, node->nd_vid, &lv, &ls);
+ if (idx < 0) {
+ rb_bug("unknown dvar (%s)", rb_id2name(node->nd_vid));
+ }
+ ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(ls - idx),
+ INT2FIX(lv));
+ }
+ break;
+ }
+ case NODE_GVAR:{
+ ADD_INSN1(ret, nd_line(node), getglobal,
+ (((long)node->nd_entry) | 1));
+ if (poped) {
+ ADD_INSN(ret, nd_line(node), pop);
+ }
+ break;
+ }
+ case NODE_IVAR:{
+ debugi("nd_vid", node->nd_vid);
+ if (!poped) {
+ ADD_INSN1(ret, nd_line(node), getinstancevariable,
+ ID2SYM(node->nd_vid));
+ }
+ break;
+ }
+ case NODE_CONST:{
+ LABEL *lstart = NEW_LABEL(nd_line(node));
+ LABEL *lend = NEW_LABEL(nd_line(node));
+ debugi("nd_vid", node->nd_vid);
- ADD_LABEL(ret, lstart);
- ADD_INSN2(ret, nd_line(node), getinlinecache,
- NEW_INLINE_CACHE_ENTRY(), lend);
- ADD_INSN1(ret, nd_line(node), getconstant, ID2SYM(node->nd_vid));
- ADD_INSN1(ret, nd_line(node), setinlinecache, lstart);
- ADD_LABEL(ret, lend);
+ ADD_LABEL(ret, lstart);
+ ADD_INSN2(ret, nd_line(node), getinlinecache,
+ NEW_INLINE_CACHE_ENTRY(), lend);
+ ADD_INSN1(ret, nd_line(node), getconstant, ID2SYM(node->nd_vid));
+ ADD_INSN1(ret, nd_line(node), setinlinecache, lstart);
+ ADD_LABEL(ret, lend);
- if (poped) {
- ADD_INSN(ret, nd_line(node), pop);
- }
- break;
- }
- case NODE_CVAR:{
- if (!poped) {
- ADD_INSN1(ret, nd_line(node), getclassvariable,
- ID2SYM(node->nd_vid));
- }
- break;
- }
- case NODE_NTH_REF:{
- ADD_INSN2(ret, nd_line(node), getspecial, INT2FIX(node->nd_cnt),
- INT2FIX(node->nd_nth << 1));
- break;
- }
- case NODE_BACK_REF:{
- ADD_INSN2(ret, nd_line(node), getspecial, INT2FIX(node->nd_cnt),
- INT2FIX(0x01 | (node->nd_nth << 1)));
- break;
- }
- case NODE_MATCH:
- case NODE_MATCH2:
- case NODE_MATCH3:{
- DECL_ANCHOR(recv);
- DECL_ANCHOR(val);
+ if (poped) {
+ ADD_INSN(ret, nd_line(node), pop);
+ }
+ break;
+ }
+ case NODE_CVAR:{
+ if (!poped) {
+ ADD_INSN1(ret, nd_line(node), getclassvariable,
+ ID2SYM(node->nd_vid));
+ }
+ break;
+ }
+ case NODE_NTH_REF:{
+ ADD_INSN2(ret, nd_line(node), getspecial, INT2FIX(node->nd_cnt),
+ INT2FIX(node->nd_nth << 1));
+ break;
+ }
+ case NODE_BACK_REF:{
+ ADD_INSN2(ret, nd_line(node), getspecial, INT2FIX(node->nd_cnt),
+ INT2FIX(0x01 | (node->nd_nth << 1)));
+ break;
+ }
+ case NODE_MATCH:
+ case NODE_MATCH2:
+ case NODE_MATCH3:{
+ DECL_ANCHOR(recv);
+ DECL_ANCHOR(val);
- if (nd_type(node) == NODE_MATCH) {
- ADD_INSN1(recv, nd_line(node), putobject, node->nd_lit);
- ADD_INSN2(val, nd_line(node), getspecial, INT2FIX(0),
- INT2FIX(0));
- }
- else {
- COMPILE(recv, "reciever", node->nd_recv);
- COMPILE(val, "value", node->nd_value);
- }
+ if (nd_type(node) == NODE_MATCH) {
+ ADD_INSN1(recv, nd_line(node), putobject, node->nd_lit);
+ ADD_INSN2(val, nd_line(node), getspecial, INT2FIX(0),
+ INT2FIX(0));
+ }
+ else {
+ COMPILE(recv, "reciever", node->nd_recv);
+ COMPILE(val, "value", node->nd_value);
+ }
#if OPT_BASIC_OPERATIONS
- /* TODO: detect by node */
- if (recv->last == recv->anchor.next &&
- INSN_OF(recv->last) == BIN(putobject)) {
- ADD_SEQ(ret, val);
- ADD_INSN1(ret, nd_line(node), opt_regexpmatch1,
- OPERAND_AT(recv->last, 0));
- }
- else {
- ADD_SEQ(ret, recv);
- ADD_SEQ(ret, val);
- ADD_INSN(ret, nd_line(node), opt_regexpmatch2);
- }
+ /* TODO: detect by node */
+ if (recv->last == recv->anchor.next &&
+ INSN_OF(recv->last) == BIN(putobject)) {
+ ADD_SEQ(ret, val);
+ ADD_INSN1(ret, nd_line(node), opt_regexpmatch1,
+ OPERAND_AT(recv->last, 0));
+ }
+ else {
+ ADD_SEQ(ret, recv);
+ ADD_SEQ(ret, val);
+ ADD_INSN(ret, nd_line(node), opt_regexpmatch2);
+ }
#else
- ADD_SEQ(ret, recv);
- ADD_SEQ(ret, val);
- ADD_SEND(ret, nd_line(node), ID2SYM(idEqTilde), INT2FIX(1));
+ ADD_SEQ(ret, recv);
+ ADD_SEQ(ret, val);
+ ADD_SEND(ret, nd_line(node), ID2SYM(idEqTilde), INT2FIX(1));
#endif
- if (poped) {
- ADD_INSN(ret, nd_line(node), pop);
- }
- break;
- }
- case NODE_LIT:{
- debugp_param("lit", node->nd_lit);
- if (!poped) {
- ADD_INSN1(ret, nd_line(node), putobject, node->nd_lit);
- }
- break;
- }
- case NODE_STR:{
- debugp_param("nd_lit", node->nd_lit);
- if (!poped) {
- ADD_INSN1(ret, nd_line(node), putstring, node->nd_lit);
- }
- break;
- }
- case NODE_DSTR:{
- compile_dstr(iseq, ret, node);
+ if (poped) {
+ ADD_INSN(ret, nd_line(node), pop);
+ }
+ break;
+ }
+ case NODE_LIT:{
+ debugp_param("lit", node->nd_lit);
+ if (!poped) {
+ ADD_INSN1(ret, nd_line(node), putobject, node->nd_lit);
+ }
+ break;
+ }
+ case NODE_STR:{
+ debugp_param("nd_lit", node->nd_lit);
+ if (!poped) {
+ ADD_INSN1(ret, nd_line(node), putstring, node->nd_lit);
+ }
+ break;
+ }
+ case NODE_DSTR:{
+ compile_dstr(iseq, ret, node);
- if (poped) {
- ADD_INSN(ret, nd_line(node), pop);
- }
- break;
- }
- case NODE_XSTR:{
- ADD_INSN(ret, nd_line(node), putself);
- ADD_INSN1(ret, nd_line(node), putobject, node->nd_lit);
- ADD_CALL(ret, nd_line(node), ID2SYM(idBackquote), INT2FIX(1));
+ if (poped) {
+ ADD_INSN(ret, nd_line(node), pop);
+ }
+ break;
+ }
+ case NODE_XSTR:{
+ ADD_INSN(ret, nd_line(node), putself);
+ ADD_INSN1(ret, nd_line(node), putobject, node->nd_lit);
+ ADD_CALL(ret, nd_line(node), ID2SYM(idBackquote), INT2FIX(1));
- if (poped) {
- ADD_INSN(ret, nd_line(node), pop);
- }
- break;
- }
- case NODE_DXSTR:{
- ADD_INSN(ret, nd_line(node), putself);
- compile_dstr(iseq, ret, node);
- ADD_CALL(ret, nd_line(node), ID2SYM(idBackquote), INT2FIX(1));
+ if (poped) {
+ ADD_INSN(ret, nd_line(node), pop);
+ }
+ break;
+ }
+ case NODE_DXSTR:{
+ ADD_INSN(ret, nd_line(node), putself);
+ compile_dstr(iseq, ret, node);
+ ADD_CALL(ret, nd_line(node), ID2SYM(idBackquote), INT2FIX(1));
- if (poped) {
- ADD_INSN(ret, nd_line(node), pop);
- }
- break;
- }
- case NODE_EVSTR:{
- COMPILE(ret, "nd_body", node->nd_body);
+ if (poped) {
+ ADD_INSN(ret, nd_line(node), pop);
+ }
+ break;
+ }
+ case NODE_EVSTR:{
+ COMPILE(ret, "nd_body", node->nd_body);
- if (poped) {
- ADD_INSN(ret, nd_line(node), pop);
- }
- else {
- ADD_INSN(ret, nd_line(node), tostring);
- }
- break;
- }
- case NODE_DREGX:{
- compile_dstr(iseq, ret, node);
- ADD_INSN1(ret, nd_line(node), toregexp, INT2FIX(node->nd_cflag));
+ if (poped) {
+ ADD_INSN(ret, nd_line(node), pop);
+ }
+ else {
+ ADD_INSN(ret, nd_line(node), tostring);
+ }
+ break;
+ }
+ case NODE_DREGX:{
+ compile_dstr(iseq, ret, node);
+ ADD_INSN1(ret, nd_line(node), toregexp, INT2FIX(node->nd_cflag));
- if (poped) {
- ADD_INSN(ret, nd_line(node), pop);
- }
- break;
- }
- case NODE_DREGX_ONCE:{
- /* fix me: once? */
- LABEL *lstart = NEW_LABEL(nd_line(node));
- LABEL *lend = NEW_LABEL(nd_line(node));
+ if (poped) {
+ ADD_INSN(ret, nd_line(node), pop);
+ }
+ break;
+ }
+ case NODE_DREGX_ONCE:{
+ /* fix me: once? */
+ LABEL *lstart = NEW_LABEL(nd_line(node));
+ LABEL *lend = NEW_LABEL(nd_line(node));
- ADD_LABEL(ret, lstart);
- ADD_INSN2(ret, nd_line(node), onceinlinecache,
- NEW_INLINE_CACHE_ENTRY(), lend);
- ADD_INSN(ret, nd_line(node), pop);
+ ADD_LABEL(ret, lstart);
+ ADD_INSN2(ret, nd_line(node), onceinlinecache,
+ NEW_INLINE_CACHE_ENTRY(), lend);
+ ADD_INSN(ret, nd_line(node), pop);
- compile_dstr(iseq, ret, node);
- ADD_INSN1(ret, nd_line(node), toregexp, INT2FIX(node->nd_cflag));
+ compile_dstr(iseq, ret, node);
+ ADD_INSN1(ret, nd_line(node), toregexp, INT2FIX(node->nd_cflag));
- ADD_INSN1(ret, nd_line(node), setinlinecache, lstart);
- ADD_LABEL(ret, lend);
+ ADD_INSN1(ret, nd_line(node), setinlinecache, lstart);
+ ADD_LABEL(ret, lend);
- if (poped) {
- ADD_INSN(ret, nd_line(node), pop);
- }
- break;
- }
- case NODE_ARGS:{
- /* OK */
- COMPILE_ERROR(("BUG: should not reach here: compile_each#NODE_ARGS"));
- break;
- }
- case NODE_ARGSCAT:{
- COMPILE(ret, "argscat body", node->nd_head);
- COMPILE(ret, "argscat body", node->nd_body);
- ADD_INSN(ret, nd_line(node), concatarray);
- break;
- }
- case NODE_ARGSPUSH:{
- /* OK */
- COMPILE_ERROR(("BUG: unknown node: NODE_ARGSPUSH"));
- break;
- }
- case NODE_SPLAT:{
- COMPILE(ret, "splat", node->nd_head);
- ADD_INSN1(ret, nd_line(node), splatarray, Qfalse);
- break;
- }
- case NODE_TO_ARY:{
- /* OK */
- COMPILE_ERROR(("BUG: unknown node: NODE_TO_ARY"));
- break;
- }
- case NODE_SVALUE:{
- COMPILE(ret, "svalue head", node->nd_head);
- ADD_INSN1(ret, nd_line(node), splatarray, Qtrue);
- break;
- }
- case NODE_BLOCK_ARG:{
- iseq->arg_block = node->nd_cnt - 2 + 1;
- iseq->arg_simple = 0;
+ if (poped) {
+ ADD_INSN(ret, nd_line(node), pop);
+ }
+ break;
+ }
+ case NODE_ARGS:{
+ /* OK */
+ COMPILE_ERROR(("BUG: should not reach here: compile_each#NODE_ARGS"));
+ break;
+ }
+ case NODE_ARGSCAT:{
+ COMPILE(ret, "argscat body", node->nd_head);
+ COMPILE(ret, "argscat body", node->nd_body);
+ ADD_INSN(ret, nd_line(node), concatarray);
+ break;
+ }
+ case NODE_ARGSPUSH:{
+ /* OK */
+ COMPILE_ERROR(("BUG: unknown node: NODE_ARGSPUSH"));
+ break;
+ }
+ case NODE_SPLAT:{
+ COMPILE(ret, "splat", node->nd_head);
+ ADD_INSN1(ret, nd_line(node), splatarray, Qfalse);
+ break;
+ }
+ case NODE_TO_ARY:{
+ /* OK */
+ COMPILE_ERROR(("BUG: unknown node: NODE_TO_ARY"));
+ break;
+ }
+ case NODE_SVALUE:{
+ COMPILE(ret, "svalue head", node->nd_head);
+ ADD_INSN1(ret, nd_line(node), splatarray, Qtrue);
+ break;
+ }
+ case NODE_BLOCK_ARG:{
+ iseq->arg_block = node->nd_cnt - 2 + 1;
+ iseq->arg_simple = 0;
- break;
- }
- case NODE_BLOCK_PASS:{
- VALUE prevblock = iseq->compile_data->current_block;
- LABEL *retry_label = NEW_LABEL(nd_line(node));
- LABEL *retry_end_l = NEW_LABEL(nd_line(node));
- DECL_ANCHOR(current_block);
+ break;
+ }
+ case NODE_BLOCK_PASS:{
+ VALUE prevblock = iseq->compile_data->current_block;
+ LABEL *retry_label = NEW_LABEL(nd_line(node));
+ LABEL *retry_end_l = NEW_LABEL(nd_line(node));
+ DECL_ANCHOR(current_block);
- COMPILE(current_block, "block pass proc", node->nd_body);
+ COMPILE(current_block, "block pass proc", node->nd_body);
- iseq->compile_data->current_block = (VALUE)current_block | 1;
- ADD_LABEL(ret, retry_label);
- COMPILE_(ret, "iter caller (NODE_BLOCK_PASS)", node->nd_iter,
- poped);
- ADD_LABEL(ret, retry_end_l);
+ iseq->compile_data->current_block = (VALUE)current_block | 1;
+ ADD_LABEL(ret, retry_label);
+ COMPILE_(ret, "iter caller (NODE_BLOCK_PASS)", node->nd_iter,
+ poped);
+ ADD_LABEL(ret, retry_end_l);
- iseq->compile_data->current_block = prevblock;
- ADD_CATCH_ENTRY(CATCH_TYPE_RETRY, retry_label, retry_end_l, 0,
- retry_label);
- break;
- }
- case NODE_DEFN:{
- VALUE iseqval = NEW_ISEQVAL(node->nd_defn,
- rb_str_new2(rb_id2name(node->nd_mid)),
- ISEQ_TYPE_METHOD);
+ iseq->compile_data->current_block = prevblock;
+ ADD_CATCH_ENTRY(CATCH_TYPE_RETRY, retry_label, retry_end_l, 0,
+ retry_label);
+ break;
+ }
+ case NODE_DEFN:{
+ VALUE iseqval = NEW_ISEQVAL(node->nd_defn,
+ rb_str_new2(rb_id2name(node->nd_mid)),
+ ISEQ_TYPE_METHOD);
- debugp_param("defn/iseq", iseqval);
+ debugp_param("defn/iseq", iseqval);
- ADD_INSN2(ret, nd_line(node), methoddef, ID2SYM(node->nd_mid),
- iseqval);
- if (!poped) {
- ADD_INSN(ret, nd_line(node), putnil);
- }
- debugp_param("defn", iseqval);
- break;
- }
- case NODE_DEFS:{
- VALUE iseqval = NEW_ISEQVAL(node->nd_defn,
- rb_str_new2(rb_id2name(node->nd_mid)),
- ISEQ_TYPE_METHOD);
+ ADD_INSN2(ret, nd_line(node), methoddef, ID2SYM(node->nd_mid),
+ iseqval);
+ if (!poped) {
+ ADD_INSN(ret, nd_line(node), putnil);
+ }
+ debugp_param("defn", iseqval);
+ break;
+ }
+ case NODE_DEFS:{
+ VALUE iseqval = NEW_ISEQVAL(node->nd_defn,
+ rb_str_new2(rb_id2name(node->nd_mid)),
+ ISEQ_TYPE_METHOD);
- debugp_param("defs/iseq", iseqval);
+ debugp_param("defs/iseq", iseqval);
- COMPILE(ret, "defs: recv", node->nd_recv);
- ADD_INSN2(ret, nd_line(node), singletonmethoddef,
- ID2SYM(node->nd_mid), iseqval);
- if (!poped) {
- ADD_INSN(ret, nd_line(node), putnil);
- }
- break;
- }
- case NODE_ALIAS:{
- VALUE s1, s2;
+ COMPILE(ret, "defs: recv", node->nd_recv);
+ ADD_INSN2(ret, nd_line(node), singletonmethoddef,
+ ID2SYM(node->nd_mid), iseqval);
+ if (!poped) {
+ ADD_INSN(ret, nd_line(node), putnil);
+ }
+ break;
+ }
+ case NODE_ALIAS:{
+ VALUE s1, s2;
- if (nd_type(node->u1.node) != NODE_LIT ||
- nd_type(node->u2.node) != NODE_LIT) {
- rb_bug("alias args must be NODE_LIT");
- }
- s1 = node->u1.node->nd_lit;
- s2 = node->u2.node->nd_lit;
+ if (nd_type(node->u1.node) != NODE_LIT ||
+ nd_type(node->u2.node) != NODE_LIT) {
+ rb_bug("alias args must be NODE_LIT");
+ }
+ s1 = node->u1.node->nd_lit;
+ s2 = node->u2.node->nd_lit;
- ADD_INSN3(ret, nd_line(node), alias, Qfalse, ID2SYM(rb_to_id(s1)),
- ID2SYM(rb_to_id(s2)));
- if (!poped) {
- ADD_INSN(ret, nd_line(node), putnil);
- }
- break;
- }
- case NODE_VALIAS:{
- ADD_INSN3(ret, nd_line(node), alias, Qtrue, ID2SYM(node->u1.id),
- ID2SYM(node->u2.id));
- if (!poped) {
- ADD_INSN(ret, nd_line(node), putnil);
- }
- break;
- }
- case NODE_UNDEF:{
- if (nd_type(node->u2.node) != NODE_LIT) {
- rb_bug("undef args must be NODE_LIT");
- }
- ADD_INSN1(ret, nd_line(node), undef,
- ID2SYM(rb_to_id(node->u2.node->nd_lit)));
- if (!poped) {
- ADD_INSN(ret, nd_line(node), putnil);
- }
- break;
- }
- case NODE_CLASS:{
- VALUE iseqval = NEW_CHILD_ISEQVAL(node->nd_body,
- make_name_with_str("<class:%s>",
- rb_id2name
- (node->
- nd_cpath->
- nd_mid)),
- ISEQ_TYPE_CLASS);
+ ADD_INSN3(ret, nd_line(node), alias, Qfalse, ID2SYM(rb_to_id(s1)),
+ ID2SYM(rb_to_id(s2)));
+ if (!poped) {
+ ADD_INSN(ret, nd_line(node), putnil);
+ }
+ break;
+ }
+ case NODE_VALIAS:{
+ ADD_INSN3(ret, nd_line(node), alias, Qtrue, ID2SYM(node->u1.id),
+ ID2SYM(node->u2.id));
+ if (!poped) {
+ ADD_INSN(ret, nd_line(node), putnil);
+ }
+ break;
+ }
+ case NODE_UNDEF:{
+ if (nd_type(node->u2.node) != NODE_LIT) {
+ rb_bug("undef args must be NODE_LIT");
+ }
+ ADD_INSN1(ret, nd_line(node), undef,
+ ID2SYM(rb_to_id(node->u2.node->nd_lit)));
+ if (!poped) {
+ ADD_INSN(ret, nd_line(node), putnil);
+ }
+ break;
+ }
+ case NODE_CLASS:{
+ VALUE iseqval = NEW_CHILD_ISEQVAL(node->nd_body,
+ make_name_with_str("<class:%s>",
+ rb_id2name
+ (node->
+ nd_cpath->
+ nd_mid)),
+ ISEQ_TYPE_CLASS);
- COMPILE(ret, "cbase", node->nd_cpath->nd_head);
- COMPILE(ret, "super", node->nd_super);
- ADD_INSN2(ret, nd_line(node), classdef,
- ID2SYM(node->nd_cpath->nd_mid), iseqval);
+ COMPILE(ret, "cbase", node->nd_cpath->nd_head);
+ COMPILE(ret, "super", node->nd_super);
+ ADD_INSN2(ret, nd_line(node), classdef,
+ ID2SYM(node->nd_cpath->nd_mid), iseqval);
- if (poped) {
- ADD_INSN(ret, nd_line(node), pop);
- }
- break;
- }
- case NODE_MODULE:{
- VALUE iseqval = NEW_CHILD_ISEQVAL(node->nd_body,
- make_name_with_str
- ("<module:%s>",
- rb_id2name(node->nd_cpath->
- nd_mid)),
- ISEQ_TYPE_CLASS);
+ if (poped) {
+ ADD_INSN(ret, nd_line(node), pop);
+ }
+ break;
+ }
+ case NODE_MODULE:{
+ VALUE iseqval = NEW_CHILD_ISEQVAL(node->nd_body,
+ make_name_with_str
+ ("<module:%s>",
+ rb_id2name(node->nd_cpath->
+ nd_mid)),
+ ISEQ_TYPE_CLASS);
- COMPILE(ret, "mbase", node->nd_cpath->nd_head);
- ADD_INSN2(ret, nd_line(node), moduledef,
- ID2SYM(node->nd_cpath->nd_mid), iseqval);
- if (poped) {
- ADD_INSN(ret, nd_line(node), pop);
- }
- break;
- }
- case NODE_SCLASS:{
- VALUE iseqval =
- NEW_ISEQVAL(node->nd_body, rb_str_new2("singletonclass"),
- ISEQ_TYPE_CLASS);
+ COMPILE(ret, "mbase", node->nd_cpath->nd_head);
+ ADD_INSN2(ret, nd_line(node), moduledef,
+ ID2SYM(node->nd_cpath->nd_mid), iseqval);
+ if (poped) {
+ ADD_INSN(ret, nd_line(node), pop);
+ }
+ break;
+ }
+ case NODE_SCLASS:{
+ VALUE iseqval =
+ NEW_ISEQVAL(node->nd_body, rb_str_new2("singletonclass"),
+ ISEQ_TYPE_CLASS);
- COMPILE(ret, "sclass#recv", node->nd_recv);
- ADD_INSN1(ret, nd_line(node), singletonclassdef, iseqval);
+ COMPILE(ret, "sclass#recv", node->nd_recv);
+ ADD_INSN1(ret, nd_line(node), singletonclassdef, iseqval);
- if (poped) {
- ADD_INSN(ret, nd_line(node), pop);
- }
- break;
- }
- case NODE_COLON2:{
- if (rb_is_const_id(node->nd_mid)) {
- /* constant */
- LABEL *lstart = NEW_LABEL(nd_line(node));
- LABEL *lend = NEW_LABEL(nd_line(node));
- DECL_ANCHOR(pref);
- DECL_ANCHOR(body);
+ if (poped) {
+ ADD_INSN(ret, nd_line(node), pop);
+ }
+ break;
+ }
+ case NODE_COLON2:{
+ if (rb_is_const_id(node->nd_mid)) {
+ /* constant */
+ LABEL *lstart = NEW_LABEL(nd_line(node));
+ LABEL *lend = NEW_LABEL(nd_line(node));
+ DECL_ANCHOR(pref);
+ DECL_ANCHOR(body);
- compile_colon2(iseq, node, pref, body);
- if (LIST_SIZE_ZERO(pref)) {
- ADD_LABEL(ret, lstart);
- ADD_INSN2(ret, nd_line(node), getinlinecache,
- NEW_INLINE_CACHE_ENTRY(), lend);
- ADD_SEQ(ret, body);
- ADD_INSN1(ret, nd_line(node), setinlinecache, lstart);
- ADD_LABEL(ret, lend);
- }
- else {
- ADD_SEQ(ret, pref);
- ADD_SEQ(ret, body);
- }
- }
- else {
- /* function call */
- ADD_INSN(ret, nd_line(node), putself);
- COMPILE(ret, "colon2#nd_head", node->nd_head);
- ADD_CALL(ret, nd_line(node), ID2SYM(node->nd_mid),
- INT2FIX(1));
- }
- if (poped) {
- ADD_INSN(ret, nd_line(node), pop);
- }
- break;
- }
- case NODE_COLON3:{
- LABEL *lstart = NEW_LABEL(nd_line(node));
- LABEL *lend = NEW_LABEL(nd_line(node));
- debugi("colon3#nd_mid", node->nd_mid);
+ compile_colon2(iseq, node, pref, body);
+ if (LIST_SIZE_ZERO(pref)) {
+ ADD_LABEL(ret, lstart);
+ ADD_INSN2(ret, nd_line(node), getinlinecache,
+ NEW_INLINE_CACHE_ENTRY(), lend);
+ ADD_SEQ(ret, body);
+ ADD_INSN1(ret, nd_line(node), setinlinecache, lstart);
+ ADD_LABEL(ret, lend);
+ }
+ else {
+ ADD_SEQ(ret, pref);
+ ADD_SEQ(ret, body);
+ }
+ }
+ else {
+ /* function call */
+ ADD_INSN(ret, nd_line(node), putself);
+ COMPILE(ret, "colon2#nd_head", node->nd_head);
+ ADD_CALL(ret, nd_line(node), ID2SYM(node->nd_mid),
+ INT2FIX(1));
+ }
+ if (poped) {
+ ADD_INSN(ret, nd_line(node), pop);
+ }
+ break;
+ }
+ case NODE_COLON3:{
+ LABEL *lstart = NEW_LABEL(nd_line(node));
+ LABEL *lend = NEW_LABEL(nd_line(node));
+ debugi("colon3#nd_mid", node->nd_mid);
- /* add cache insn */
- ADD_LABEL(ret, lstart);
- ADD_INSN2(ret, nd_line(node), getinlinecache,
- NEW_INLINE_CACHE_ENTRY(), lend);
- ADD_INSN(ret, nd_line(node), pop);
- ADD_INSN1(ret, nd_line(node), putobject, rb_cObject);
- ADD_INSN1(ret, nd_line(node), getconstant, ID2SYM(node->nd_mid));
- ADD_INSN1(ret, nd_line(node), setinlinecache, lstart);
- ADD_LABEL(ret, lend);
+ /* add cache insn */
+ ADD_LABEL(ret, lstart);
+ ADD_INSN2(ret, nd_line(node), getinlinecache,
+ NEW_INLINE_CACHE_ENTRY(), lend);
+ ADD_INSN(ret, nd_line(node), pop);
+ ADD_INSN1(ret, nd_line(node), putobject, rb_cObject);
+ ADD_INSN1(ret, nd_line(node), getconstant, ID2SYM(node->nd_mid));
+ ADD_INSN1(ret, nd_line(node), setinlinecache, lstart);
+ ADD_LABEL(ret, lend);
- if (poped) {
- ADD_INSN(ret, nd_line(node), pop);
- }
- break;
- }
- case NODE_CREF:{
- /* OK */
- COMPILE_ERROR(("BUG: unknown node: NODE_CREF"));
- break;
- }
- case NODE_DOT2:
- case NODE_DOT3:{
- int flag = type == NODE_DOT2 ? INT2FIX(0) : INT2FIX(1);
- COMPILE(ret, "min", (NODE *) node->nd_beg);
- COMPILE(ret, "max", (NODE *) node->nd_end);
- if (poped) {
- ADD_INSN(ret, nd_line(node), pop);
- ADD_INSN(ret, nd_line(node), pop);
- }
- else {
- ADD_INSN1(ret, nd_line(node), newrange, flag);
- }
- break;
- }
- case NODE_FLIP2:
- case NODE_FLIP3:{
- LABEL *lend = NEW_LABEL(nd_line(node));
- LABEL *lfin = NEW_LABEL(nd_line(node));
- LABEL *ltrue = NEW_LABEL(nd_line(node));
+ if (poped) {
+ ADD_INSN(ret, nd_line(node), pop);
+ }
+ break;
+ }
+ case NODE_CREF:{
+ /* OK */
+ COMPILE_ERROR(("BUG: unknown node: NODE_CREF"));
+ break;
+ }
+ case NODE_DOT2:
+ case NODE_DOT3:{
+ int flag = type == NODE_DOT2 ? INT2FIX(0) : INT2FIX(1);
+ COMPILE(ret, "min", (NODE *) node->nd_beg);
+ COMPILE(ret, "max", (NODE *) node->nd_end);
+ if (poped) {
+ ADD_INSN(ret, nd_line(node), pop);
+ ADD_INSN(ret, nd_line(node), pop);
+ }
+ else {
+ ADD_INSN1(ret, nd_line(node), newrange, flag);
+ }
+ break;
+ }
+ case NODE_FLIP2:
+ case NODE_FLIP3:{
+ LABEL *lend = NEW_LABEL(nd_line(node));
+ LABEL *lfin = NEW_LABEL(nd_line(node));
+ LABEL *ltrue = NEW_LABEL(nd_line(node));
- ADD_INSN2(ret, nd_line(node), getspecial, INT2FIX(node->nd_cnt),
- INT2FIX(0));
- ADD_INSNL(ret, nd_line(node), if, lend) ;
+ ADD_INSN2(ret, nd_line(node), getspecial, INT2FIX(node->nd_cnt),
+ INT2FIX(0));
+ ADD_INSNL(ret, nd_line(node), if, lend) ;
- /* *flip == 0 */
- COMPILE(ret, "flip2 beg", node->nd_beg);
- ADD_INSN(ret, nd_line(node), dup);
- ADD_INSNL(ret, nd_line(node), unless, lfin);
- if (nd_type(node) == NODE_FLIP3) {
- ADD_INSN(ret, nd_line(node), dup);
- ADD_INSN2(ret, nd_line(node), setspecial,
- INT2FIX(node->nd_cnt), INT2FIX(0));
- ADD_INSNL(ret, nd_line(node), jump, lfin);
- }
- else {
- ADD_INSN2(ret, nd_line(node), setspecial,
- INT2FIX(node->nd_cnt), INT2FIX(0));
- }
+ /* *flip == 0 */
+ COMPILE(ret, "flip2 beg", node->nd_beg);
+ ADD_INSN(ret, nd_line(node), dup);
+ ADD_INSNL(ret, nd_line(node), unless, lfin);
+ if (nd_type(node) == NODE_FLIP3) {
+ ADD_INSN(ret, nd_line(node), dup);
+ ADD_INSN2(ret, nd_line(node), setspecial,
+ INT2FIX(node->nd_cnt), INT2FIX(0));
+ ADD_INSNL(ret, nd_line(node), jump, lfin);
+ }
+ else {
+ ADD_INSN2(ret, nd_line(node), setspecial,
+ INT2FIX(node->nd_cnt), INT2FIX(0));
+ }
- /* *flip == 1 */
- ADD_LABEL(ret, lend);
- COMPILE(ret, "flip2 end", node->nd_end);
- ADD_INSNL(ret, nd_line(node), unless, ltrue);
- ADD_INSN1(ret, nd_line(node), putobject, Qfalse);
- ADD_INSN2(ret, nd_line(node), setspecial, INT2FIX(node->nd_cnt),
- INT2FIX(0));
+ /* *flip == 1 */
+ ADD_LABEL(ret, lend);
+ COMPILE(ret, "flip2 end", node->nd_end);
+ ADD_INSNL(ret, nd_line(node), unless, ltrue);
+ ADD_INSN1(ret, nd_line(node), putobject, Qfalse);
+ ADD_INSN2(ret, nd_line(node), setspecial, INT2FIX(node->nd_cnt),
+ INT2FIX(0));
- ADD_LABEL(ret, ltrue);
- ADD_INSN1(ret, nd_line(node), putobject, Qtrue);
+ ADD_LABEL(ret, ltrue);
+ ADD_INSN1(ret, nd_line(node), putobject, Qtrue);
- ADD_LABEL(ret, lfin);
+ ADD_LABEL(ret, lfin);
- break;
- }
- case NODE_ATTRSET:{
- /* OK */
- COMPILE_ERROR(("BUG: unknown node: NODE_ATTRSET"));
- break;
- }
- case NODE_SELF:{
- if (!poped) {
- ADD_INSN(ret, nd_line(node), putself);
- }
+ break;
+ }
+ case NODE_ATTRSET:{
+ /* OK */
+ COMPILE_ERROR(("BUG: unknown node: NODE_ATTRSET"));
+ break;
+ }
+ case NODE_SELF:{
+ if (!poped) {
+ ADD_INSN(ret, nd_line(node), putself);
+ }
- break;
- }
- case NODE_NIL:{
- if (!poped) {
- ADD_INSN(ret, nd_line(node), putnil);
- }
- break;
- }
- case NODE_TRUE:{
- if (!poped) {
- ADD_INSN1(ret, nd_line(node), putobject, Qtrue);
- }
- break;
- }
- case NODE_FALSE:{
- if (!poped) {
- ADD_INSN1(ret, nd_line(node), putobject, Qfalse);
- }
- break;
- }
- case NODE_ERRINFO:{
- if (!poped) {
- if (iseq->type == ISEQ_TYPE_RESCUE) {
- ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(1),
- INT2FIX(0));
- }
- else {
- yarv_iseq_t *ip = iseq;
- int level = 0;
- while (ip) {
- if (ip->type == ISEQ_TYPE_RESCUE) {
- break;
- }
- ip = ip->parent_iseq;
- level++;
- }
- if (ip) {
- ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(1),
- INT2FIX(level));
- }
- else {
- ADD_INSN(ret, nd_line(node), putnil);
- }
- }
- }
- break;
- }
- case NODE_DEFINED:{
- if (!poped) {
- LABEL *lfinish = NEW_LABEL(nd_line(node));
- defined_expr(iseq, ret, node->nd_head, lfinish, Qtrue);
- ADD_LABEL(ret, lfinish);
- }
- break;
- }
- case NODE_POSTEXE:{
- ADD_INSN1(ret, nd_line(node), postexe,
- iseq->compile_data->current_block);
- if (!poped) {
- ADD_INSN(ret, nd_line(node), putnil);
- }
- break;
- }
+ break;
+ }
+ case NODE_NIL:{
+ if (!poped) {
+ ADD_INSN(ret, nd_line(node), putnil);
+ }
+ break;
+ }
+ case NODE_TRUE:{
+ if (!poped) {
+ ADD_INSN1(ret, nd_line(node), putobject, Qtrue);
+ }
+ break;
+ }
+ case NODE_FALSE:{
+ if (!poped) {
+ ADD_INSN1(ret, nd_line(node), putobject, Qfalse);
+ }
+ break;
+ }
+ case NODE_ERRINFO:{
+ if (!poped) {
+ if (iseq->type == ISEQ_TYPE_RESCUE) {
+ ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(1),
+ INT2FIX(0));
+ }
+ else {
+ yarv_iseq_t *ip = iseq;
+ int level = 0;
+ while (ip) {
+ if (ip->type == ISEQ_TYPE_RESCUE) {
+ break;
+ }
+ ip = ip->parent_iseq;
+ level++;
+ }
+ if (ip) {
+ ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(1),
+ INT2FIX(level));
+ }
+ else {
+ ADD_INSN(ret, nd_line(node), putnil);
+ }
+ }
+ }
+ break;
+ }
+ case NODE_DEFINED:{
+ if (!poped) {
+ LABEL *lfinish = NEW_LABEL(nd_line(node));
+ defined_expr(iseq, ret, node->nd_head, lfinish, Qtrue);
+ ADD_LABEL(ret, lfinish);
+ }
+ break;
+ }
+ case NODE_POSTEXE:{
+ ADD_INSN1(ret, nd_line(node), postexe,
+ iseq->compile_data->current_block);
+ if (!poped) {
+ ADD_INSN(ret, nd_line(node), putnil);
+ }
+ break;
+ }
#ifdef C_ALLOCA
- case NODE_ALLOCA:{
- /* OK */
- COMPILE_ERROR(("BUG: unknown node: NODE_ALLOCA"));
- break;
- }
+ case NODE_ALLOCA:{
+ /* OK */
+ COMPILE_ERROR(("BUG: unknown node: NODE_ALLOCA"));
+ break;
+ }
#endif
- case NODE_BMETHOD:{
- /* block method, OK */
- COMPILE_ERROR(("BUG: unknown node: NODE_BMETHOD"));
- break;
- }
- case NODE_MEMO:{
- /* OK */
- COMPILE_ERROR(("BUG: unknown node: NODE_MEMO"));
- break;
- }
- case NODE_IFUNC:{
- /* OK */
- COMPILE_ERROR(("BUG: unknown node: NODE_IFUNC"));
- break;
- }
- case NODE_DSYM:{
- compile_dstr(iseq, ret, node);
- if (!poped) {
- ADD_SEND(ret, nd_line(node), ID2SYM(idIntern), INT2FIX(0));
- }
- else {
- ADD_INSN(ret, nd_line(node), pop);
- }
- break;
- }
- case NODE_ATTRASGN:{
- DECL_ANCHOR(recv);
- DECL_ANCHOR(args);
- VALUE argc;
+ case NODE_BMETHOD:{
+ /* block method, OK */
+ COMPILE_ERROR(("BUG: unknown node: NODE_BMETHOD"));
+ break;
+ }
+ case NODE_MEMO:{
+ /* OK */
+ COMPILE_ERROR(("BUG: unknown node: NODE_MEMO"));
+ break;
+ }
+ case NODE_IFUNC:{
+ /* OK */
+ COMPILE_ERROR(("BUG: unknown node: NODE_IFUNC"));
+ break;
+ }
+ case NODE_DSYM:{
+ compile_dstr(iseq, ret, node);
+ if (!poped) {
+ ADD_SEND(ret, nd_line(node), ID2SYM(idIntern), INT2FIX(0));
+ }
+ else {
+ ADD_INSN(ret, nd_line(node), pop);
+ }
+ break;
+ }
+ case NODE_ATTRASGN:{
+ DECL_ANCHOR(recv);
+ DECL_ANCHOR(args);
+ VALUE argc;
- if (node->nd_args) {
- compile_array(iseq, args, node->nd_args, Qfalse);
- argc = OPERAND_AT(POP_ELEMENT(args), 0);
- }
- else {
- argc = INT2FIX(0); /* massign */
- }
+ if (node->nd_args) {
+ compile_array(iseq, args, node->nd_args, Qfalse);
+ argc = OPERAND_AT(POP_ELEMENT(args), 0);
+ }
+ else {
+ argc = INT2FIX(0); /* massign */
+ }
- if (node->nd_recv == (NODE *) 1) {
- ADD_INSN(recv, nd_line(node), putself);
- }
- else {
- COMPILE(recv, "recv", node->nd_recv);
- }
+ if (node->nd_recv == (NODE *) 1) {
+ ADD_INSN(recv, nd_line(node), putself);
+ }
+ else {
+ COMPILE(recv, "recv", node->nd_recv);
+ }
- debugp_param("argc", argc);
- debugp_param("nd_mid", ID2SYM(node->nd_mid));
+ debugp_param("argc", argc);
+ debugp_param("nd_mid", ID2SYM(node->nd_mid));
- ADD_SEQ(ret, recv);
- ADD_SEQ(ret, args);
+ ADD_SEQ(ret, recv);
+ ADD_SEQ(ret, args);
- ADD_SEND(ret, nd_line(node), ID2SYM(node->nd_mid), argc);
+ ADD_SEND(ret, nd_line(node), ID2SYM(node->nd_mid), argc);
- if (poped) {
- ADD_INSN(ret, nd_line(node), pop);
- }
- break;
- }
- case NODE_OPTBLOCK:{
- /* for optimize */
- LABEL *redo_label = NEW_LABEL(0);
- LABEL *next_label = NEW_LABEL(0);
+ if (poped) {
+ ADD_INSN(ret, nd_line(node), pop);
+ }
+ break;
+ }
+ case NODE_OPTBLOCK:{
+ /* for optimize */
+ LABEL *redo_label = NEW_LABEL(0);
+ LABEL *next_label = NEW_LABEL(0);
- iseq->compile_data->start_label = next_label;
- iseq->compile_data->redo_label = redo_label;
+ iseq->compile_data->start_label = next_label;
+ iseq->compile_data->redo_label = redo_label;
- ADD_LABEL(ret, redo_label);
- COMPILE_(ret, "optblock body", node->nd_head, 1 /* pop */ );
- ADD_LABEL(ret, next_label);
- ADD_INSN(ret, 0, opt_checkenv);
- break;
- }
- case NODE_PRELUDE:{
- VALUE iseqval = NEW_ISEQVAL(node->nd_head,
- rb_str_new2("BEGIN{}"),
- ISEQ_TYPE_TOP);
+ ADD_LABEL(ret, redo_label);
+ COMPILE_(ret, "optblock body", node->nd_head, 1 /* pop */ );
+ ADD_LABEL(ret, next_label);
+ ADD_INSN(ret, 0, opt_checkenv);
+ break;
+ }
+ case NODE_PRELUDE:{
+ VALUE iseqval = NEW_ISEQVAL(node->nd_head,
+ rb_str_new2("BEGIN{}"),
+ ISEQ_TYPE_TOP);
- ADD_INSN1(ret, nd_line(node), preexe, iseqval);
- ADD_INSN(ret, nd_line(node), pop);
- COMPILE_(ret, "prelude body", node->nd_body, poped);
- break;
- }
- default:
+ ADD_INSN1(ret, nd_line(node), preexe, iseqval);
+ ADD_INSN(ret, nd_line(node), pop);
+ COMPILE_(ret, "prelude body", node->nd_body, poped);
+ break;
+ }
+ default:
COMPILE_ERROR(("BUG: unknown node (default): %s", node_name(type)));
return Qnil;
}
Modified: trunk/test.rb
===================================================================
--- trunk/test.rb 2006-02-13 12:23:53 UTC (rev 393)
+++ trunk/test.rb 2006-02-13 12:24:09 UTC (rev 394)
@@ -1,8 +1,65 @@
+def m
+ proc{
+ break :ok
+ }.call
+end
+p m
__END__
+pr = eval %q{
+ proc{
+ p 1
+ break
+ }
+}
+pr.call
+p 'exit'
+__END__
+
+eval(%q{
+ proc{
+ break
+ }
+}).call
+
+__END__
+
+GC.stress = true
+eval(' proc{
+ p 1;
+ break :ok
+ }').call
+ p 'exit'
+
+__END__
+eval('redo')
+
+__END__
+
+class Hoge
+ def fuge
+ eval "EvaluatedConst = 10"
+ self
+ end
+end
+
+Hoge.new.fuge
+p Hoge::EvaluatedConst
+begin
+ p EvaluatedConst
+rescue Exception
+ p $!
+end
+p Hoge.module_eval("remove_const :EvaluatedConst")
+
+
+
+__END__
+
+
module M
class C
def m
--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml