summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog42
-rw-r--r--Makefile.in7
-rw-r--r--class.c7
-rw-r--r--configure.in22
-rw-r--r--defines.h2
-rw-r--r--dict.c16
-rw-r--r--dir.c4
-rw-r--r--dln.c2
-rw-r--r--env.h14
-rw-r--r--eval.c558
-rw-r--r--file.c6
-rw-r--r--gc.c133
-rw-r--r--glob.c6
-rw-r--r--inits.c3
-rw-r--r--io.c32
-rw-r--r--methods.h22
-rw-r--r--missing/strdup.c4
-rw-r--r--missing/strftime.c6
-rw-r--r--node.h40
-rw-r--r--object.c6
-rw-r--r--pack.c6
-rw-r--r--parse.y380
-rw-r--r--process.c6
-rw-r--r--re.c69
-rw-r--r--ruby.c14
-rw-r--r--ruby.h85
-rw-r--r--sample/blk.rb9
-rw-r--r--sample/export.rb2
-rw-r--r--spec31
-rw-r--r--st.c2
-rw-r--r--string.c4
-rw-r--r--variable.c23
-rw-r--r--version.c6
-rw-r--r--version.h4
34 files changed, 804 insertions, 769 deletions
diff --git a/ChangeLog b/ChangeLog
index 52af56fba7..dfa5c85f51 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,44 @@
+Mon Dec 19 12:01:10 1994 Yukihiro Matsumoto (matz@ix-02)
+
+ * eval.c: ��ɬ�פˤʤä�PUSH_ENV, POP_ENV�򸺤餷����
+
+ * env.h: ENVION����self��Ϥ�������PUSH_ENV��super�ν����Τ������
+ ���Ѥ��뤳�Ȥˤ�����
+
+ * eval.c: �����Υ��֥������Ȳ����٤��ʤä��¹�®�٤��Ȥ��ᤷ����
+
+Mon Dec 17 23:01:10 1994 Yukihiro Matsumoto (matz@ix-02)
+
+ * eval.c: env.{argv,argc}��scope.local_vars�Υ��֥������Ȳ���
+
+ * eval.c: 1�����������ʣ��Block�����������Ȥ��ΥХ�������
+
+Fri Dec 16 15:52:06 1994 Yukihiro Matsumoto (matz@ix-02)
+
+ * parse.y: `&&'��`||'��ξ�դϤ��ĤǤ��P�Ȥ�����
+
+Thu Dec 15 00:16:04 1994 Yukihiro Matsumoto (matz@dyna)
+
+ * eval.c(Block): Block���֥������Ȥ�¸���
+
+ * node.h: NODE_QLIST�Ϥʤ��ʤä���
+
+ * eval.c(rb_call): �����ؤ�������̾���ǰ�Ĥ�����������Τ���ơ�
+ ���٤˥��ԡ�����褦�ˤ�����
+
+ * eval.c(rb_call): ruby�ǵ��Ҥ��줿�᥽�åɤؤΰ����Ϥ���inline����
+
+ * eval.c: ���ƥ졼��Ƚ����������̽񤭴�������Ŭ�ڤʥ��ƥ졼���Ƥ�
+ �Ф���ʤ��������㤨�С�[foo(),bar()]{i|baz(i)}�פ�foo��bar�⥤
+ �ƥ졼���Ȥ��ƸƤӽФ���*�ʤ�*��
+
+ * eval.c(rb_call): SCOPE������inline�����᥽�åɸƤӽФ��μ㴳�ι�
+ ®����
+
+Wed Dec 14 18:09:33 1994 Yukihiro Matsumoto (matz@ix-02)
+
+ * node.h: node�⥪�֥������Ȥˤ��롥��ä�GC�Dz������롥
+
Thu Dec 8 14:17:29 1994 Yukihiro Matsumoto (matz@ix-02)
* 0.60 released - alpha test baseline.
-
diff --git a/Makefile.in b/Makefile.in
index 3a88a991be..a63ee53af8 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -16,7 +16,7 @@ CFLAGS = -g
LDFLAGS = @STATIC@ $(CFLAGS)
LIBS = @LIBS@
DEFS = @DEFS@
-MISSING = @LIBOBJS@
+MISSING = @LIBOBJS@ @ALLOCA@
prefix = /usr/local
binprefix =
@@ -78,8 +78,7 @@ OBJS = array.o \
time.o \
variable.o \
version.o \
- $(MISSING) \
- @ALLOCA@
+ $(MISSING)
PROGRAM = ruby
@@ -95,6 +94,8 @@ $(bindir)/$(PROGRAM): $(PROGRAM)
install: $(bindir)/$(PROGRAM)
clean:; @rm -f $(OBJS)
+
+realclean:; @rm -f $(OBJS)
@rm -f core ruby *~ config.status Makefile
.c.o:
$(CC) $(CFLAGS) $(CPPFLAGS) -c $<
diff --git a/class.c b/class.c
index 4a36f0e928..fa1860060a 100644
--- a/class.c
+++ b/class.c
@@ -3,7 +3,7 @@
class.c -
$Author: matz $
- $Date: 1994/11/01 08:27:48 $
+ $Date: 1994/12/16 00:59:42 $
created at: Tue Aug 10 15:05:44 JST 1993
Copyright (C) 1994 Yukihiro Matsumoto
@@ -86,7 +86,6 @@ rb_define_class_id(id, super)
/* make metaclass */
RBASIC(cls)->class = single_class_new(super?super->class:C_Class);
- literalize(RBASIC(cls)->class);
return (VALUE)cls;
}
@@ -193,10 +192,6 @@ rb_add_method(class, mid, node, noex)
Warning("redefine %s", rb_id2name(mid));
}
rb_clear_cache(body);
- freenode(body);
- }
- if (node && node->type != NODE_FBODY) {
- node = NEW_FBODY(node, mid);
}
body = NEW_METHOD(node, noex);
st_insert(class->m_tbl, mid, body);
diff --git a/configure.in b/configure.in
index 9eec8ad999..5ee5463ab9 100644
--- a/configure.in
+++ b/configure.in
@@ -16,17 +16,20 @@ fi
AC_SUBST(STATIC)dnl
AC_PROG_YACC
AC_PROG_INSTALL
-AC_HAVE_HEADERS(unistd.h syscall.h a.out.h)
+AC_HAVE_HEADERS(unistd.h stdlib.h syscall.h a.out.h dirent.h\
+ string.h strings.h)
AC_DIR_HEADER
AC_GETGROUPS_T
AC_RETSIGTYPE
-AC_REPLACE_FUNCS(memmove mkdir strerror strftime)
-AC_REPLACE_FUNCS(strstr strtol strtoul strdup)
-AC_HAVE_FUNCS(fmod killpg socket random)
-AC_HAVE_FUNCS(wait4 waitpid syscall getcwd)
-AC_HAVE_FUNCS(setruid seteuid setreuid)
-AC_HAVE_FUNCS(setrgid setegid setregid)
-AC_HAVE_FUNCS(getpriority sigprocmask)
+AC_HAVE_LIBRARY(m, [LIBS="$LIBS -lm"])
+AC_HAVE_LIBRARY(dbm, [LIBS="$LIBS -ldbm"])
+AC_HAVE_LIBRARY(socket, [LIBS="$LIBS -lsocket"])
+AC_HAVE_LIBRARY(crypt, [LIBS="$LIBS -lcrypt"])
+AC_REPLACE_FUNCS(memmove mkdir strerror strftime\
+ strstr strtol strtoul strdup)
+AC_HAVE_FUNCS(fmod killpg socket random wait4 waitpid syscall getcwd\
+ setruid seteuid setreuid setrgid setegid setregid\
+ getpriority sigprocmask)
AC_FUNC_CHECK(setenv, [], AC_HAVE_FUNCS(putenv))
case "$LIBOBJS" in
@@ -56,8 +59,5 @@ AC_COMPILE_CHECK([pw_comment in struct passwd], [#include <pwd.h>],
[struct passwd pw; pw.pw_comment;], AC_DEFINE(PW_COMMENT))
AC_COMPILE_CHECK([pw_expire in struct passwd], [#include <pwd.h>],
[struct passwd pw; pw.pw_expire;], AC_DEFINE(PW_EXPIRE))
-AC_HAVE_LIBRARY(m, [LIBS="$LIBS -lm"])
-AC_HAVE_LIBRARY(dbm, [LIBS="$LIBS -ldbm"])
-AC_HAVE_LIBRARY(socket, [LIBS="$LIBS -lsocket"])
AC_OUTPUT(Makefile)
mv confdefs.h config.h
diff --git a/defines.h b/defines.h
index d5e86072af..4928db7d1e 100644
--- a/defines.h
+++ b/defines.h
@@ -3,7 +3,7 @@
defines.h -
$Author: matz $
- $Date: 1994/11/18 01:37:26 $
+ $Date: 1994/12/09 01:28:22 $
created at: Wed May 18 00:21:44 JST 1994
************************************************/
diff --git a/dict.c b/dict.c
index 74bfc22e03..3db2501fd9 100644
--- a/dict.c
+++ b/dict.c
@@ -3,7 +3,7 @@
dict.c -
$Author: matz $
- $Date: 1994/12/06 09:29:53 $
+ $Date: 1994/12/19 08:30:00 $
created at: Mon Nov 22 18:51:18 JST 1993
Copyright (C) 1994 Yukihiro Matsumoto
@@ -90,8 +90,16 @@ Fdic_indexes(dic, args)
struct RArray *new;
int i = 0;
- if (!args || args->len == 1 && TYPE(args->ptr) != T_ARRAY) {
- args = (struct RArray*)rb_to_a(args->ptr[0]);
+ if (!args || args->len == 0) {
+ Fail("wrong # of argment");
+ }
+ else if (args->len == 1) {
+ if (TYPE(args->ptr[0])) {
+ args = (struct RArray*)rb_to_a(args->ptr[0]);
+ }
+ else {
+ args = (struct RArray*)args->ptr[0];
+ }
}
new = (struct RArray*)ary_new2(args->len);
@@ -583,7 +591,7 @@ Init_Dict()
rb_define_single_method(envtbl,"to_s", Fenv_to_s, 0);
rb_include_module(CLASS_OF(envtbl), M_Enumerable);
- rb_define_variable("$ENV", &envtbl, Qnil, rb_readonly_hook);
+ rb_define_variable("$ENV", &envtbl, Qnil, rb_readonly_hook, 0);
rb_define_private_method(C_Kernel, "getenv", Fgetenv, 1);
rb_define_private_method(C_Kernel, "setenv", Fsetenv, 2);
diff --git a/dir.c b/dir.c
index f139c40554..84299127ca 100644
--- a/dir.c
+++ b/dir.c
@@ -3,20 +3,20 @@
dir.c -
$Author: matz $
- $Date: 1994/12/06 09:29:55 $
+ $Date: 1994/12/09 09:40:18 $
created at: Wed Jan 5 09:51:01 JST 1994
Copyright (C) 1994 Yukihiro Matsumoto
************************************************/
+#include <sys/param.h>
#include "ruby.h"
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
-#include <sys/param.h>
/* unistd.h defines _POSIX_VERSION on POSIX.1 systems. */
#if defined(DIRENT) || defined(_POSIX_VERSION)
diff --git a/dln.c b/dln.c
index b15c01bce1..44179ec3e9 100644
--- a/dln.c
+++ b/dln.c
@@ -3,7 +3,7 @@
dln.c -
$Author: matz $
- $Date: 1994/11/18 01:37:28 $
+ $Date: 1994/12/09 01:28:23 $
created at: Tue Jan 18 17:05:06 JST 1994
Copyright (C) 1994 Yukihiro Matsumoto
diff --git a/env.h b/env.h
index ebf378073f..ebed038d39 100644
--- a/env.h
+++ b/env.h
@@ -3,8 +3,8 @@
env.h -
$Author: matz $
- $Revision: 1.5 $
- $Date: 1994/11/01 08:27:51 $
+ $Revision: 1.7 $
+ $Date: 1994/12/19 08:30:01 $
created at: Mon Jul 11 11:53:03 JST 1994
************************************************/
@@ -12,27 +12,21 @@
#define ENV_H
extern struct ENVIRON {
- VALUE self;
int argc;
VALUE *argv;
+ VALUE arg_ary;
ID last_func;
struct RClass *last_class;
struct ENVIRON *prev;
} *the_env;
-#undef Qself
-#define Qself the_env->self
-
extern struct SCOPE {
ID *local_tbl;
VALUE *local_vars;
- VALUE block;
- int flags;
+ VALUE var_ary;
struct SCOPE *prev;
} *the_scope;
-#define VARS_MALLOCED (1<<2)
-
extern int rb_in_eval;
#endif /* ENV_H */
diff --git a/eval.c b/eval.c
index fac68662c9..e40d78121f 100644
--- a/eval.c
+++ b/eval.c
@@ -3,7 +3,7 @@
eval.c -
$Author: matz $
- $Date: 1994/12/06 09:29:59 $
+ $Date: 1994/12/19 08:39:17 $
created at: Thu Jun 10 14:22:17 JST 1993
Copyright (C) 1994 Yukihiro Matsumoto
@@ -92,12 +92,16 @@ rb_get_method_body(classp, idp, noexp)
ent->origin = origin;
ent->method = body->nd_body;
ent->noex = body->nd_noex;
+ body = body->nd_body;
- if (ent->method == Qnil) return Qnil;
- *idp = ent->method->nd_mid;
+ if (body == Qnil) return Qnil;
+ if (nd_type(body) == NODE_FBODY) {
+ *idp = body->nd_mid;
+ body = body->nd_head;
+ }
*classp = origin;
if (noexp) *noexp = ent->noex;
- return ent->method->nd_head;
+ return body;
}
void
@@ -114,17 +118,16 @@ rb_alias(class, name, def)
Fail("undefined method `%s' for class `%s'",
rb_id2name(def), rb_class2name(class));
}
- body->nd_body->nd_cnt++;
if (st_lookup(class->m_tbl, name, &old)) {
if (verbose) {
Warning("redefine %s", rb_id2name(name));
}
rb_clear_cache(old->nd_body);
- freenode(old);
}
- st_insert(class->m_tbl, name, NEW_METHOD(body->nd_body, body->nd_noex));
+ st_insert(class->m_tbl, name, NEW_METHOD(NEW_FBODY(body->nd_body, name),
+ body->nd_noex));
}
void
@@ -199,28 +202,33 @@ extern NODE *eval_tree;
extern int nerrs;
extern VALUE TopSelf;
+VALUE Qself;
+
+#define PUSH_SELF(s) { \
+ VALUE __saved_self__ = Qself; \
+ Qself = s; \
+
+#define POP_SELF() Qself = __saved_self__; }
+
struct ENVIRON *the_env, *top_env;
struct SCOPE *the_scope, *top_scope;
-#define PUSH_ENV() {\
- struct ENVIRON _this;\
- _this.prev = the_env;\
- the_env = &_this;\
-
-#define DUP_ENV() {\
- struct ENVIRON _this;\
- _this = *the_env;\
- _this.prev = the_env;\
- the_env = &_this;\
+#define PUSH_ENV() { \
+ struct ENVIRON _this; \
+ _this.prev = the_env; \
+ the_env = &_this; \
#define POP_ENV() the_env = the_env->prev; }
struct BLOCK {
NODE *var;
NODE *body;
+ VALUE self;
struct ENVIRON env;
struct SCOPE scope;
int level;
+ VALUE block;
+ int iter;
struct BLOCK *prev;
} *the_block;
@@ -229,38 +237,64 @@ struct BLOCK {
_this.level = tag_level; \
_this.var=v; \
_this.body = b; \
+ _this.self = Qself; \
_this.env = *the_env; \
_this.scope = *the_scope; \
+ _this.block = Qnil; \
_this.prev = the_block; \
the_block = &_this; \
+#define PUSH_BLOCK2(b) { \
+ b->prev = the_block; \
+ the_block = b; \
+
#define POP_BLOCK() the_block = the_block->prev; }
+static struct iter {
+ int iter;
+ struct iter *prev;
+} *iter;
+
+#define PUSH_ITER(i) {\
+ struct iter __iter__;\
+ __iter__.prev = iter;\
+ __iter__.iter = (i);\
+ iter = &__iter__;\
+
+#define POP_ITER() \
+ iter = iter->prev;\
+}
+
static int tag_level, target_level;
static struct tag {
int level;
jmp_buf buf;
struct gc_list *gclist;
+ VALUE self;
struct ENVIRON *env;
+ struct iter *iter;
struct tag *prev;
} *prot_tag;
-#define PUSH_TAG() {\
- struct tag _this;\
- _this.level= ++tag_level;\
- _this.env = the_env;\
- _this.prev = prot_tag;\
- prot_tag = &_this;\
+#define PUSH_TAG() { \
+ struct tag _this; \
+ _this.level= ++tag_level; \
+ _this.self = Qself; \
+ _this.env = the_env; \
+ _this.iter = iter; \
+ _this.prev = prot_tag; \
+ prot_tag = &_this; \
-#define POP_TAG() \
- tag_level--;\
- prot_tag = prot_tag->prev;\
+#define EXEC_TAG() (setjmp(prot_tag->buf))
+#define JUMP_TAG(val) { \
+ the_env = prot_tag->env; \
+ iter = prot_tag->iter; \
+ longjmp(prot_tag->buf,(val)); \
}
-#define EXEC_TAG() (setjmp(prot_tag->buf))
-#define JUMP_TAG(val) {\
- the_env = prot_tag->env;\
- longjmp(prot_tag->buf,(val));\
+#define POP_TAG() \
+ tag_level--; \
+ prot_tag = prot_tag->prev; \
}
#define TAG_RETURN 1
@@ -293,8 +327,6 @@ struct class_link {
struct SCOPE _scope; \
_scope = *the_scope; \
_scope.prev = the_scope; \
- _scope.block = Qnil; \
- _scope.flags = 0; \
the_scope = &_scope; \
#define POP_SCOPE() the_scope = the_scope->prev; }
@@ -317,8 +349,6 @@ extern VALUE rb_stderr;
extern int sourceline;
extern char *sourcefile;
-static int iter_level = 0;
-
VALUE
rb_self()
{
@@ -387,20 +417,13 @@ Eval(toplevel)
tree = eval_tree;
eval_tree = Qnil;
- sourcefile = tree->src;
+ sourcefile = tree->file;
PUSH_TAG();
if ((state = EXEC_TAG()) == 0) {
result = rb_eval(tree);
}
POP_TAG();
-/* #define PURIFY_D /* define when purify'ing */
-#ifdef PURIFY_D
- freenode(tree);
-#else
- /* you don't have to free at toplevel */
- if (!toplevel) freenode(tree);
-#endif
if (state) JUMP_TAG(state);
return result;
@@ -413,7 +436,7 @@ ruby_run()
if (nerrs > 0) exit(nerrs);
Init_stack();
- rb_define_variable("$!", &errstr, Qnil, Qnil);
+ rb_define_variable("$!", &errstr, Qnil, Qnil, 0);
errat = Qnil; /* clear for execution */
PUSH_TAG();
@@ -463,12 +486,11 @@ rb_trap_eval(cmd)
{
int state, go_out;
- DUP_ENV();
+ PUSH_SELF(TopSelf);
PUSH_CLASS();
PUSH_TAG();
PUSH_SCOPE();
if ((state = EXEC_TAG()) == 0) {
- the_env->self = TopSelf;
the_class = (struct RClass*)C_Object;
the_scope->local_vars = top_scope->local_vars;
the_scope->local_tbl = top_scope->local_tbl;
@@ -482,7 +504,7 @@ rb_trap_eval(cmd)
POP_SCOPE();
POP_TAG();
POP_CLASS();
- POP_ENV();
+ POP_SELF();
if (go_out) JUMP_TAG(state);
}
@@ -493,23 +515,23 @@ rb_trap_eval(cmd)
argc = 0;\
argv = Qnil;\
}\
- else if (n->type == NODE_ARRAY) {\
- int i;\
- for (argc=0; n; n=n->nd_next) argc++;\
+ else if (nd_type(n) == NODE_ARRAY) {\
+ argc=n->nd_alen;\
if (argc > 0) {\
+ int i;\
n = node->nd_args;\
argv = (VALUE*)alloca(sizeof(VALUE)*argc);\
- for (i=0;n;n=n->nd_next) {\
- argv[i++] = rb_eval(n->nd_head);\
+ for (i=0;i<argc;i++) {\
+ argv[i] = rb_eval(n->nd_head);\
+ n=n->nd_next;\
}\
}\
}\
else {\
- args = rb_eval(n);\
- if (TYPE(args) != T_ARRAY)\
- args = rb_to_a(args);\
- argc = RARRAY(args)->len;\
- argv = RARRAY(args)->ptr;\
+ argc = -2;\
+ argv = (VALUE*)rb_eval(n);\
+ if (TYPE(argv) != T_ARRAY)\
+ argv = (VALUE*)rb_to_a(argv);\
}\
}
@@ -537,7 +559,7 @@ rb_eval(node)
}
#endif
- switch (node->type) {
+ switch (nd_type(node)) {
case NODE_BLOCK:
while (node->nd_next) {
rb_eval(node->nd_head);
@@ -569,7 +591,7 @@ rb_eval(node)
val = rb_eval(node->nd_head);
node = node->nd_body;
while (node) {
- if (node->type == NODE_WHEN) {
+ if (nd_type(node) == NODE_WHEN) {
NODE *tag = node->nd_head;
while (tag) {
@@ -667,31 +689,23 @@ rb_eval(node)
case NODE_ITER:
case NODE_FOR:
{
- int iter_saved = iter_level;
-
- DUP_ENV();
PUSH_BLOCK(node->nd_var, node->nd_body);
PUSH_TAG();
state = EXEC_TAG();
if (state == 0) {
- if (node->type == NODE_ITER) {
- iter_level = 1;
+ if (nd_type(node) == NODE_ITER) {
result = rb_eval(node->nd_iter);
}
else {
VALUE recv;
- iter_level = 0;
recv = rb_eval(node->nd_iter);
- iter_level = 1;
- result = rb_call(CLASS_OF(recv), recv, each, 0, Qnil);
+ result = rb_call(CLASS_OF(recv),recv,each,0,Qnil,0,1);
}
}
POP_TAG();
POP_BLOCK();
- POP_ENV();
- iter_level = iter_saved;
switch (state) {
case 0:
break;
@@ -730,6 +744,17 @@ rb_eval(node)
}
return result;
+ case NODE_IYIELD:
+ {
+ VALUE val;
+
+ val = rb_eval(node->nd_stts);
+ PUSH_ITER(1);
+ result = rb_yield(val);
+ POP_ITER();
+ }
+ return result;
+
case NODE_PROT:
PUSH_TAG();
switch (state = EXEC_TAG()) {
@@ -817,83 +842,26 @@ rb_eval(node)
break;
case NODE_CALL:
- case NODE_CALL2:
+ case NODE_ICALL:
{
- VALUE recv, *argv;
- int argc, iter_saved = iter_level;
- VALUE args = Qnil; /* used in SETUP_ARGS */
+ VALUE recv;
+ int argc; VALUE *argv; /* used in SETUP_ARGS */
VALUE buf[3];
- iter_level = 0; /* recv & args are not iter. */
recv = node->nd_recv?rb_eval(node->nd_recv):Qself;
-#if 0
SETUP_ARGS;
-#else
- {
- NODE *n = node->nd_args;
- if (n == Qnil) {
- argc = 0;
- argv = Qnil;
- }
- else if (n->type == NODE_ARRAY) {
- if (n->nd_next == Qnil) {
- /* 1 arg */
- argc = 1;
- buf[0] = rb_eval(n->nd_head);
- argv = buf;
- }
- else if (n->nd_next->nd_next == Qnil) {
- /* 2 args */
- argc = 2;
- buf[0] = rb_eval(n->nd_head);
- buf[1] = rb_eval(n->nd_next->nd_head);
- argv = buf;
- }
- else if (n->nd_next->nd_next->nd_next == Qnil) {
- /* 3 args */
- argc = 3;
- buf[0] = rb_eval(n->nd_head);
- buf[1] = rb_eval(n->nd_next->nd_head);
- buf[2] = rb_eval(n->nd_next->nd_next->nd_head);
- argv = buf;
- }
- else {
- int i;
- for (argc=0; n; n=n->nd_next) argc++;
- n = node->nd_args;
- argv = (VALUE*)alloca(sizeof(VALUE)*argc);
- for (i=0;n;n=n->nd_next) {
- argv[i++] = rb_eval(n->nd_head);
- }
- }
- }
- else {
- args = rb_eval(n);
- if (TYPE(args) != T_ARRAY)
- args = rb_to_a(args);
- argc = RARRAY(args)->len;
- argv = RARRAY(args)->ptr;
- }
- }
-#endif
- iter_level = iter_saved; /* restore iter. level */
-
return rb_call(CLASS_OF(recv),recv,node->nd_mid,argc,argv,
- node->nd_recv?0:1);
+ node->nd_recv?0:1, nd_type(node)==NODE_ICALL);
}
break;
case NODE_SUPER:
case NODE_ZSUPER:
{
- int iter_saved = iter_level;
- int i, argc;
- VALUE *argv;
- VALUE args = Qnil; /* used in SETUP_ARGS */
-
- iter_level = 0; /* recv & args are not iter. */
+ int i;
+ int argc; VALUE *argv; /* used in SETUP_ARGS */
- if (node->type == NODE_ZSUPER) {
+ if (nd_type(node) == NODE_ZSUPER) {
argc = the_env->argc;
argv = the_env->argv;
}
@@ -901,11 +869,8 @@ rb_eval(node)
SETUP_ARGS;
}
- if (iter_saved == 0) iter_level = 1;
result = rb_call(the_env->last_class->super, Qself,
- the_env->last_func, argc, argv, 1);
- /* restore iter. level */
- iter_level = iter_saved;
+ the_env->last_func, argc, argv, 1, iter->iter);
}
return result;
@@ -929,8 +894,6 @@ rb_eval(node)
result = rb_eval(node->nd_body);
}
POP_TAG();
- if (the_scope->local_vars && (the_scope->flags&VARS_MALLOCED))
- free(the_scope->local_vars);
POP_SCOPE();
if (state != 0) JUMP_TAG(state);
@@ -989,7 +952,8 @@ rb_eval(node)
case NODE_CVAR:
{
VALUE val = rb_const_get(node->nd_vid);
- node->type = NODE_CONST;
+
+ nd_set_type(node, NODE_CONST);
node->nd_cval = val;
return val;
}
@@ -1026,7 +990,7 @@ rb_eval(node)
int i;
NODE *list;
- for (i=0, list=node; list; list=list->nd_next) i++;
+ i = node->nd_alen;
ary = ary_new2(i);
for (i=0;node;node=node->nd_next) {
RARRAY(ary)->ptr[i++] = rb_eval(node->nd_head);
@@ -1050,7 +1014,7 @@ rb_eval(node)
str = str_new3(node->nd_lit);
while (list) {
- if (list->nd_head->type == NODE_STR) {
+ if (nd_type(list->nd_head) == NODE_STR) {
str2 = list->nd_head->nd_lit;
}
else {
@@ -1062,13 +1026,13 @@ rb_eval(node)
}
list = list->nd_next;
}
- if (node->type == NODE_DREGX) {
+ if (nd_type(node) == NODE_DREGX) {
return regexp_new(RSTRING(str)->ptr, RSTRING(str)->len);
}
- if (node->type == NODE_XSTR2) {
+ if (nd_type(node) == NODE_XSTR2) {
return rb_xstring(str);
}
- if (node->type == NODE_DGLOB) {
+ if (nd_type(node) == NODE_DGLOB) {
return glob_new(str);
}
return str;
@@ -1085,38 +1049,9 @@ rb_eval(node)
Fail("Wrong # of arguments(%d for 1)", the_env->argc);
return rb_ivar_set(node->nd_vid, the_env->argv[0]);
- case NODE_ARGS:
- {
- NODE *local;
- int i, len;
-
- i = node->nd_cnt;
- len = the_env->argc;
- if (i > len || (node->nd_rest == -1 && i < len))
- Fail("Wrong # of arguments(%d for %d)", len, i);
-
- local = node->nd_frml;
- if (the_scope->local_vars == Qnil)
- Bug("unexpected local variable asignment");
-
- for (i=0;local;i++) {
- the_scope->local_vars[(int)local->nd_head] = the_env->argv[i];
- local = local->nd_next;
- }
- if (node->nd_rest >= 0) {
- if (the_env->argc == 0)
- the_scope->local_vars[node->nd_rest] = ary_new();
- else
- the_scope->local_vars[node->nd_rest] =
- ary_new4(the_env->argc-i, the_env->argv+i);
- }
- }
- return Qnil;
-
case NODE_DEFN:
{
if (node->nd_defn) {
- node->nd_defn->nd_cnt++;
rb_add_method(the_class,node->nd_mid,node->nd_defn,
node->nd_noex);
}
@@ -1132,7 +1067,6 @@ rb_eval(node)
Fail("Can't define method \"%s\" for nil",
rb_id2name(node->nd_mid));
}
- node->nd_defn->nd_cnt++;
rb_add_method(rb_single_class(recv),
node->nd_mid, node->nd_defn, 0);
}
@@ -1169,21 +1103,19 @@ rb_eval(node)
if (verbose) {
Warning("redefine class %s", rb_id2name(node->nd_cname));
}
- unliteralize(class);
}
- DUP_ENV();
+ PUSH_SELF((VALUE)the_class);
PUSH_CLASS();
the_class = (struct RClass*)
rb_define_class_id(node->nd_cname, super);
- Qself = (VALUE)the_class;
PUSH_TAG();
if ((state = EXEC_TAG()) == 0) {
rb_eval(node->nd_body);
}
POP_TAG();
POP_CLASS();
- POP_ENV();
+ POP_SELF();
if (state) JUMP_TAG(state);
}
return Qnil;
@@ -1196,20 +1128,18 @@ rb_eval(node)
if (verbose) {
Warning("redefine module %s", rb_id2name(node->nd_cname));
}
- unliteralize(module);
}
- DUP_ENV();
+ PUSH_SELF((VALUE)the_class);
PUSH_CLASS();
the_class = (struct RClass*)rb_define_module_id(node->nd_cname);
- Qself = (VALUE)the_class;
PUSH_TAG();
if ((state = EXEC_TAG()) == 0) {
rb_eval(node->nd_body);
}
POP_TAG();
POP_CLASS();
- POP_ENV();
+ POP_SELF();
if (state) JUMP_TAG(state);
}
return Qnil;
@@ -1227,7 +1157,7 @@ rb_eval(node)
return Qnil;
default:
- Bug("unknown node type %d", node->type);
+ Bug("unknown node type %d", nd_type(node));
}
return Qnil; /* not reached */
}
@@ -1330,17 +1260,18 @@ rb_fail(mesg)
VALUE
iterator_p()
{
- if (iter_level == 0) return TRUE;
+ if (iter->iter) return TRUE;
return FALSE;
}
static VALUE
Fiterator_p()
{
- if (iter_level == -1) return TRUE;
+ if (iter->prev && iter->prev->iter) return TRUE;
return FALSE;
}
+
VALUE
rb_yield(val)
VALUE val;
@@ -1350,7 +1281,7 @@ rb_yield(val)
int state, go_out;
VALUE result;
- if (!iter_level == 0) {
+ if (!iterator_p()) {
Fail("yield called out of iterator");
}
@@ -1361,18 +1292,19 @@ rb_yield(val)
the_scope = &(block->scope);
the_block = block->prev;
if (block->var) {
- if (block->var->type == NODE_MASGN)
+ if (nd_type(block->var) == NODE_MASGN)
masign(block->var, val);
else
asign(block->var, val);
}
+ PUSH_ITER(block->iter);
PUSH_TAG();
node = block->body;
switch (state = EXEC_TAG()) {
redo:
case 0:
- if (node->type == NODE_CFUNC) {
+ if (nd_type(node) == NODE_CFUNC) {
result = (*node->nd_cfnc)(val,node->nd_argc);
}
else {
@@ -1395,6 +1327,7 @@ rb_yield(val)
break;
}
POP_TAG();
+ POP_ITER();
the_block = block;
the_env = the_env->prev;
the_scope = the_scope->prev;
@@ -1446,7 +1379,7 @@ asign(lhs, val)
NODE *lhs;
VALUE val;
{
- switch (lhs->type) {
+ switch (nd_type(lhs)) {
case NODE_GASGN:
rb_gvar_set(lhs->nd_entry, val);
break;
@@ -1495,28 +1428,23 @@ rb_iterate(it_proc, data1, bl_proc, data2)
VALUE (*it_proc)(), (*bl_proc)();
char *data1, *data2;
{
- int state, iter_saved;
+ int state;
VALUE retval;
NODE *node = NEW_CFUNC(bl_proc, data2);
struct BLOCK block;
- DUP_ENV();
+ PUSH_ITER(1);
PUSH_BLOCK(Qnil, node);
PUSH_TAG();
- iter_saved = iter_level;
- iter_level = 1;
state = EXEC_TAG();
if (state == 0) {
retval = (*it_proc)(data1);
}
- iter_level = iter_saved;
POP_TAG();
POP_BLOCK();
- POP_ENV();
-
- freenode(node);
+ POP_ITER();
switch (state) {
case 0:
@@ -1637,12 +1565,13 @@ rb_undefined(obj, id, noex)
}
static VALUE
-rb_call(class, recv, mid, argc, argv, func)
+rb_call(class, recv, mid, argc, argv, func, itr)
struct RClass *class;
- VALUE recv, *argv;
- int argc;
+ VALUE recv;
ID mid;
- int func;
+ int argc;
+ VALUE *argv;
+ int func, itr;
{
NODE *body;
int noex;
@@ -1655,7 +1584,7 @@ rb_call(class, recv, mid, argc, argv, func)
if (ent->method == Qnil) rb_undefined(recv, mid, 0);
class = ent->origin;
mid = ent->mid;
- body = ent->method->nd_head;
+ body = ent->method;
noex = ent->noex;
}
else {
@@ -1669,20 +1598,26 @@ rb_call(class, recv, mid, argc, argv, func)
if (!func && noex) rb_undefined(recv, mid, 1);
+ PUSH_ITER(itr);
+ PUSH_SELF(recv);
PUSH_ENV();
- Qself = recv;
the_env->last_func = mid;
- the_env->argc = argc;
- the_env->argv = argv;
- iter_level--;
-
the_env->last_class = class;
- if (body->type == NODE_CFUNC) {
+ if (argc < 0) {
+ the_env->arg_ary = (VALUE)argv;
+ argc = RARRAY(argv)->len;
+ argv = RARRAY(argv)->ptr;
+ }
+ else {
+ the_env->arg_ary = Qnil;
+ }
+
+ if (nd_type(body) == NODE_CFUNC) {
int len = body->nd_argc;
if (len >= 0 && argc != len) {
- Fail("Wrong # of arguments for(%d for %d)", argc, body->nd_argc);
+ Fail("Wrong # of arguments(%d for %d)", argc, body->nd_argc);
}
switch (len) {
@@ -1789,14 +1724,52 @@ rb_call(class, recv, mid, argc, argv, func)
}
else {
int state;
+ VALUE *local_vars;
- sourcefile = body->src;
+ sourcefile = body->file;
+ PUSH_SCOPE();
PUSH_TAG();
+ if (body->nd_cnt > 0) {
+ local_vars = (VALUE*)alloca(sizeof(VALUE)*body->nd_cnt);
+ memset(local_vars, 0, sizeof(VALUE)*body->nd_cnt);
+ the_scope->local_tbl = body->nd_tbl;
+ the_scope->local_vars = local_vars;
+ }
+ else {
+ local_vars = the_scope->local_vars = Qnil;
+ the_scope->local_tbl = Qnil;
+ }
+ body = body->nd_body;
+ if (nd_type(body) == NODE_BLOCK) {
+ NODE *node = body->nd_head;
+ NODE *local;
+ int i;
+
+ if (nd_type(node) != NODE_ARGS) {
+ Bug("no argument-node");
+ }
+
+ body = body->nd_next;
+ i = node->nd_cnt;
+ if (i > argc || (node->nd_rest == -1 && i < argc))
+ Fail("Wrong # of arguments(%d for %d)", argc, i);
+
+ if (local_vars) {
+ memcpy(local_vars, argv, argc*sizeof(VALUE));
+ if (node->nd_rest >= 0) {
+ if (argc == 0)
+ local_vars[node->nd_rest] = ary_new();
+ else
+ local_vars[node->nd_rest] = ary_new4(argc-i, argv+i);
+ }
+ }
+ }
state = EXEC_TAG();
if (state == 0) {
result = rb_eval(body);
}
POP_TAG();
+ POP_SCOPE();
switch (state) {
case 0:
break;
@@ -1819,8 +1792,9 @@ rb_call(class, recv, mid, argc, argv, func)
JUMP_TAG(state);
}
}
- iter_level++;
POP_ENV();
+ POP_SELF();
+ POP_ITER();
return result;
}
@@ -1831,18 +1805,7 @@ rb_apply(recv, mid, args)
struct RArray *args;
ID mid;
{
- VALUE *argv;
- int argc, i;
-
- if (args) {
- argc = args->len;
- argv = args->ptr;
- }
- else {
- argc = 0;
- argv = Qnil;
- }
- return rb_call(CLASS_OF(recv), recv, mid, argc, argv, recv==Qself);
+ return rb_call(CLASS_OF(recv), recv, mid, -2, (VALUE*)args, 1, 0);
}
static VALUE
@@ -1889,7 +1852,7 @@ rb_funcall(recv, mid, n, va_alist)
argv = Qnil;
}
- return rb_call(CLASS_OF(recv), recv, mid, n, argv, recv==Qself);
+ return rb_call(CLASS_OF(recv), recv, mid, n, argv, 1, 0);
}
int rb_in_eval = 0;
@@ -1906,7 +1869,6 @@ Feval(obj, src)
Check_Type(src, T_STRING);
PUSH_TAG();
- DUP_ENV();
rb_in_eval = 1;
node = eval_tree;
@@ -1926,7 +1888,6 @@ Feval(obj, src)
}
eval_tree = node;
POP_CLASS();
- POP_ENV();
POP_TAG();
if (state) JUMP_TAG(state);
@@ -2004,11 +1965,10 @@ Fload(obj, fname)
}
}
#endif
+ PUSH_SELF(TopSelf);
PUSH_TAG();
- DUP_ENV();
PUSH_CLASS();
the_class = (struct RClass*)C_Object;
- Qself = TopSelf;
the_scope->local_vars = top_scope->local_vars;
the_scope->local_tbl = top_scope->local_tbl;
rb_in_eval = 1;
@@ -2020,8 +1980,8 @@ Fload(obj, fname)
}
}
POP_CLASS();
- POP_ENV();
POP_TAG();
+ POP_SELF();
rb_in_eval = in_eval;
if (nerrs > 0) {
rb_fail(errstr);
@@ -2093,12 +2053,12 @@ Init_load()
char *path;
rb_load_path = ary_new();
- rb_define_variable("$:", &rb_load_path, Qnil, rb_readonly_hook);
- rb_define_variable("$LOAD_PATH", &rb_load_path, Qnil, rb_readonly_hook);
+ rb_define_variable("$:", &rb_load_path, Qnil, rb_readonly_hook, 0);
+ rb_define_variable("$LOAD_PATH", &rb_load_path, Qnil, rb_readonly_hook, 0);
rb_loadfiles = ary_new();
- rb_define_variable("$\"", &rb_load_path, Qnil, rb_readonly_hook);
- rb_define_variable("$LOAD_FILES", &rb_load_path, Qnil, rb_readonly_hook);
+ rb_define_variable("$\"", &rb_load_path, Qnil, rb_readonly_hook, 0);
+ rb_define_variable("$LOAD_FILES", &rb_load_path, Qnil, rb_readonly_hook,0);
addpath(getenv("RUBYLIB"));
addpath(RUBY_LIB);
@@ -2108,8 +2068,140 @@ Init_load()
Init_eval()
{
+ rb_global_variable(&eval_tree);
rb_define_private_method(C_Kernel, "exit", Fexit, -2);
rb_define_private_method(C_Kernel, "eval", Feval, 1);
rb_define_private_method(C_Kernel, "iterator_p", Fiterator_p, 0);
rb_define_method(C_Kernel, "apply", Fapply, -2);
}
+
+VALUE C_Block;
+static ID blkdata;
+
+static void
+blk_mark(data)
+ struct BLOCK *data;
+{
+ gc_mark_scope(&data->scope);
+ gc_mark(data->env.arg_ary);
+ gc_mark(data->var);
+ gc_mark(data->body);
+ gc_mark(data->self);
+}
+
+static void
+blk_free(data)
+ struct BLOCK *data;
+{
+ free(data->scope.local_tbl);
+ free(data->scope.local_vars);
+}
+
+static VALUE
+Sblk_new(class)
+{
+ VALUE blk;
+ struct BLOCK *data;
+ struct SCOPE *scope;
+ ID *tbl;
+ int len;
+
+ if (!iterator_p() && !Fiterator_p()) {
+ Fail("tryed to create Block out of iterator");
+ }
+ if (the_block->block) return the_block->block;
+ blk = obj_alloc(C_Block);
+ Make_Data_Struct(blk, blkdata, struct BLOCK, Qnil, blk_free, data);
+ memcpy(data, the_block, sizeof(struct BLOCK));
+ scope = the_scope;
+ tbl = data->scope.local_tbl;
+ len = tbl ? tbl[0] : 0;
+
+ while (scope && scope->local_tbl != tbl)
+ scope = scope->prev;
+
+ if (!scope) {
+ Bug("non-existing scope");
+ }
+ if (scope->var_ary == Qnil) {
+ scope->var_ary = ary_new4(len, scope->local_vars);
+ scope->local_vars = RARRAY(scope->var_ary)->ptr;
+ }
+ data->scope.local_vars = scope->local_vars;
+ data->scope.var_ary = scope->var_ary;
+
+ if (len > 0) {
+ len++;
+ tbl = ALLOC_N(ID, len);
+ memcpy(tbl, data->scope.local_tbl, sizeof(ID)*len);
+ data->scope.local_tbl = tbl;
+ }
+
+ the_block->block = blk;
+ return blk;
+}
+
+static VALUE
+Fblk_do(blk, args)
+ VALUE blk, args;
+{
+ struct BLOCK *data;
+ VALUE result;
+ int state;
+
+ switch (RARRAY(args)->len) {
+ case 0:
+ args = Qnil;
+ break;
+ case 1:
+ args = RARRAY(args)->ptr[0];
+ break;
+ }
+
+ Get_Data_Struct(blk, blkdata, struct BLOCK, data);
+
+ /* PUSH BLOCK from data */
+ PUSH_BLOCK2(data);
+ PUSH_ITER(1);
+ PUSH_TAG();
+
+ state = EXEC_TAG();
+ if (state == 0) {
+ result = rb_yield(args);
+ }
+
+ POP_TAG();
+ POP_ITER();
+ POP_BLOCK();
+
+ switch (state) {
+ case 0:
+ break;
+ case TAG_RETRY:
+ case IN_BLOCK|TAG_RETRY:
+ Fail("retry from block-closure");
+ break;
+ case TAG_BREAK:
+ case IN_BLOCK|TAG_BREAK:
+ Fail("break from block-closure");
+ break;
+ case TAG_RETURN:
+ case IN_BLOCK|TAG_RETURN:
+ Fail("return from block-closure");
+ break;
+ default:
+ JUMP_TAG(state);
+ }
+
+ return result;
+}
+
+Init_Block()
+{
+ C_Block = rb_define_class("Block", C_Object);
+
+ rb_define_single_method(C_Block, "new", Sblk_new, 0);
+
+ rb_define_method(C_Block, "do", Fblk_do, -2);
+ blkdata = rb_intern("blk");
+}
diff --git a/file.c b/file.c
index 1fc344778e..8fd04bc8b1 100644
--- a/file.c
+++ b/file.c
@@ -4,17 +4,17 @@
file.c -
$Author: matz $
- $Date: 1994/12/06 09:30:00 $
+ $Date: 1994/12/09 09:40:19 $
created at: Mon Nov 15 12:24:34 JST 1993
Copyright (C) 1994 Yukihiro Matsumoto
************************************************/
+#include <sys/param.h>
+#include <sys/time.h>
#include "ruby.h"
#include "io.h"
-#include <sys/time.h>
-#include <sys/param.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
diff --git a/gc.c b/gc.c
index 5c1d27e553..780d1902f8 100644
--- a/gc.c
+++ b/gc.c
@@ -3,7 +3,7 @@
gc.c -
$Author: matz $
- $Date: 1994/12/06 09:30:02 $
+ $Date: 1994/12/19 08:39:19 $
created at: Tue Oct 5 09:44:46 JST 1993
Copyright (C) 1994 Yukihiro Matsumoto
@@ -13,6 +13,7 @@
#include "ruby.h"
#include "env.h"
#include "st.h"
+#include "node.h"
#include <stdio.h>
#include <setjmp.h>
@@ -166,7 +167,7 @@ rb_global_variable(var)
struct RVALUE {
union {
struct {
- UINT flag; /* alway 0 for freed obj */
+ UINT flag; /* always 0 for freed obj */
struct RVALUE *next;
} free;
struct RObject object;
@@ -179,6 +180,7 @@ struct RVALUE {
struct RData data;
struct RStruct rstruct;
struct RBignum bignum;
+ struct RNode node;
} as;
} *freelist = Qnil;
@@ -189,7 +191,7 @@ struct heap_block {
struct RVALUE body[1];
} *heap_link = Qnil;
-#define SEG_SLOTS 4000
+#define SEG_SLOTS 10000
#define SEG_SIZE (SEG_SLOTS*sizeof(struct RVALUE))
static int heap_size;
@@ -252,53 +254,6 @@ data_new(datap, dfree, dmark)
return (VALUE)data;
}
-static struct literal_list {
- VALUE val;
- struct literal_list *next;
-} *Literal_List = Qnil;
-
-void
-literalize(obj)
- VALUE obj;
-{
- struct literal_list *tmp;
-
- tmp = (struct literal_list*)xmalloc(sizeof(struct literal_list));
- tmp->next = Literal_List;
- tmp->val = obj;
- Literal_List = tmp;
-}
-
-void
-unliteralize(obj)
- VALUE obj;
-{
- struct literal_list *ptr = Literal_List, *tmp;
-
- if (NIL_P(obj) || FIXNUM_P(obj)) return;
-
- if (!FL_TEST(obj, FL_LITERAL)) return;
- FL_UNSET(obj, FL_LITERAL);
-
- if (ptr->val == obj) {
- Literal_List = ptr->next;
- free(ptr);
- return;
- }
-
- while (ptr->next) {
- if (ptr->next->val == obj) {
- tmp = ptr->next;
- ptr->next = ptr->next->next;
- ptr = tmp;
- free(tmp);
- return;
- }
- ptr = ptr->next;
- }
- Bug("0x%x is not a literal object.", obj);
-}
-
extern st_table *rb_class_tbl;
static VALUE *stack_start_ptr;
@@ -311,7 +266,7 @@ looks_pointerp(p)
if (FIXNUM_P(p)) return FALSE;
while (heap) {
if (heap->beg <= p && p < heap->end
- && ((((char*)p) - ((char*)heap->beg)) % sizeof(struct RVALUE)) == 0)
+ && ((((char*)p)-((char*)heap->beg))%sizeof(struct RVALUE)) == 0)
return TRUE;
heap = heap->next;
}
@@ -384,6 +339,15 @@ mark_dict(tbl)
}
void
+gc_mark_maybe(obj)
+ void *obj;
+{
+ if (looks_pointerp(obj)) {
+ gc_mark(obj);
+ }
+}
+
+void
gc_mark(obj)
register struct RBasic *obj;
{
@@ -400,19 +364,21 @@ gc_mark(obj)
break;
}
- if (obj->iv_tbl) mark_tbl(obj->iv_tbl);
- gc_mark(obj->class);
switch (obj->flags & T_MASK) {
case T_ICLASS:
gc_mark(RCLASS(obj)->super);
if (RCLASS(obj)->c_tbl) mark_tbl(RCLASS(obj)->c_tbl);
+ mark_tbl(RCLASS(obj)->m_tbl);
break;
+
case T_CLASS:
gc_mark(RCLASS(obj)->super);
case T_MODULE:
if (RCLASS(obj)->c_tbl) mark_tbl(RCLASS(obj)->c_tbl);
+ mark_tbl(RCLASS(obj)->m_tbl);
gc_mark(RBASIC(obj)->class);
break;
+
case T_ARRAY:
{
int i, len = RARRAY(obj)->len;
@@ -422,20 +388,25 @@ gc_mark(obj)
gc_mark(ptr[i]);
}
break;
+
case T_DICT:
mark_dict(RDICT(obj)->tbl);
break;
+
case T_STRING:
if (RSTRING(obj)->orig) gc_mark(RSTRING(obj)->orig);
break;
+
case T_DATA:
if (RDATA(obj)->dmark) (*RDATA(obj)->dmark)(DATA_PTR(obj));
break;
+
case T_OBJECT:
case T_REGEXP:
case T_FLOAT:
case T_BIGNUM:
break;
+
case T_STRUCT:
{
int i, len = RSTRUCT(obj)->len;
@@ -445,9 +416,23 @@ gc_mark(obj)
gc_mark(ptr[i].value);
}
break;
+
+ case T_CONS:
+ gc_mark(RCONS(obj)->car);
+ gc_mark(RCONS(obj)->cdr);
+ break;
+
+ case T_NODE:
+ gc_mark_maybe(RNODE(obj)->u1.node);
+ gc_mark_maybe(RNODE(obj)->u2.node);
+ gc_mark_maybe(RNODE(obj)->u3.node);
+ return; /* no need to mark class & tbl */
+
default:
Bug("gc_mark(): unknown data type %d", obj->flags & T_MASK);
}
+ if (obj->iv_tbl) mark_tbl(obj->iv_tbl);
+ gc_mark(obj->class);
}
#define MIN_FREE_OBJ 512
@@ -509,15 +494,6 @@ gc_sweep()
}
}
-static
-freemethod(key, body)
- ID key;
- void *body;
-{
- freenode(body);
- return ST_CONTINUE;
-}
-
static void
obj_free(obj)
struct RBasic *obj;
@@ -529,14 +505,12 @@ obj_free(obj)
break;
}
- if (obj->iv_tbl) st_free_table(obj->iv_tbl);
switch (obj->flags & T_MASK) {
case T_OBJECT:
break;
case T_MODULE:
case T_CLASS:
rb_clear_cache2(obj);
- st_foreach(RCLASS(obj)->m_tbl, freemethod);
st_free_table(RCLASS(obj)->m_tbl);
if (RCLASS(obj)->c_tbl)
st_free_table(RCLASS(obj)->c_tbl);
@@ -569,15 +543,29 @@ obj_free(obj)
case T_BIGNUM:
free(RBIGNUM(obj)->digits);
break;
+ case T_NODE:
+ if (nd_type(obj) == NODE_SCOPE && RNODE(obj)->nd_tbl) {
+ free(RNODE(obj)->nd_tbl);
+ }
+ return; /* no need to free iv_tbl */
default:
Bug("gc_sweep(): unknown data type %d", obj->flags & T_MASK);
}
+ if (obj->iv_tbl) st_free_table(obj->iv_tbl);
+}
+
+void
+gc_mark_scope(scope)
+ struct SCOPE *scope;
+{
+ if (scope->local_vars && scope->var_ary == Qnil)
+ mark_locations_array(scope->local_vars, scope->local_tbl[0]);
+ gc_mark(scope->var_ary);
}
void
gc()
{
- struct literal_list *lit;
struct gc_list *list;
struct ENVIRON *env;
struct SCOPE *scope;
@@ -588,17 +576,9 @@ gc()
if (dont_gc) return;
dont_gc++;
- /* mark env stack */
- for (env = the_env; env; env = env->prev) {
- gc_mark(env->self);
- if (env->argv)
- mark_locations_array(env->argv, env->argc);
- }
-
/* mark scope stack */
for (scope = the_scope; scope; scope = scope->prev) {
- if (scope->local_vars)
- mark_locations_array(scope->local_vars, scope->local_tbl[0]);
+ gc_mark_scope(scope);
}
FLUSH_REGISTER_WINDOWS;
@@ -617,11 +597,6 @@ gc()
gc_mark(*list->varptr);
}
- /* mark literal objects */
- for (lit = Literal_List; lit; lit = lit->next) {
- gc_mark(lit->val);
- }
-
gc_mark_global_tbl();
mark_tbl(rb_class_tbl);
diff --git a/glob.c b/glob.c
index bc4ad8aad0..74dfe52fdd 100644
--- a/glob.c
+++ b/glob.c
@@ -2,15 +2,15 @@
glob.c -
- $Author$
- $Date$
+ $Author: matz $
+ $Date: 1994/12/09 09:47:52 $
created at: Mon Sep 12 18:56:43 JST 1994
************************************************/
+#include <sys/param.h>
#include "ruby.h"
#include "fnmatch.h"
-#include <sys/param.h>
char *strdup();
diff --git a/inits.c b/inits.c
index 6b227fb498..9a5b208306 100644
--- a/inits.c
+++ b/