diff options
-rw-r--r-- | ChangeLog | 42 | ||||
-rw-r--r-- | Makefile.in | 7 | ||||
-rw-r--r-- | class.c | 7 | ||||
-rw-r--r-- | configure.in | 22 | ||||
-rw-r--r-- | defines.h | 2 | ||||
-rw-r--r-- | dict.c | 16 | ||||
-rw-r--r-- | dir.c | 4 | ||||
-rw-r--r-- | dln.c | 2 | ||||
-rw-r--r-- | env.h | 14 | ||||
-rw-r--r-- | eval.c | 558 | ||||
-rw-r--r-- | file.c | 6 | ||||
-rw-r--r-- | gc.c | 133 | ||||
-rw-r--r-- | glob.c | 6 | ||||
-rw-r--r-- | inits.c | 3 | ||||
-rw-r--r-- | io.c | 32 | ||||
-rw-r--r-- | methods.h | 22 | ||||
-rw-r--r-- | missing/strdup.c | 4 | ||||
-rw-r--r-- | missing/strftime.c | 6 | ||||
-rw-r--r-- | node.h | 40 | ||||
-rw-r--r-- | object.c | 6 | ||||
-rw-r--r-- | pack.c | 6 | ||||
-rw-r--r-- | parse.y | 380 | ||||
-rw-r--r-- | process.c | 6 | ||||
-rw-r--r-- | re.c | 69 | ||||
-rw-r--r-- | ruby.c | 14 | ||||
-rw-r--r-- | ruby.h | 85 | ||||
-rw-r--r-- | sample/blk.rb | 9 | ||||
-rw-r--r-- | sample/export.rb | 2 | ||||
-rw-r--r-- | spec | 31 | ||||
-rw-r--r-- | st.c | 2 | ||||
-rw-r--r-- | string.c | 4 | ||||
-rw-r--r-- | variable.c | 23 | ||||
-rw-r--r-- | version.c | 6 | ||||
-rw-r--r-- | version.h | 4 |
34 files changed, 804 insertions, 769 deletions
@@ -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 $< @@ -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 @@ -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 ************************************************/ @@ -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); @@ -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) @@ -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 @@ -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 */ @@ -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"); +} @@ -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 @@ -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); @@ -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(); |