diff --git a/ChangeLog b/ChangeLog index 4303ca4c20..9a83ad0e1e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,29 @@ +Tue Sep 23 16:41:31 2008 Koichi Sasada + + * include/ruby/node.h, vm_core.h: move definition of + RUBY_VM_METHOD_NODE to node.h. + + * class.c, common.mk: remove useless inclusion. + + * compile.h, iseq.h, vm_core.h: rename compile.h to iseq.h. + move some definitions from vm_core.h to iseq.h. + + * compile.c, iseq.c, vm.c: ditto. + + * eval.c, compile.c: move some functions for parser + from eval.c to compile.c. + + * eval_intern.h, vm_core.h: move va_init_list() macro to + vm_core.h. + + * iseq.c (rb_iseq_new_top, rb_iseq_first_lineno): added. + + * load.c, ruby.c: use rb_iseq_new_top() instead of + rb_iseq_new() with ISEQ_TYPE_TOP constant directly. + + * proc.c: use rb_iseq_first_lineno() instead of accessing + iseq structure. + Tue Sep 23 16:17:54 2008 Yukihiro Matsumoto * ext/ripper/eventids2.c (token_to_eventid): supper __ENCODING__ diff --git a/class.c b/class.c index 0c41e2c638..792c8d32ad 100644 --- a/class.c +++ b/class.c @@ -12,7 +12,6 @@ #include "ruby/ruby.h" #include "ruby/node.h" #include "ruby/st.h" -#include "vm_core.h" #include extern st_table *rb_class_tbl; diff --git a/common.mk b/common.mk index f3e51101f4..1c250962a3 100644 --- a/common.mk +++ b/common.mk @@ -445,7 +445,7 @@ VM_CORE_H_INCLUDES = {$(VPATH)}vm_core.h {$(VPATH)}vm_opts.h \ array.$(OBJEXT): {$(VPATH)}array.c $(RUBY_H_INCLUDES) {$(VPATH)}util.h bignum.$(OBJEXT): {$(VPATH)}bignum.c $(RUBY_H_INCLUDES) -class.$(OBJEXT): {$(VPATH)}class.c $(RUBY_H_INCLUDES) $(VM_CORE_H_INCLUDES) +class.$(OBJEXT): {$(VPATH)}class.c $(RUBY_H_INCLUDES) {$(VPATH)}node.h compar.$(OBJEXT): {$(VPATH)}compar.c $(RUBY_H_INCLUDES) complex.$(OBJEXT): {$(VPATH)}complex.c $(RUBY_H_INCLUDES) dir.$(OBJEXT): {$(VPATH)}dir.c $(RUBY_H_INCLUDES) {$(VPATH)}util.h \ @@ -537,14 +537,14 @@ variable.$(OBJEXT): {$(VPATH)}variable.c $(RUBY_H_INCLUDES) \ version.$(OBJEXT): {$(VPATH)}version.c $(RUBY_H_INCLUDES) \ {$(VPATH)}version.h $(srcdir)/revision.h -compile.$(OBJEXT): {$(VPATH)}compile.c {$(VPATH)}compile.h \ +compile.$(OBJEXT): {$(VPATH)}compile.c {$(VPATH)}iseq.h \ $(RUBY_H_INCLUDES) $(VM_CORE_H_INCLUDES) \ {$(VPATH)}insns.inc {$(VPATH)}insns_info.inc {$(VPATH)}optinsn.inc -iseq.$(OBJEXT): {$(VPATH)}iseq.c {$(VPATH)}gc.h \ +iseq.$(OBJEXT): {$(VPATH)}iseq.c {$(VPATH)}gc.h {$(VPATH)}iseq.h \ $(RUBY_H_INCLUDES) $(VM_CORE_H_INCLUDES) \ {$(VPATH)}insns.inc {$(VPATH)}insns_info.inc {$(VPATH)}node_name.inc -vm.$(OBJEXT): {$(VPATH)}vm.c $(RUBY_H_INCLUDES) $(ENCODING_H_INCLUDES) \ - {$(VPATH)}gc.h {$(VPATH)}eval_intern.h $(VM_CORE_H_INCLUDES) \ +vm.$(OBJEXT): {$(VPATH)}vm.c {$(VPATH)}gc.h {$(VPATH)}iseq.h {$(VPATH)}eval_intern.h \ + $(RUBY_H_INCLUDES) $(ENCODING_H_INCLUDES) $(VM_CORE_H_INCLUDES) \ {$(VPATH)}vm_method.c {$(VPATH)}vm_eval.c \ {$(VPATH)}vm_insnhelper.c {$(VPATH)}vm_insnhelper.h \ {$(VPATH)}vm_exec.c {$(VPATH)}vm_exec.h \ diff --git a/compile.c b/compile.c index 41d1a9247f..8e8decbe96 100644 --- a/compile.c +++ b/compile.c @@ -14,21 +14,10 @@ #define USE_INSN_STACK_INCREASE 1 #include "vm_core.h" -#include "compile.h" +#include "iseq.h" #include "insns.inc" #include "insns_info.inc" -#ifdef HAVE_STDARG_PROTOTYPES -#include -#define va_init_list(a,b) va_start(a,b) -#else -#include -#define va_init_list(a,b) va_start(a) -#endif - -VALUE iseq_load(VALUE self, VALUE data, VALUE parent, VALUE opt); - -/* types */ typedef struct iseq_link_element { enum { @@ -82,6 +71,232 @@ struct iseq_compile_data_ensure_node_stack { struct ensure_range *erange; }; +/** + * debug function(macro) interface depend on CPDEBUG + * if it is less than 0, runtime option is in effect. + * + * debug level: + * 0: no debug output + * 1: show node type + * 2: show node important parameters + * ... + * 5: show other parameters + * 10: show every AST array + */ + +#ifndef CPDEBUG +#define CPDEBUG 0 +#endif + +#if CPDEBUG >= 0 +#define compile_debug CPDEBUG +#else +#define compile_debug iseq->compile_data->option->debug_level +#endif + +NORETURN(PRINTF_ARGS(void rb_compile_bug(const char*, int, const char*, ...), 3, 4)); + +#if CPDEBUG + +#define compile_debug_print_indent(level) \ + ruby_debug_print_indent(level, compile_debug, gl_node_level * 2) + +#define debugp(header, value) (void) \ + (compile_debug_print_indent(1) && \ + ruby_debug_print_value(1, compile_debug, header, value)) + +#define debugi(header, id) (void) \ + (compile_debug_print_indent(1) && \ + ruby_debug_print_id(1, compile_debug, header, id)) + +#define debugp_param(header, value) (void) \ + (compile_debug_print_indent(1) && \ + ruby_debug_print_value(1, compile_debug, header, value)) + +#define debugp_verbose(header, value) (void) \ + (compile_debug_print_indent(2) && \ + ruby_debug_print_value(2, compile_debug, header, value)) + +#define debugp_verbose_node(header, value) (void) \ + (compile_debug_print_indent(10) && \ + ruby_debug_print_value(10, compile_debug, header, value)) + +#define debug_node_start(node) ((void) \ + (compile_debug_print_indent(1) && \ + (ruby_debug_print_node(1, CPDEBUG, "", (NODE *)node), gl_node_level)), \ + gl_node_level++) + +#define debug_node_end() gl_node_level --; + +#else + +static inline ID +r_id(ID id) +{ + return id; +} + +static inline VALUE +r_value(VALUE value) +{ + return value; +} + +#define debugi(header, id) r_id(id) +#define debugp(header, value) r_value(value) +#define debugp_verbose(header, value) r_value(value) +#define debugp_verbose_node(header, value) r_value(value) +#define debugp_param(header, value) r_value(value) +#define debug_node_start(node) ((void)0) +#define debug_node_end() ((void)0) +#endif + +#if CPDEBUG > 1 || CPDEBUG < 0 +PRINTF_ARGS(void ruby_debug_printf(const char*, ...), 1, 2); +#define debugs if (compile_debug_print_indent(1)) ruby_debug_printf +#define debug_compile(msg, v) ((void)(compile_debug_print_indent(1) && fputs(msg, stderr)), (v)) +#else +#define debugs if(0)printf +#define debug_compile(msg, v) (v) +#endif + + +/* create new label */ +#define NEW_LABEL(l) new_label_body(iseq, l) + +#define iseq_filename(iseq) \ + (((rb_iseq_t*)DATA_PTR(iseq))->filename) + +#define NEW_ISEQVAL(node, name, type) \ + new_child_iseq(iseq, node, name, 0, type) + +#define NEW_CHILD_ISEQVAL(node, name, type) \ + new_child_iseq(iseq, node, name, iseq->self, type) + +#define NEW_SPECIAQL_BLOCK_ISEQVAL(iseq, sym) \ + new_child_iseq(iseq, iseq->node, iseq->name, iseq->parent_iseq, iseq->type, sym) + +/* add instructions */ +#define ADD_SEQ(seq1, seq2) \ + APPEND_LIST(seq1, seq2) + +/* add an instruction */ +#define ADD_INSN(seq, line, insn) \ + ADD_ELEM(seq, (LINK_ELEMENT *) new_insn_body(iseq, line, BIN(insn), 0)) + +/* add an instruction with label operand */ +#define ADD_INSNL(seq, line, insn, label) \ + ADD_ELEM(seq, (LINK_ELEMENT *) \ + new_insn_body(iseq, line, BIN(insn), 1, (VALUE)label)) + +/* add an instruction with some operands (1, 2, 3, 5) */ +#define ADD_INSN1(seq, line, insn, op1) \ + ADD_ELEM(seq, (LINK_ELEMENT *) \ + new_insn_body(iseq, line, BIN(insn), 1, (VALUE)op1)) + +#define ADD_INSN2(seq, line, insn, op1, op2) \ + ADD_ELEM(seq, (LINK_ELEMENT *) \ + new_insn_body(iseq, line, BIN(insn), 2, (VALUE)op1, (VALUE)op2)) + +#define ADD_INSN3(seq, line, insn, op1, op2, op3) \ + ADD_ELEM(seq, (LINK_ELEMENT *) \ + new_insn_body(iseq, line, BIN(insn), 3, (VALUE)op1, (VALUE)op2, (VALUE)op3)) + +/* Specific Insn factory */ +#define ADD_SEND(seq, line, id, argc) \ + ADD_SEND_R(seq, line, id, argc, (VALUE)Qfalse, (VALUE)INT2FIX(0)) + +#define ADD_CALL_RECEIVER(seq, line) \ + ADD_INSN(seq, line, putnil) + +#define ADD_CALL(seq, line, id, argc) \ + ADD_SEND_R(seq, line, id, argc, (VALUE)Qfalse, (VALUE)INT2FIX(VM_CALL_FCALL_BIT)) + +#define ADD_CALL_WITH_BLOCK(seq, line, id, argc, block) \ + ADD_SEND_R(seq, line, id, argc, block, (VALUE)INT2FIX(VM_CALL_FCALL_BIT)) + +#define ADD_SEND_R(seq, line, id, argc, block, flag) \ + ADD_ELEM(seq, (LINK_ELEMENT *) \ + new_insn_send(iseq, line, \ + (VALUE)id, (VALUE)argc, (VALUE)block, (VALUE)flag)) + +#define ADD_TRACE(seq, line, event) \ + do { \ + if ((event) == RUBY_EVENT_LINE && iseq->coverage && \ + RARRAY_PTR(iseq->coverage)[(line) - 1] == Qnil) { \ + RARRAY_PTR(iseq->coverage)[(line) - 1] = INT2FIX(0); \ + ADD_INSN1(seq, line, trace, INT2FIX(RUBY_EVENT_COVERAGE)); \ + } \ + if (iseq->compile_data->option->trace_instruction) { \ + ADD_INSN1(seq, line, trace, INT2FIX(event)); \ + } \ + }while(0); + +/* add label */ +#define ADD_LABEL(seq, label) \ + ADD_ELEM(seq, (LINK_ELEMENT *) label) + +#define ADD_ADJUST(seq, line, label) \ + ADD_ELEM(seq, (LINK_ELEMENT *) new_adjust_body(iseq, label, line)) + +#define ADD_ADJUST_RESTORE(seq, label) \ + ADD_ELEM(seq, (LINK_ELEMENT *) new_adjust_body(iseq, label, -1)) + +#define ADD_CATCH_ENTRY(type, ls, le, iseqv, lc) \ + (rb_ary_push(iseq->compile_data->catch_table_ary, \ + rb_ary_new3(5, type, \ + (VALUE)(ls) | 1, (VALUE)(le) | 1, \ + iseqv, (VALUE)(lc) | 1))) + +/* compile node */ +#define COMPILE(anchor, desc, node) \ + (debug_compile("== " desc "\n", \ + iseq_compile_each(iseq, anchor, node, 0))) + +/* compile node, this node's value will be poped */ +#define COMPILE_POPED(anchor, desc, node) \ + (debug_compile("== " desc "\n", \ + iseq_compile_each(iseq, anchor, node, 1))) + +/* compile node, which is poped when 'poped' is true */ +#define COMPILE_(anchor, desc, node, poped) \ + (debug_compile("== " desc "\n", \ + iseq_compile_each(iseq, anchor, node, poped))) + +#define OPERAND_AT(insn, idx) \ + (((INSN*)(insn))->operands[idx]) + +#define INSN_OF(insn) \ + (((INSN*)(insn))->insn_id) + +/* error */ +#define COMPILE_ERROR(strs) \ +{ \ + VALUE tmp = GET_THREAD()->errinfo; \ + if (compile_debug) rb_compile_bug strs; \ + GET_THREAD()->errinfo = iseq->compile_data->err_info; \ + rb_compile_error strs; \ + iseq->compile_data->err_info = GET_THREAD()->errinfo; \ + GET_THREAD()->errinfo = tmp; \ + ret = 0; \ + break; \ +} + +#define ERROR_ARGS ruby_sourcefile, nd_line(node), + + +#define COMPILE_OK 1 +#define COMPILE_NG 0 + + +/* leave name uninitialized so that compiler warn if INIT_ANCHOR is + * missing */ +#define DECL_ANCHOR(name) \ + LINK_ANCHOR *name, name##_body__ = {{0,},} +#define INIT_ANCHOR(name) \ + (name##_body__.last = &name##_body__.anchor, name = &name##_body__) + + #include "optinsn.inc" #if OPT_INSTRUCTIONS_UNIFICATION #include "optunifs.inc" @@ -5051,3 +5266,55 @@ iseq_build_from_ary(rb_iseq_t *iseq, VALUE locals, VALUE args, iseq_build_body(iseq, anchor, body, labels_table); return iseq->self; } + +/* for parser */ + +int +rb_dvar_defined(ID id) +{ + rb_thread_t *th = GET_THREAD(); + rb_iseq_t *iseq; + if (th->base_block && (iseq = th->base_block->iseq)) { + while (iseq->type == ISEQ_TYPE_BLOCK || + iseq->type == ISEQ_TYPE_RESCUE || + iseq->type == ISEQ_TYPE_ENSURE || + iseq->type == ISEQ_TYPE_EVAL) { + int i; + + for (i = 0; i < iseq->local_table_size; i++) { + if (iseq->local_table[i] == id) { + return 1; + } + } + iseq = iseq->parent_iseq; + } + } + return 0; +} + +int +rb_local_defined(ID id) +{ + rb_thread_t *th = GET_THREAD(); + rb_iseq_t *iseq; + + if (th->base_block && th->base_block->iseq) { + int i; + iseq = th->base_block->iseq->local_iseq; + + for (i=0; ilocal_table_size; i++) { + if (iseq->local_table[i] == id) { + return 1; + } + } + } + return 0; +} + +int +rb_parse_in_eval(void) +{ + return GET_THREAD()->parse_in_eval != 0; +} + + diff --git a/compile.h b/compile.h deleted file mode 100644 index 4bd4e99e2c..0000000000 --- a/compile.h +++ /dev/null @@ -1,241 +0,0 @@ -/********************************************************************** - - compile.h - - - $Author$ - created at: 04/01/01 23:36:57 JST - - Copyright (C) 2004-2007 Koichi Sasada - -**********************************************************************/ - -#ifndef RUBY_COMPILE_H -#define RUBY_COMPILE_H - -/* */ -/** - * debug function(macro) interface depend on CPDEBUG - * if it is less than 0, runtime option is in effect. - * - * debug level: - * 0: no debug output - * 1: show node type - * 2: show node important parameters - * ... - * 5: show other parameters - * 10: show every AST array - */ - -#ifndef CPDEBUG -#define CPDEBUG 0 -#endif - -#if CPDEBUG >= 0 -#define compile_debug CPDEBUG -#else -#define compile_debug iseq->compile_data->option->debug_level -#endif - -NORETURN(PRINTF_ARGS(void rb_compile_bug(const char*, int, const char*, ...), 3, 4)); - -#if CPDEBUG - -#define compile_debug_print_indent(level) \ - ruby_debug_print_indent(level, compile_debug, gl_node_level * 2) - -#define debugp(header, value) (void) \ - (compile_debug_print_indent(1) && \ - ruby_debug_print_value(1, compile_debug, header, value)) - -#define debugi(header, id) (void) \ - (compile_debug_print_indent(1) && \ - ruby_debug_print_id(1, compile_debug, header, id)) - -#define debugp_param(header, value) (void) \ - (compile_debug_print_indent(1) && \ - ruby_debug_print_value(1, compile_debug, header, value)) - -#define debugp_verbose(header, value) (void) \ - (compile_debug_print_indent(2) && \ - ruby_debug_print_value(2, compile_debug, header, value)) - -#define debugp_verbose_node(header, value) (void) \ - (compile_debug_print_indent(10) && \ - ruby_debug_print_value(10, compile_debug, header, value)) - -#define debug_node_start(node) ((void) \ - (compile_debug_print_indent(1) && \ - (ruby_debug_print_node(1, CPDEBUG, "", (NODE *)node), gl_node_level)), \ - gl_node_level++) - -#define debug_node_end() gl_node_level --; - -#else - -static inline ID -r_id(ID id) -{ - return id; -} - -static inline VALUE -r_value(VALUE value) -{ - return value; -} - -#define debugi(header, id) r_id(id) -#define debugp(header, value) r_value(value) -#define debugp_verbose(header, value) r_value(value) -#define debugp_verbose_node(header, value) r_value(value) -#define debugp_param(header, value) r_value(value) -#define debug_node_start(node) ((void)0) -#define debug_node_end() ((void)0) -#endif - -#if CPDEBUG > 1 || CPDEBUG < 0 -PRINTF_ARGS(void ruby_debug_printf(const char*, ...), 1, 2); -#define debugs if (compile_debug_print_indent(1)) ruby_debug_printf -#define debug_compile(msg, v) ((void)(compile_debug_print_indent(1) && fputs(msg, stderr)), (v)) -#else -#define debugs if(0)printf -#define debug_compile(msg, v) (v) -#endif - - -/* create new label */ -#define NEW_LABEL(l) new_label_body(iseq, l) - -#define iseq_filename(iseq) \ - (((rb_iseq_t*)DATA_PTR(iseq))->filename) - -#define NEW_ISEQVAL(node, name, type) \ - new_child_iseq(iseq, node, name, 0, type) - -#define NEW_CHILD_ISEQVAL(node, name, type) \ - new_child_iseq(iseq, node, name, iseq->self, type) - -#define NEW_SPECIAQL_BLOCK_ISEQVAL(iseq, sym) \ - new_child_iseq(iseq, iseq->node, iseq->name, iseq->parent_iseq, iseq->type, sym) - -/* add instructions */ -#define ADD_SEQ(seq1, seq2) \ - APPEND_LIST(seq1, seq2) - -/* add an instruction */ -#define ADD_INSN(seq, line, insn) \ - ADD_ELEM(seq, (LINK_ELEMENT *) new_insn_body(iseq, line, BIN(insn), 0)) - -/* add an instruction with label operand */ -#define ADD_INSNL(seq, line, insn, label) \ - ADD_ELEM(seq, (LINK_ELEMENT *) \ - new_insn_body(iseq, line, BIN(insn), 1, (VALUE)label)) - -/* add an instruction with some operands (1, 2, 3, 5) */ -#define ADD_INSN1(seq, line, insn, op1) \ - ADD_ELEM(seq, (LINK_ELEMENT *) \ - new_insn_body(iseq, line, BIN(insn), 1, (VALUE)op1)) - -#define ADD_INSN2(seq, line, insn, op1, op2) \ - ADD_ELEM(seq, (LINK_ELEMENT *) \ - new_insn_body(iseq, line, BIN(insn), 2, (VALUE)op1, (VALUE)op2)) - -#define ADD_INSN3(seq, line, insn, op1, op2, op3) \ - ADD_ELEM(seq, (LINK_ELEMENT *) \ - new_insn_body(iseq, line, BIN(insn), 3, (VALUE)op1, (VALUE)op2, (VALUE)op3)) - -/* Specific Insn factory */ -#define ADD_SEND(seq, line, id, argc) \ - ADD_SEND_R(seq, line, id, argc, (VALUE)Qfalse, (VALUE)INT2FIX(0)) - -#define ADD_CALL_RECEIVER(seq, line) \ - ADD_INSN(seq, line, putnil) - -#define ADD_CALL(seq, line, id, argc) \ - ADD_SEND_R(seq, line, id, argc, (VALUE)Qfalse, (VALUE)INT2FIX(VM_CALL_FCALL_BIT)) - -#define ADD_CALL_WITH_BLOCK(seq, line, id, argc, block) \ - ADD_SEND_R(seq, line, id, argc, block, (VALUE)INT2FIX(VM_CALL_FCALL_BIT)) - -#define ADD_SEND_R(seq, line, id, argc, block, flag) \ - ADD_ELEM(seq, (LINK_ELEMENT *) \ - new_insn_send(iseq, line, \ - (VALUE)id, (VALUE)argc, (VALUE)block, (VALUE)flag)) - -#define ADD_TRACE(seq, line, event) \ - do { \ - if ((event) == RUBY_EVENT_LINE && iseq->coverage && \ - RARRAY_PTR(iseq->coverage)[(line) - 1] == Qnil) { \ - RARRAY_PTR(iseq->coverage)[(line) - 1] = INT2FIX(0); \ - ADD_INSN1(seq, line, trace, INT2FIX(RUBY_EVENT_COVERAGE)); \ - } \ - if (iseq->compile_data->option->trace_instruction) { \ - ADD_INSN1(seq, line, trace, INT2FIX(event)); \ - } \ - }while(0); - -/* add label */ -#define ADD_LABEL(seq, label) \ - ADD_ELEM(seq, (LINK_ELEMENT *) label) - -#define ADD_ADJUST(seq, line, label) \ - ADD_ELEM(seq, (LINK_ELEMENT *) new_adjust_body(iseq, label, line)) - -#define ADD_ADJUST_RESTORE(seq, label) \ - ADD_ELEM(seq, (LINK_ELEMENT *) new_adjust_body(iseq, label, -1)) - -#define ADD_CATCH_ENTRY(type, ls, le, iseqv, lc) \ - (rb_ary_push(iseq->compile_data->catch_table_ary, \ - rb_ary_new3(5, type, \ - (VALUE)(ls) | 1, (VALUE)(le) | 1, \ - iseqv, (VALUE)(lc) | 1))) - -/* compile node */ -#define COMPILE(anchor, desc, node) \ - (debug_compile("== " desc "\n", \ - iseq_compile_each(iseq, anchor, node, 0))) - -/* compile node, this node's value will be poped */ -#define COMPILE_POPED(anchor, desc, node) \ - (debug_compile("== " desc "\n", \ - iseq_compile_each(iseq, anchor, node, 1))) - -/* compile node, which is poped when 'poped' is true */ -#define COMPILE_(anchor, desc, node, poped) \ - (debug_compile("== " desc "\n", \ - iseq_compile_each(iseq, anchor, node, poped))) - -#define OPERAND_AT(insn, idx) \ - (((INSN*)(insn))->operands[idx]) - -#define INSN_OF(insn) \ - (((INSN*)(insn))->insn_id) - -/* error */ -#define COMPILE_ERROR(strs) \ -{ \ - VALUE tmp = GET_THREAD()->errinfo; \ - if (compile_debug) rb_compile_bug strs; \ - GET_THREAD()->errinfo = iseq->compile_data->err_info; \ - rb_compile_error strs; \ - iseq->compile_data->err_info = GET_THREAD()->errinfo; \ - GET_THREAD()->errinfo = tmp; \ - ret = 0; \ - break; \ -} - -#define ERROR_ARGS ruby_sourcefile, nd_line(node), - - -#define COMPILE_OK 1 -#define COMPILE_NG 0 - - -/* leave name uninitialized so that compiler warn if INIT_ANCHOR is - * missing */ -#define DECL_ANCHOR(name) \ - LINK_ANCHOR *name, name##_body__ = {{0,},} -#define INIT_ANCHOR(name) \ - (name##_body__.last = &name##_body__.anchor, name = &name##_body__) - -#endif /* RUBY_COMPILE_H */ diff --git a/eval.c b/eval.c index e2d7cfcfd9..ca01e02e81 100644 --- a/eval.c +++ b/eval.c @@ -12,6 +12,7 @@ **********************************************************************/ #include "eval_intern.h" +#include "iseq.h" VALUE proc_invoke(VALUE, VALUE, VALUE, VALUE); VALUE rb_binding_new(void); @@ -1175,56 +1176,3 @@ Init_eval(void) OBJ_TAINT(exception_error); OBJ_FREEZE(exception_error); } - - -/* for parser */ - -int -rb_dvar_defined(ID id) -{ - rb_thread_t *th = GET_THREAD(); - rb_iseq_t *iseq; - if (th->base_block && (iseq = th->base_block->iseq)) { - while (iseq->type == ISEQ_TYPE_BLOCK || - iseq->type == ISEQ_TYPE_RESCUE || - iseq->type == ISEQ_TYPE_ENSURE || - iseq->type == ISEQ_TYPE_EVAL) { - int i; - - for (i = 0; i < iseq->local_table_size; i++) { - if (iseq->local_table[i] == id) { - return 1; - } - } - iseq = iseq->parent_iseq; - } - } - return 0; -} - -int -rb_local_defined(ID id) -{ - rb_thread_t *th = GET_THREAD(); - rb_iseq_t *iseq; - - if (th->base_block && th->base_block->iseq) { - int i; - iseq = th->base_block->iseq->local_iseq; - - for (i=0; ilocal_table_size; i++) { - if (iseq->local_table[i] == id) { - return 1; - } - } - } - return 0; -} - -int -rb_parse_in_eval(void) -{ - return GET_THREAD()->parse_in_eval != 0; -} - - diff --git a/eval_intern.h b/eval_intern.h index dbfcb66300..9444e0798b 100644 --- a/eval_intern.h +++ b/eval_intern.h @@ -52,14 +52,6 @@ void *alloca(); # endif /* HAVE_ALLOCA_H */ #endif /* __GNUC__ */ -#ifdef HAVE_STDARG_PROTOTYPES -#include -#define va_init_list(a,b) va_start(a,b) -#else -#include -#define va_init_list(a,b) va_start(a) -#endif - #ifndef HAVE_STRING_H char *strrchr(const char *, const char); #endif diff --git a/include/ruby/node.h b/include/ruby/node.h index d83f55098c..5ae28382bd 100644 --- a/include/ruby/node.h +++ b/include/ruby/node.h @@ -481,6 +481,8 @@ typedef struct RNode { #define CALL_VCALL 2 #define CALL_SUPER 3 +#define RUBY_VM_METHOD_NODE NODE_METHOD + VALUE rb_parser_new(void); VALUE rb_parser_end_seen_p(VALUE); VALUE rb_parser_encoding(VALUE); diff --git a/iseq.c b/iseq.c index 057516deed..de8664d5e4 100644 --- a/iseq.c +++ b/iseq.c @@ -15,6 +15,7 @@ /* #define MARK_FREE_DEBUG 1 */ #include "gc.h" #include "vm_core.h" +#include "iseq.h" #include "insns.inc" #include "insns_info.inc" @@ -307,6 +308,13 @@ rb_iseq_new(NODE *node, VALUE name, VALUE filename, &COMPILE_OPTION_DEFAULT); } +VALUE +rb_iseq_new_top(NODE *node, VALUE name, VALUE filename, VALUE parent) +{ + return rb_iseq_new_with_opt(node, name, filename, parent, ISEQ_TYPE_TOP, + &COMPILE_OPTION_DEFAULT); +} + static VALUE rb_iseq_new_with_bopt_and_opt(NODE *node, VALUE name, VALUE filename, VALUE parent, VALUE type, VALUE bopt, @@ -571,6 +579,12 @@ iseq_to_a(VALUE self) return iseq_data_to_ary(iseq); } +int +rb_iseq_first_lineno(rb_iseq_t *iseq) +{ + return iseq->insn_info_table[0].line_no; +} + /* TODO: search algorithm is brute force. this should be binary search or so. */ diff --git a/iseq.h b/iseq.h new file mode 100644 index 0000000000..631ef30e9d --- /dev/null +++ b/iseq.h @@ -0,0 +1,94 @@ +/********************************************************************** + + iseq.h - + + $Author$ + created at: 04/01/01 23:36:57 JST + + Copyright (C) 2004-2008 Koichi Sasada + +**********************************************************************/ + +#ifndef RUBY_COMPILE_H +#define RUBY_COMPILE_H + +VALUE iseq_load(VALUE self, VALUE data, VALUE parent, VALUE opt); + +#define ISEQ_TYPE_TOP INT2FIX(1) +#define ISEQ_TYPE_METHOD INT2FIX(2) +#define ISEQ_TYPE_BLOCK INT2FIX(3) +#define ISEQ_TYPE_CLASS INT2FIX(4) +#define ISEQ_TYPE_RESCUE INT2FIX(5) +#define ISEQ_TYPE_ENSURE INT2FIX(6) +#define ISEQ_TYPE_EVAL INT2FIX(7) +#define ISEQ_TYPE_DEFINED_GUARD INT2FIX(8) + +#define CATCH_TYPE_RESCUE INT2FIX(1) +#define CATCH_TYPE_ENSURE INT2FIX(2) +#define CATCH_TYPE_RETRY INT2FIX(3) +#define CATCH_TYPE_BREAK INT2FIX(4) +#define CATCH_TYPE_REDO INT2FIX(5) +#define CATCH_TYPE_NEXT INT2FIX(6) + +struct iseq_insn_info_entry { + unsigned short position; + unsigned short line_no; + unsigned short sp; +}; + +struct iseq_catch_table_entry { + VALUE type; + VALUE iseq; + unsigned long start; + unsigned long end; + unsigned long cont; + unsigned long sp; +}; + +#define INITIAL_ISEQ_COMPILE_DATA_STORAGE_BUFF_SIZE (512) + +struct iseq_compile_data_storage { + struct iseq_compile_data_storage *next; + unsigned long pos; + unsigned long size; + char *buff; +}; + +struct iseq_compile_data { + /* GC is needed */ + VALUE err_info; + VALUE mark_ary; + VALUE catch_table_ary; /* Array */ + + /* GC is not needed */ + struct iseq_label_data *start_label; + struct iseq_label_data *end_label; + struct iseq_label_data *redo_label; + VALUE current_block; + VALUE loopval_popped; /* used by NODE_BREAK */ + VALUE ensure_node; + VALUE for_iseq; + struct iseq_compile_data_ensure_node_stack *ensure_node_stack; + int cached_const; + struct iseq_compile_data_storage *storage_head; + struct iseq_compile_data_storage *storage_current; + int last_line; + int flip_cnt; + int label_no; + int node_level; + const rb_compile_option_t *option; +}; + +/* defined? */ +#define DEFINED_IVAR INT2FIX(1) +#define DEFINED_IVAR2 INT2FIX(2) +#define DEFINED_GVAR INT2FIX(3) +#define DEFINED_CVAR INT2FIX(4) +#define DEFINED_CONST INT2FIX(5) +#define DEFINED_METHOD INT2FIX(6) +#define DEFINED_YIELD INT2FIX(7) +#define DEFINED_REF INT2FIX(8) +#define DEFINED_ZSUPER INT2FIX(9) +#define DEFINED_FUNC INT2FIX(10) + +#endif /* RUBY_COMPILE_H */ diff --git a/load.c b/load.c index 94837f3c6f..d550f2c2c4 100644 --- a/load.c +++ b/load.c @@ -280,8 +280,7 @@ rb_load(VALUE fname, int wrap) th->mild_compile_error++; node = (NODE *)rb_load_file(RSTRING_PTR(fname)); loaded = Qtrue; - iseq = rb_iseq_new(node, rb_str_new2(""), - fname, Qfalse, ISEQ_TYPE_TOP); + iseq = rb_iseq_new_top(node, rb_str_new2(""), fname, Qfalse); th->mild_compile_error--; rb_iseq_eval(iseq); } diff --git a/proc.c b/proc.c index 56c51ccabb..99e1e99d72 100644 --- a/proc.c +++ b/proc.c @@ -629,7 +629,7 @@ rb_proc_location(VALUE self) if (!iseq) return Qnil; loc[0] = iseq->filename; if (iseq->insn_info_table) { - loc[1] = INT2FIX(iseq->insn_info_table[0].line_no); + loc[1] = INT2FIX(rb_iseq_first_lineno(iseq)); } else { loc[1] = Qnil; @@ -710,7 +710,7 @@ proc_to_s(VALUE self) int line_no = 0; if (iseq->insn_info_table) { - line_no = iseq->insn_info_table[0].line_no; + line_no = rb_iseq_first_lineno(iseq); } str = rb_sprintf("#<%s:%p@%s:%d%s>", cname, (void *)self, RSTRING_PTR(iseq->filename), diff --git a/ruby.c b/ruby.c index c773fafc15..8db5ff5db2 100644 --- a/ruby.c +++ b/ruby.c @@ -1142,8 +1142,8 @@ process_options(VALUE arg) tree = rb_parser_while_loop(parser, tree, opt->do_line, opt->do_split); } - iseq = rb_iseq_new(tree, rb_str_new2("
"), - opt->script_name, Qfalse, ISEQ_TYPE_TOP); + iseq = rb_iseq_new_top(tree, rb_str_new2("
"), + opt->script_name, Qfalse); if (opt->dump & DUMP_BIT(insns)) { rb_io_write(rb_stdout, ruby_iseq_disasm(iseq)); diff --git a/vm.c b/vm.c index 634924779d..b3087c370f 100644 --- a/vm.c +++ b/vm.c @@ -15,6 +15,7 @@ #include "gc.h" #include "vm_core.h" +#include "iseq.h" #include "eval_intern.h" #include "vm_insnhelper.h" diff --git a/vm_core.h b/vm_core.h index 9476284081..87d1e4014f 100644 --- a/vm_core.h +++ b/vm_core.h @@ -47,6 +47,14 @@ #define RUBY_NSIG NSIG +#ifdef HAVE_STDARG_PROTOTYPES +#include +#define va_init_list(a,b) va_start(a,b) +#else +#include +#define va_init_list(a,b) va_start(a) +#endif + /*****************/ /* configuration */ /*****************/ @@ -92,46 +100,6 @@ typedef unsigned long rb_num_t; -#define ISEQ_TYPE_TOP INT2FIX(1) -#define ISEQ_TYPE_METHOD INT2FIX(2) -#define ISEQ_TYPE_BLOCK INT2FIX(3) -#define ISEQ_TYPE_CLASS INT2FIX(4) -#define ISEQ_TYPE_RESCUE INT2FIX(5) -#define ISEQ_TYPE_ENSURE INT2FIX(6) -#define ISEQ_TYPE_EVAL INT2FIX(7) -#define ISEQ_TYPE_DEFINED_GUARD INT2FIX(8) - -#define CATCH_TYPE_RESCUE INT2FIX(1) -#define CATCH_TYPE_ENSURE INT2FIX(2) -#define CATCH_TYPE_RETRY INT2FIX(3) -#define CATCH_TYPE_BREAK INT2FIX(4) -#define CATCH_TYPE_REDO INT2FIX(5) -#define CATCH_TYPE_NEXT INT2FIX(6) - -struct iseq_insn_info_entry { - unsigned short position; - unsigned short line_no; - unsigned short sp; -}; - -struct iseq_catch_table_entry { - VALUE type; - VALUE iseq; - unsigned long start; - unsigned long end; - unsigned long cont; - unsigned long sp; -}; - -#define INITIAL_ISEQ_COMPILE_DATA_STORAGE_BUFF_SIZE (512) - -struct iseq_compile_data_storage { - struct iseq_compile_data_storage *next; - unsigned long pos; - unsigned long size; - char *buff; -}; - struct iseq_compile_data_ensure_node_stack; typedef struct rb_compile_option_struct { @@ -146,31 +114,6 @@ typedef struct rb_compile_option_struct { int debug_level; } rb_compile_option_t; -struct iseq_compile_data { - /* GC is needed */ - VALUE err_info; - VALUE mark_ary; - VALUE catch_table_ary; /* Array */ - - /* GC is not needed */ - struct iseq_label_data *start_label; - struct iseq_label_data *end_label; - struct iseq_label_data *redo_label; - VALUE current_block; - VALUE loopval_popped; /* used by NODE_BREAK */ - VALUE ensure_node; - VALUE for_iseq; - struct iseq_compile_data_ensure_node_stack *ensure_node_stack; - int cached_const; - struct iseq_compile_data_storage *storage_head; - struct iseq_compile_data_storage *storage_current; - int last_line; - int flip_cnt; - int label_no; - int node_level; - const rb_compile_option_t *option; -}; - #if 1 #define GetCoreDataFromValue(obj, type, ptr) do { \ ptr = (type*)DATA_PTR(obj); \ @@ -505,6 +448,7 @@ typedef struct rb_thread_struct /* iseq.c */ VALUE rb_iseq_new(NODE*, VALUE, VALUE, VALUE, VALUE); +VALUE rb_iseq_new_top(NODE *node, VALUE name, VALUE filename, VALUE parent); VALUE rb_iseq_new_with_bopt(NODE*, VALUE, VALUE, VALUE, VALUE, VALUE); VALUE rb_iseq_new_with_opt(NODE*, VALUE, VALUE, VALUE, VALUE, const rb_compile_option_t*); VALUE rb_iseq_compile(VALUE src, VALUE file, VALUE line); @@ -512,6 +456,7 @@ VALUE ruby_iseq_disasm(VALUE self); VALUE ruby_iseq_disasm_insn(VALUE str, VALUE *iseqval, int pos, rb_iseq_t *iseq, VALUE child); const char *ruby_node_name(int node); VALUE rb_iseq_clone(VALUE iseqval, VALUE newcbase); +int rb_iseq_first_lineno(rb_iseq_t *iseq); RUBY_EXTERN VALUE rb_cISeq; RUBY_EXTERN VALUE rb_cRubyVM; @@ -617,8 +562,6 @@ typedef rb_control_frame_t * #define GC_GUARDED_PTR_REF(p) ((void *)(((VALUE)p) & ~0x03)) #define GC_GUARDED_PTR_P(p) (((VALUE)p) & 0x01) -#define RUBY_VM_METHOD_NODE NODE_METHOD - #define RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp) (cfp+1) #define RUBY_VM_NEXT_CONTROL_FRAME(cfp) (cfp-1) #define RUBY_VM_END_CONTROL_FRAME(th) \ @@ -638,18 +581,6 @@ typedef rb_control_frame_t * #define RUBY_VM_GET_CFP_FROM_BLOCK_PTR(b) \ ((rb_control_frame_t *)((VALUE *)(b) - 5)) -/* defined? */ -#define DEFINED_IVAR INT2FIX(1) -#define DEFINED_IVAR2 INT2FIX(2) -#define DEFINED_GVAR INT2FIX(3) -#define DEFINED_CVAR INT2FIX(4) -#define DEFINED_CONST INT2FIX(5) -#define DEFINED_METHOD INT2FIX(6) -#define DEFINED_YIELD INT2FIX(7) -#define DEFINED_REF INT2FIX(8) -#define DEFINED_ZSUPER INT2FIX(9) -#define DEFINED_FUNC INT2FIX(10) - /* VM related object allocate functions */ /* TODO: should be static functions */ VALUE rb_thread_alloc(VALUE klass);