mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@19472 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
0867b94cb9
commit
7f7834abf7
15 changed files with 437 additions and 405 deletions
26
ChangeLog
26
ChangeLog
|
@ -1,3 +1,29 @@
|
||||||
|
Tue Sep 23 16:41:31 2008 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
|
* 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 <matz@ruby-lang.org>
|
Tue Sep 23 16:17:54 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
* ext/ripper/eventids2.c (token_to_eventid): supper __ENCODING__
|
* ext/ripper/eventids2.c (token_to_eventid): supper __ENCODING__
|
||||||
|
|
1
class.c
1
class.c
|
@ -12,7 +12,6 @@
|
||||||
#include "ruby/ruby.h"
|
#include "ruby/ruby.h"
|
||||||
#include "ruby/node.h"
|
#include "ruby/node.h"
|
||||||
#include "ruby/st.h"
|
#include "ruby/st.h"
|
||||||
#include "vm_core.h"
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
extern st_table *rb_class_tbl;
|
extern st_table *rb_class_tbl;
|
||||||
|
|
10
common.mk
10
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
|
array.$(OBJEXT): {$(VPATH)}array.c $(RUBY_H_INCLUDES) {$(VPATH)}util.h
|
||||||
bignum.$(OBJEXT): {$(VPATH)}bignum.c $(RUBY_H_INCLUDES)
|
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)
|
compar.$(OBJEXT): {$(VPATH)}compar.c $(RUBY_H_INCLUDES)
|
||||||
complex.$(OBJEXT): {$(VPATH)}complex.c $(RUBY_H_INCLUDES)
|
complex.$(OBJEXT): {$(VPATH)}complex.c $(RUBY_H_INCLUDES)
|
||||||
dir.$(OBJEXT): {$(VPATH)}dir.c $(RUBY_H_INCLUDES) {$(VPATH)}util.h \
|
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) \
|
version.$(OBJEXT): {$(VPATH)}version.c $(RUBY_H_INCLUDES) \
|
||||||
{$(VPATH)}version.h $(srcdir)/revision.h
|
{$(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) \
|
$(RUBY_H_INCLUDES) $(VM_CORE_H_INCLUDES) \
|
||||||
{$(VPATH)}insns.inc {$(VPATH)}insns_info.inc {$(VPATH)}optinsn.inc
|
{$(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) \
|
$(RUBY_H_INCLUDES) $(VM_CORE_H_INCLUDES) \
|
||||||
{$(VPATH)}insns.inc {$(VPATH)}insns_info.inc {$(VPATH)}node_name.inc
|
{$(VPATH)}insns.inc {$(VPATH)}insns_info.inc {$(VPATH)}node_name.inc
|
||||||
vm.$(OBJEXT): {$(VPATH)}vm.c $(RUBY_H_INCLUDES) $(ENCODING_H_INCLUDES) \
|
vm.$(OBJEXT): {$(VPATH)}vm.c {$(VPATH)}gc.h {$(VPATH)}iseq.h {$(VPATH)}eval_intern.h \
|
||||||
{$(VPATH)}gc.h {$(VPATH)}eval_intern.h $(VM_CORE_H_INCLUDES) \
|
$(RUBY_H_INCLUDES) $(ENCODING_H_INCLUDES) $(VM_CORE_H_INCLUDES) \
|
||||||
{$(VPATH)}vm_method.c {$(VPATH)}vm_eval.c \
|
{$(VPATH)}vm_method.c {$(VPATH)}vm_eval.c \
|
||||||
{$(VPATH)}vm_insnhelper.c {$(VPATH)}vm_insnhelper.h \
|
{$(VPATH)}vm_insnhelper.c {$(VPATH)}vm_insnhelper.h \
|
||||||
{$(VPATH)}vm_exec.c {$(VPATH)}vm_exec.h \
|
{$(VPATH)}vm_exec.c {$(VPATH)}vm_exec.h \
|
||||||
|
|
291
compile.c
291
compile.c
|
@ -14,21 +14,10 @@
|
||||||
|
|
||||||
#define USE_INSN_STACK_INCREASE 1
|
#define USE_INSN_STACK_INCREASE 1
|
||||||
#include "vm_core.h"
|
#include "vm_core.h"
|
||||||
#include "compile.h"
|
#include "iseq.h"
|
||||||
#include "insns.inc"
|
#include "insns.inc"
|
||||||
#include "insns_info.inc"
|
#include "insns_info.inc"
|
||||||
|
|
||||||
#ifdef HAVE_STDARG_PROTOTYPES
|
|
||||||
#include <stdarg.h>
|
|
||||||
#define va_init_list(a,b) va_start(a,b)
|
|
||||||
#else
|
|
||||||
#include <varargs.h>
|
|
||||||
#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 {
|
typedef struct iseq_link_element {
|
||||||
enum {
|
enum {
|
||||||
|
@ -82,6 +71,232 @@ struct iseq_compile_data_ensure_node_stack {
|
||||||
struct ensure_range *erange;
|
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"
|
#include "optinsn.inc"
|
||||||
#if OPT_INSTRUCTIONS_UNIFICATION
|
#if OPT_INSTRUCTIONS_UNIFICATION
|
||||||
#include "optunifs.inc"
|
#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);
|
iseq_build_body(iseq, anchor, body, labels_table);
|
||||||
return iseq->self;
|
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; i<iseq->local_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
241
compile.h
241
compile.h
|
@ -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 */
|
|
54
eval.c
54
eval.c
|
@ -12,6 +12,7 @@
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
|
||||||
#include "eval_intern.h"
|
#include "eval_intern.h"
|
||||||
|
#include "iseq.h"
|
||||||
|
|
||||||
VALUE proc_invoke(VALUE, VALUE, VALUE, VALUE);
|
VALUE proc_invoke(VALUE, VALUE, VALUE, VALUE);
|
||||||
VALUE rb_binding_new(void);
|
VALUE rb_binding_new(void);
|
||||||
|
@ -1175,56 +1176,3 @@ Init_eval(void)
|
||||||
OBJ_TAINT(exception_error);
|
OBJ_TAINT(exception_error);
|
||||||
OBJ_FREEZE(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; i<iseq->local_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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -52,14 +52,6 @@ void *alloca();
|
||||||
# endif /* HAVE_ALLOCA_H */
|
# endif /* HAVE_ALLOCA_H */
|
||||||
#endif /* __GNUC__ */
|
#endif /* __GNUC__ */
|
||||||
|
|
||||||
#ifdef HAVE_STDARG_PROTOTYPES
|
|
||||||
#include <stdarg.h>
|
|
||||||
#define va_init_list(a,b) va_start(a,b)
|
|
||||||
#else
|
|
||||||
#include <varargs.h>
|
|
||||||
#define va_init_list(a,b) va_start(a)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef HAVE_STRING_H
|
#ifndef HAVE_STRING_H
|
||||||
char *strrchr(const char *, const char);
|
char *strrchr(const char *, const char);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -481,6 +481,8 @@ typedef struct RNode {
|
||||||
#define CALL_VCALL 2
|
#define CALL_VCALL 2
|
||||||
#define CALL_SUPER 3
|
#define CALL_SUPER 3
|
||||||
|
|
||||||
|
#define RUBY_VM_METHOD_NODE NODE_METHOD
|
||||||
|
|
||||||
VALUE rb_parser_new(void);
|
VALUE rb_parser_new(void);
|
||||||
VALUE rb_parser_end_seen_p(VALUE);
|
VALUE rb_parser_end_seen_p(VALUE);
|
||||||
VALUE rb_parser_encoding(VALUE);
|
VALUE rb_parser_encoding(VALUE);
|
||||||
|
|
14
iseq.c
14
iseq.c
|
@ -15,6 +15,7 @@
|
||||||
/* #define MARK_FREE_DEBUG 1 */
|
/* #define MARK_FREE_DEBUG 1 */
|
||||||
#include "gc.h"
|
#include "gc.h"
|
||||||
#include "vm_core.h"
|
#include "vm_core.h"
|
||||||
|
#include "iseq.h"
|
||||||
|
|
||||||
#include "insns.inc"
|
#include "insns.inc"
|
||||||
#include "insns_info.inc"
|
#include "insns_info.inc"
|
||||||
|
@ -307,6 +308,13 @@ rb_iseq_new(NODE *node, VALUE name, VALUE filename,
|
||||||
&COMPILE_OPTION_DEFAULT);
|
&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
|
static VALUE
|
||||||
rb_iseq_new_with_bopt_and_opt(NODE *node, VALUE name, VALUE filename,
|
rb_iseq_new_with_bopt_and_opt(NODE *node, VALUE name, VALUE filename,
|
||||||
VALUE parent, VALUE type, VALUE bopt,
|
VALUE parent, VALUE type, VALUE bopt,
|
||||||
|
@ -571,6 +579,12 @@ iseq_to_a(VALUE self)
|
||||||
return iseq_data_to_ary(iseq);
|
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.
|
/* TODO: search algorithm is brute force.
|
||||||
this should be binary search or so. */
|
this should be binary search or so. */
|
||||||
|
|
||||||
|
|
94
iseq.h
Normal file
94
iseq.h
Normal file
|
@ -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 */
|
3
load.c
3
load.c
|
@ -280,8 +280,7 @@ rb_load(VALUE fname, int wrap)
|
||||||
th->mild_compile_error++;
|
th->mild_compile_error++;
|
||||||
node = (NODE *)rb_load_file(RSTRING_PTR(fname));
|
node = (NODE *)rb_load_file(RSTRING_PTR(fname));
|
||||||
loaded = Qtrue;
|
loaded = Qtrue;
|
||||||
iseq = rb_iseq_new(node, rb_str_new2("<top (required)>"),
|
iseq = rb_iseq_new_top(node, rb_str_new2("<top (required)>"), fname, Qfalse);
|
||||||
fname, Qfalse, ISEQ_TYPE_TOP);
|
|
||||||
th->mild_compile_error--;
|
th->mild_compile_error--;
|
||||||
rb_iseq_eval(iseq);
|
rb_iseq_eval(iseq);
|
||||||
}
|
}
|
||||||
|
|
4
proc.c
4
proc.c
|
@ -629,7 +629,7 @@ rb_proc_location(VALUE self)
|
||||||
if (!iseq) return Qnil;
|
if (!iseq) return Qnil;
|
||||||
loc[0] = iseq->filename;
|
loc[0] = iseq->filename;
|
||||||
if (iseq->insn_info_table) {
|
if (iseq->insn_info_table) {
|
||||||
loc[1] = INT2FIX(iseq->insn_info_table[0].line_no);
|
loc[1] = INT2FIX(rb_iseq_first_lineno(iseq));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
loc[1] = Qnil;
|
loc[1] = Qnil;
|
||||||
|
@ -710,7 +710,7 @@ proc_to_s(VALUE self)
|
||||||
int line_no = 0;
|
int line_no = 0;
|
||||||
|
|
||||||
if (iseq->insn_info_table) {
|
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,
|
str = rb_sprintf("#<%s:%p@%s:%d%s>", cname, (void *)self,
|
||||||
RSTRING_PTR(iseq->filename),
|
RSTRING_PTR(iseq->filename),
|
||||||
|
|
4
ruby.c
4
ruby.c
|
@ -1142,8 +1142,8 @@ process_options(VALUE arg)
|
||||||
tree = rb_parser_while_loop(parser, tree, opt->do_line, opt->do_split);
|
tree = rb_parser_while_loop(parser, tree, opt->do_line, opt->do_split);
|
||||||
}
|
}
|
||||||
|
|
||||||
iseq = rb_iseq_new(tree, rb_str_new2("<main>"),
|
iseq = rb_iseq_new_top(tree, rb_str_new2("<main>"),
|
||||||
opt->script_name, Qfalse, ISEQ_TYPE_TOP);
|
opt->script_name, Qfalse);
|
||||||
|
|
||||||
if (opt->dump & DUMP_BIT(insns)) {
|
if (opt->dump & DUMP_BIT(insns)) {
|
||||||
rb_io_write(rb_stdout, ruby_iseq_disasm(iseq));
|
rb_io_write(rb_stdout, ruby_iseq_disasm(iseq));
|
||||||
|
|
1
vm.c
1
vm.c
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
#include "gc.h"
|
#include "gc.h"
|
||||||
#include "vm_core.h"
|
#include "vm_core.h"
|
||||||
|
#include "iseq.h"
|
||||||
#include "eval_intern.h"
|
#include "eval_intern.h"
|
||||||
|
|
||||||
#include "vm_insnhelper.h"
|
#include "vm_insnhelper.h"
|
||||||
|
|
89
vm_core.h
89
vm_core.h
|
@ -47,6 +47,14 @@
|
||||||
|
|
||||||
#define RUBY_NSIG NSIG
|
#define RUBY_NSIG NSIG
|
||||||
|
|
||||||
|
#ifdef HAVE_STDARG_PROTOTYPES
|
||||||
|
#include <stdarg.h>
|
||||||
|
#define va_init_list(a,b) va_start(a,b)
|
||||||
|
#else
|
||||||
|
#include <varargs.h>
|
||||||
|
#define va_init_list(a,b) va_start(a)
|
||||||
|
#endif
|
||||||
|
|
||||||
/*****************/
|
/*****************/
|
||||||
/* configuration */
|
/* configuration */
|
||||||
/*****************/
|
/*****************/
|
||||||
|
@ -92,46 +100,6 @@
|
||||||
|
|
||||||
typedef unsigned long rb_num_t;
|
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;
|
struct iseq_compile_data_ensure_node_stack;
|
||||||
|
|
||||||
typedef struct rb_compile_option_struct {
|
typedef struct rb_compile_option_struct {
|
||||||
|
@ -146,31 +114,6 @@ typedef struct rb_compile_option_struct {
|
||||||
int debug_level;
|
int debug_level;
|
||||||
} rb_compile_option_t;
|
} 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
|
#if 1
|
||||||
#define GetCoreDataFromValue(obj, type, ptr) do { \
|
#define GetCoreDataFromValue(obj, type, ptr) do { \
|
||||||
ptr = (type*)DATA_PTR(obj); \
|
ptr = (type*)DATA_PTR(obj); \
|
||||||
|
@ -505,6 +448,7 @@ typedef struct rb_thread_struct
|
||||||
|
|
||||||
/* iseq.c */
|
/* iseq.c */
|
||||||
VALUE rb_iseq_new(NODE*, VALUE, VALUE, VALUE, VALUE);
|
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_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_new_with_opt(NODE*, VALUE, VALUE, VALUE, VALUE, const rb_compile_option_t*);
|
||||||
VALUE rb_iseq_compile(VALUE src, VALUE file, VALUE line);
|
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);
|
VALUE ruby_iseq_disasm_insn(VALUE str, VALUE *iseqval, int pos, rb_iseq_t *iseq, VALUE child);
|
||||||
const char *ruby_node_name(int node);
|
const char *ruby_node_name(int node);
|
||||||
VALUE rb_iseq_clone(VALUE iseqval, VALUE newcbase);
|
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_cISeq;
|
||||||
RUBY_EXTERN VALUE rb_cRubyVM;
|
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_REF(p) ((void *)(((VALUE)p) & ~0x03))
|
||||||
#define GC_GUARDED_PTR_P(p) (((VALUE)p) & 0x01)
|
#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_PREVIOUS_CONTROL_FRAME(cfp) (cfp+1)
|
||||||
#define RUBY_VM_NEXT_CONTROL_FRAME(cfp) (cfp-1)
|
#define RUBY_VM_NEXT_CONTROL_FRAME(cfp) (cfp-1)
|
||||||
#define RUBY_VM_END_CONTROL_FRAME(th) \
|
#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) \
|
#define RUBY_VM_GET_CFP_FROM_BLOCK_PTR(b) \
|
||||||
((rb_control_frame_t *)((VALUE *)(b) - 5))
|
((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 */
|
/* VM related object allocate functions */
|
||||||
/* TODO: should be static functions */
|
/* TODO: should be static functions */
|
||||||
VALUE rb_thread_alloc(VALUE klass);
|
VALUE rb_thread_alloc(VALUE klass);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue