diff options
-rw-r--r-- | C-IF | 181 | ||||
-rw-r--r-- | CVS/Entries | 51 | ||||
-rw-r--r-- | CVS/Repository | 1 | ||||
-rw-r--r-- | ChangeLog | 131 | ||||
-rw-r--r-- | Makefile | 206 | ||||
-rw-r--r-- | Makefile.in | 10 | ||||
-rw-r--r-- | README | 51 | ||||
-rw-r--r-- | ToDo | 2 | ||||
-rw-r--r-- | array.c | 51 | ||||
-rw-r--r-- | bignum.c | 107 | ||||
-rw-r--r-- | bring | 57 | ||||
-rw-r--r-- | class.c | 61 | ||||
-rwxr-xr-x | config.status | 72 | ||||
-rw-r--r-- | configure.in | 4 | ||||
-rw-r--r-- | dbm.c | 25 | ||||
-rw-r--r-- | defines.h | 4 | ||||
-rw-r--r-- | dict.c | 87 | ||||
-rw-r--r-- | dir.c | 13 | ||||
-rw-r--r-- | enum.c | 43 | ||||
-rw-r--r-- | error.c | 3 | ||||
-rw-r--r-- | etc.c | 76 | ||||
-rw-r--r-- | eval.c | 257 | ||||
-rw-r--r-- | file.c | 26 | ||||
-rw-r--r-- | gc.c | 522 | ||||
-rw-r--r-- | io.c | 166 | ||||
-rw-r--r-- | math.c | 3 | ||||
-rw-r--r-- | methods.c | 59 | ||||
-rw-r--r-- | methods.h | 22 | ||||
-rw-r--r-- | missing/strftime.c | 4 | ||||
-rwxr-xr-x | newver.rb | 2 | ||||
-rw-r--r-- | node.h | 13 | ||||
-rw-r--r-- | numeric.c | 58 | ||||
-rw-r--r-- | object.c | 36 | ||||
-rw-r--r-- | pack.c | 9 | ||||
-rw-r--r-- | parse.y | 388 | ||||
-rw-r--r-- | process.c | 27 | ||||
-rw-r--r-- | random.c | 4 | ||||
-rw-r--r-- | range.c | 8 | ||||
-rw-r--r-- | re.c | 18 | ||||
-rw-r--r-- | regex.c | 2 | ||||
-rw-r--r-- | ruby.1 | 22 | ||||
-rw-r--r-- | ruby.c | 28 | ||||
-rw-r--r-- | ruby.h | 52 | ||||
-rw-r--r-- | sample/cbreak.rb | 6 | ||||
-rw-r--r-- | sample/fullpath.rb | 1 | ||||
-rw-r--r-- | sample/gctest.rb | 3 | ||||
-rwxr-xr-x | sample/getopts.test | 4 | ||||
-rw-r--r-- | sample/newver.rb | 13 | ||||
-rw-r--r-- | sample/opt_s.rb | 4 | ||||
-rw-r--r-- | sample/rcs.rb | 2 | ||||
-rw-r--r-- | sample/ruby-mode.el | 296 | ||||
-rw-r--r-- | sample/system.rb | 2 | ||||
-rw-r--r-- | sample/t1.rb | 8 | ||||
-rw-r--r-- | sample/trojan.pl | 12 | ||||
-rw-r--r-- | sample/trojan.rb | 12 | ||||
-rw-r--r-- | socket.c | 53 | ||||
-rw-r--r-- | spec | 192 | ||||
-rw-r--r-- | sprintf.c | 9 | ||||
-rw-r--r-- | string.c | 25 | ||||
-rw-r--r-- | struct.c | 23 | ||||
-rw-r--r-- | time.c | 34 | ||||
-rw-r--r-- | variable.c | 15 | ||||
-rw-r--r-- | version.h | 4 |
63 files changed, 1998 insertions, 1682 deletions
@@ -2,131 +2,164 @@ Ruby-C �����ե����� -VALUE +�� - Ruby���֥������Ȥ�ɽ�����뷿. ɬ�פ˱����ƥ��㥹�Ȥ����Ѥ���. + VALUE -Qnil + Ruby���֥������Ȥ�ɽ�����뷿. ɬ�פ˱����ƥ��㥹�Ȥ����Ѥ���. �Ȥ� + ���߷���ɽ������C�η���ruby.h�˵��Ҥ��Ƥ���R�ǻϤޤ빽¤�ΤǤ���. + VALUE�����˥��㥹�Ȥ��뤿���R�ǻϤޤ빽¤��̾��������ʸ���� + ����̾���Υޥ������Ѱդ���Ƥ���. - ���: nil���֥������� +�ѿ������ -Qself + Qnil - �ѿ�: ���ߤ�self���֥������Ȥ���. �����ѿ����ͤ��ѹ�������ϰʸ�� - self���ͤ��Τ�Τ��Ѥ�äƤ��ޤ��Τ�, ���Ť˹Ԥʤ�����. + ���: nil���֥������� -VALUE rb_define_class(char *name, VALUE super) + Qself - Ruby���饹���������. + �ѿ�: ���ߤ�self���֥������Ȥ���. ���̤˥�åɤˤ�self��ؤ����� + ��Ϳ������Τ�, �����ѿ��˥�����������ɬ�פϤʤ�. �����ѿ����ͤ� + �ѹ�������ϰʸ��self���ͤ��Τ�Τ��Ѥ�äƤ��ޤ��Τ�, ���Ť˹Ԥ� + ������. -VALUE rb_define_module(char *name) +���饹���⥸�塼����� - Ruby�⥸�塼����������. + VALUE rb_define_class(char *name, VALUE super) -rb_include_module(VALUE class, VALUE module) + super�Υ��֥��饹�Ȥ��ƿ�����Ruby���饹���������. - �⥸�塼��롼�ɤ���. class�����Ǥ�module�롼�ɤ��Ƥ� - ����ˤϲ��⤷�ʤ�(¿�ť��롼�ɤζػ�). + VALUE rb_define_module(char *name) -void rb_define_variable(char *name, VALUE *var, - VALUE (*get_hook), VALUE (*set+hook)()) + Ruby�⥸�塼����������. - Ruby��C�ȤǶ�ͭ���륰�����Х��ѿ����������. Ruby���֥������Ȥ�ؤ��� - ���ѿ������Ƥ��δؿ��ˤ�ä��������ʤ���Фʤ�ʤ�(GC�����ݸ�뤿 - ��). get_hook��Qnil�Ǥʤ���, �ѿ����Ȥκݤ�get_hook�˥��åȤ��줿�ؿ� - ���ƤФ��. set_hook��Qnil�Ǥʤ����ˤ������λ���set_hook���ƤФ��. + void rb_include_module(VALUE class, VALUE module) - �ѿ�̾��`$'�ǻϤޤ�ʤ����ˤϼ�ưŪ���ɲä����. �ѿ�̾�Ȥ���ruby�μ� - �̻ҤȤ��Ƶ�����ʤ�ʸ��(�㤨��` ')��ޤ���ˤ�ruby�ץ�����फ�饢 - �������Ǥ��ʤ��ʤ�. + �⥸�塼��롼�ɤ���. class�����Ǥ�module�롼�ɤ��� + ������ˤϲ��⤷�ʤ�(¿�ť��롼�ɤζػ�). -void rb_global_variable(VALUE *var) +����ѿ� - GC��Ruby����ϥ�����������ʤ���, Ruby���֥������Ȥ�ޤ�����ѿ���ޡ� - ��������. + void rb_define_variable(char *name, VALUE *var, + VALUE (*get_hook), VALUE (*set_hook)()) -void rb_read_only_hook() + Ruby��C�ȤǶ�ͭ���륰�����Х��ѿ����������. get_hook��Qnil�Ǥʤ���, + �ѿ����Ȥκݤ�get_hook�˥��åȤ��줿�ؿ����ƤФ��. set_hook��Qnil + �Ǥʤ����ˤ������λ���set_hook���ƤФ��. - �ɤ߽Ф����Ѥ��ѿ��Τ����set_hook�ؿ�. + �ѿ�̾��`$'�ǻϤޤ�ʤ����ˤϼ�ưŪ���ɲä����. �ѿ�̾�Ȥ���ruby�� + ���̻ҤȤ��Ƶ�����ʤ�ʸ��(�㤨��` ')��ޤ���ˤ�ruby�ץ�����फ + �饢�������Ǥ��ʤ��ʤ�. -rb_define_method(VALUE class, char *name, VALUE (*func)(), int argc) + void rb_global_variable(VALUE *var) - ��åɤ��������. argc��-1�λ�, ������argc, argv������Ϳ������. + GC��Ruby����ϥ�����������ʤ���, Ruby���֥������Ȥ�ޤ�����ѿ��� + �ޡ�������. -rb_define_single_method(VALUE class, char *name, VALUE (*func)(), int argc) + void rb_read_only_hook() - �ðۥ�åɤ��������. ������rb_define_method()��Ʊ��. + �ɤ߽Ф����Ѥ��ѿ��Τ����set_hook�ؿ�. �ͤ����ꤷ�褦�Ȥ�����㳰 + ��ȯ��������. -ID rb_intern(char *name) +���饹��� - ʸ������б�����ID���֤�. + void rb_define_const(VALUE class, char *name, VALUE val) -char *rb_id2name(ID id) + ���饹������������. - ID���б�����ʸ������֤�(�ǥХå���). +��å���� -VALUE rb_funcall(VALUE recv, ID mid, int narg, ...) + rb_define_method(VALUE class, char *name, VALUE (*func)(), int argc) - ��åɸƤӽФ�. ʸ����mid�����뤿��ˤ�rb_intern()��Ȥ�. + ��åɤ��������. argc��self����������ο�. argc��-1�λ�, ������ + argc, argv������Ϳ������. argc��-2�λ�, ������self, args(args�� + ������ޤ�ruby������)�Ȥ���������Ϳ������. -rb_iv_get(VALUE obj, char *name) + rb_define_single_method(VALUE class, char *name, VALUE (*func)(), int argc) - obj�Υ������ѿ�������. @����Ϥޤ�ʤ��������ѿ���Ruby�� - ������फ�饢�������Ǥ��ʤ�. + �ðۥ�åɤ��������. ������rb_define_method()��Ʊ��. -rb_iv_set(VALUE obj, char *name, VALUE val) + rb_scan_args(VALUE args, char *fmt, ...) - obj�Υ������ѿ���val�˥��åȤ���. + args������Ϳ����줿������ʬ��. fmt��ɬ�ܰ����ο�, �ղð����ο�, + �Ĥ�ΰ��������뤫����ꤹ��ʸ�����, "��������*"�Ȥ��������Ǥ���. + 2 ���ܤο�����"*"�Ͼ�ά��ǽ�Ǥ���. ��3�����ʹߤ��ѿ��ؤΥݥ���, + �����������Ǥ������ѿ��˳�Ǽ�����. �ղð�����Ϳ�����ʤ������� + ���� Qnil�����������. -rb_call_super(VALUE args) +Ruby��åɸƤӽФ� - �����ѡ����饹�Υ�åɤ�ƤӽФ�. args�ϰ����ꥹ�ȤȤʤ�����. args - ��Qnil�λ��ϰ����Τޤް����Ѥ�. + VALUE rb_funcall(VALUE recv, ID mid, int narg, ...) -rb_iterate(VALUE (*func1)(), char *arg1, VALUE (*func2)(), char *arg2) + ��åɸƤӽФ�. ʸ����mid�����뤿��ˤ�rb_intern()��Ȥ�. - func2��֥��å��Ȥ������ꤷ, func1�ƥ졼���Ȥ��ƸƤ�. func1�ˤ� - arg1�������Ȥ����Ϥ���, func2�ˤ���1�����˥��ƥ졼���Ȥ���Ϳ����줿 - ��, ��2������arg2���Ϥ����. - -rb_yield(VALUE val) + rb_call_super(VALUE args) + + �����ѡ����饹�Υ�åɤ�ƤӽФ�. args�ϰ����ꥹ�ȤȤʤ�����. + args ��Qnil�λ��ϸ��ߤΥ�åɤΰ����Τޤް����Ѥ�. + +ʸ���� <-> ID�Ѵ� + + ID rb_intern(char *name) + + ʸ������б�����ID���֤�. + + char *rb_id2name(ID id) + + ID���б�����ʸ������֤�(�ǥХå���). - val���ͤȤ��ƥ��ƥ졼���֥��å���ƤӽФ�. +�������ѿ� -rb_resque(VALUE (*func1)(), char *arg1, VALUE (*func2)(), char *arg2) + VALUE rb_iv_get(VALUE obj, char *name) - �ؿ�func1��arg1������˸ƤӽФ�. func1�μ¹�����㳰��ȯ���������ˤ� - func2��arg2������Ȥ��ƸƤ�. ����ͤ��㳰��ȯ�����ʤ��ä�����func1�� - �����, �㳰��ȯ���������ˤ�func2������ͤǤ���. + obj�Υ������ѿ����ͤ�����. `@'�ǻϤޤ�ʤ��������ѿ��� + Ruby�ץ�����फ�饢�������Ǥ��ʤ�. + + VALUE rb_iv_set(VALUE obj, char *name, VALUE val) + + obj�Υ������ѿ���val�˥��åȤ���. + +���湽¤ + + VALUE rb_iterate(VALUE (*func1)(), char *arg1, VALUE (*func2)(), char *arg2) + + func2��֥��å��Ȥ������ꤷ, func1�ƥ졼���Ȥ��ƸƤ�. func1�� + �� arg1�������Ȥ����Ϥ���, func2�ˤ���1�����˥��ƥ졼���Ȥ���Ϳ���� + �줿��, ��2������arg2���Ϥ����. + + VALUE rb_yield(VALUE val) -rb_ensure(VALUE (*func1)(), char *arg1, VALUE (*func2)(), char *arg2) + val���ͤȤ��ƥ��ƥ졼���֥��å���ƤӽФ�. - �ؿ�func1��arg1������Ȥ��Ƽ¹Ԥ�, �¹Խ�λ��(���Ȥ��㳰��ȯ�����Ƥ�) - func2��arg2������Ȥ��Ƽ¹Ԥ���. ����ͤ�func1������ͤǤ���(�㳰��ȯ - ����������nil). + VALUE rb_resque(VALUE (*func1)(), char *arg1, VALUE (*func2)(), char *arg2) -GC_LINK + �ؿ�func1��arg1������˸ƤӽФ�. func1�μ¹�����㳰��ȯ���������� + �� func2��arg2������Ȥ��ƸƤ�. ����ͤ��㳰��ȯ�����ʤ��ä����� + func1�������, �㳰��ȯ���������ˤ�func2������ͤǤ���. - ���������ѿ���GC�ݸ��Ԥʤ����. + VALUE rb_ensure(VALUE (*func1)(), char *arg1, VALUE (*func2)(), char *arg2) -GC_PRO(var) + �ؿ�func1��arg1������Ȥ��Ƽ¹Ԥ�, �¹Խ�λ��(���Ȥ��㳰��ȯ������ + ��) func2��arg2������Ȥ��Ƽ¹Ԥ���. ����ͤ�func1������ͤǤ���(�� + ����ȯ����������nil). - ���������ѿ���GC�����ݸ��. ���������ѿ����ݸ��Ƥ��ʤ���ǽ���� - ����Ruby���֥������Ȥ�ؤ��Ƥ�����ˤ�GC_PRO()��Ȥä��ݸ��ɬ�פ� - ����. GC_PRO()���ݸ����ѿ���ɬ�����������Ƥ���ɬ�פ�����(̤��� - ���Υ��ߤ����äƤ��GC�������). +�㳰�����顼 -GC_PRO2(var) + void Fail(char *fmt, ...) - GC�ݸ�, var��nil�ǽ�������뤳�Ȱʳ���GC_PRO(var)��Ʊ��. + �㳰��ȯ��������. ������printf()��Ʊ��. -GC_PRO2(var, init) + void Fatal(char *fmt, ...) - GC�ݸ�, var��init�˽�������뤳�Ȱʳ���GC_PRO(var)��Ʊ��. + ��̿Ū�㳰��ȯ��������. �̾���㳰�����ϹԤʤ�줺, �����ץ + ����λ����(������ensure�ǻ��ꤵ�줿�����ɤϽ�λ���˼¹Ԥ����). -GC_UNLINK + void Bug(char *fmt, ...) - GC�ݸλ�����. + �����ץ�ʤɥץ������ΥХ��Ǥ���ȯ������Ϥ��Τʤ������λ� + �Ƥ�. �����ץ�ϥ�������פ�ľ���˽�λ����. �㳰�����ϰ��ڹ� + �ʤ��ʤ�. /* * Local variables: diff --git a/CVS/Entries b/CVS/Entries deleted file mode 100644 index 067e16dd65..0000000000 --- a/CVS/Entries +++ /dev/null @@ -1,51 +0,0 @@ -/autoexec.c/0.15/Wed Jun 1 23:40:54 1994 Thu Mar 17 18:49:43 1994// -/class.c/0.22/Wed Jun 1 23:40:54 1994 Fri Mar 25 13:12:36 1994// -/compar.c/0.15/Wed Jun 1 23:40:54 1994 Thu Mar 17 18:49:43 1994// -/dln.h/0.14/Wed Jun 1 23:40:57 1994 Thu Mar 17 15:55:00 1994// -/error.c/0.15/Wed Jun 1 23:40:57 1994 Thu Mar 17 18:49:43 1994// -/etc.c/0.22/Wed Jun 1 23:40:58 1994 Fri Mar 25 13:12:36 1994// -/ident.h/0.17/Wed Jun 1 23:41:00 1994 Wed May 25 00:56:16 1994// -/inits.c/0.27/Wed Jun 1 23:41:00 1994 Mon Apr 25 23:30:29 1994// -/io.h/0.14/Wed Jun 1 23:41:01 1994 Thu Mar 17 15:55:00 1994// -/methods.c/0.20/Wed Jun 1 23:41:01 1994 Tue Mar 22 16:58:31 1994// -/missing.c/0.29/Wed Jun 1 23:41:01 1994 Wed Jun 1 23:36:26 1994// -/parse.y/0.35/Wed Jun 1 23:41:08 1994 Wed Jun 1 23:36:30 1994// -/random.c/0.15/Wed Jun 1 23:41:09 1994 Thu Mar 17 18:49:43 1994// -/range.c/0.15/Wed Jun 1 23:41:09 1994 Thu Mar 17 18:49:43 1994// -/re.h/0.15/Wed Jun 1 23:41:10 1994 Thu May 26 00:41:30 1994// -/regex.c/0.15/Wed Jun 1 23:41:12 1994 Wed Jun 1 23:36:35 1994// -/regex.h/0.14/Wed Jun 1 23:41:12 1994 Thu Mar 17 15:55:00 1994// -/st.h/0.14/Wed Jun 1 23:41:14 1994 Thu Mar 17 15:55:00 1994// -/variable.c/0.29/Wed Jun 1 23:41:16 1994 Wed May 25 00:56:35 1994// -/version.c/0.27/Wed Jun 1 23:41:16 1994 Mon Apr 25 23:30:35 1994// -/Makefile/0.32/Fri Jun 3 00:15:00 1994 Fri Jun 3 00:15:00 1994// -/Makefile.in/1.3/Fri Jun 3 00:15:01 1994 Fri Jun 3 00:15:01 1994// -/array.c/0.29/Fri Jun 3 00:15:02 1994 Fri Jun 3 00:15:02 1994// -/configure/1.3/Fri Jun 3 00:15:04 1994 Fri Jun 3 00:15:03 1994// -/configure.in/1.3/Fri Jun 3 00:15:04 1994 Fri Jun 3 00:15:04 1994// -/dbm.c/0.28/Fri Jun 3 00:15:05 1994 Fri Jun 3 00:15:05 1994// -/defines.h/1.4/Fri Jun 3 00:15:06 1994 Fri Jun 3 00:15:06 1994// -/dict.c/0.28/Fri Jun 3 00:15:06 1994 Fri Jun 3 00:15:06 1994// -/dir.c/0.18/Fri Jun 3 00:15:07 1994 Fri Jun 3 00:15:07 1994// -/dln.c/0.29/Fri Jun 3 00:15:08 1994 Fri Jun 3 00:15:08 1994// -/enum.c/0.16/Fri Jun 3 00:15:09 1994 Fri Jun 3 00:15:08 1994// -/eval.c/0.35/Fri Jun 3 00:15:10 1994 Fri Jun 3 00:15:09 1994// -/file.c/0.29/Fri Jun 3 00:15:11 1994 Fri Jun 3 00:15:11 1994// -/gc.c/0.30/Fri Jun 3 00:15:12 1994 Fri Jun 3 00:15:12 1994// -/io.c/0.29/Fri Jun 3 00:15:13 1994 Fri Jun 3 00:15:13 1994// -/math.c/0.28/Fri Jun 3 00:15:14 1994 Fri Jun 3 00:15:14 1994// -/node.h/0.32/Fri Jun 3 00:15:15 1994 Fri Jun 3 00:15:14 1994// -/numeric.c/0.19/Fri Jun 3 00:15:15 1994 Fri Jun 3 00:15:15 1994// -/object.c/0.32/Fri Jun 3 00:15:16 1994 Fri Jun 3 00:15:16 1994// -/pack.c/0.18/Fri Jun 3 00:15:17 1994 Fri Jun 3 00:15:17 1994// -/process.c/0.30/Fri Jun 3 00:15:18 1994 Fri Jun 3 00:15:17 1994// -/re.c/0.32/Fri Jun 3 00:15:19 1994 Fri Jun 3 00:15:18 1994// -/ruby.c/0.34/Fri Jun 3 00:15:19 1994 Fri Jun 3 00:15:19 1994// -/ruby.h/0.30/Fri Jun 3 00:15:20 1994 Fri Jun 3 00:15:20 1994// -/socket.c/0.27/Fri Jun 3 00:15:21 1994 Fri Jun 3 00:15:21 1994// -/sprintf.c/0.23/Fri Jun 3 00:15:22 1994 Fri Jun 3 00:15:21 1994// -/st.c/0.15/Fri Jun 3 00:15:22 1994 Fri Jun 3 00:15:22 1994// -/string.c/0.29/Fri Jun 3 00:15:23 1994 Fri Jun 3 00:15:23 1994// -/struct.c/0.26/Fri Jun 3 00:15:25 1994 Fri Jun 3 00:15:24 1994// -/time.c/0.29/Fri Jun 3 00:15:26 1994 Fri Jun 3 00:15:26 1994// -/version.h/1.7/Fri Jun 3 00:15:27 1994 Fri Jun 3 00:15:27 1994// diff --git a/CVS/Repository b/CVS/Repository deleted file mode 100644 index b98482fac9..0000000000 --- a/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -/work/cvsroot/ruby @@ -1,3 +1,110 @@ +Wed Aug 10 15:54:46 1994 Yukihiro Matsumoto (matz@ix-02) + + * variable.c: -v���ץ�����ꤵ��Ƥ�����Ͻ��������Ƥ��ʤ�, + ����ѿ�, �������ѿ�, ���������ѿ��Ȥ���������warning + ��Ф��褦�ˤ���. + +Tue Aug 9 11:50:48 1994 Yukihiro Matsumoto (matz@ix-02) + + * bignum.c: �Ѿ�˴ؤ��Ƥ�¿��Ĺ�黻��Ԥʤ��褦��. �ä���ư������ + �����ϰϤ�ۤ������ν�����Ū�Τ˹Ԥʤ��褦��. + + * eval.c: ��å������Ϲ�ʸ�ڤ���, ��å������ʬ��. ̵�� + �ʺ������������ʤ��褦�ˤ��뤿���2�Ť�free()����ʤ�����. + + * array.c(Fary_aref): ������1�Ĥ�Fixnum�λ�, Range check��Ԥʤ�� + ���褦�˽���. + + * eval.c: �����ο���ѥ�����˷����Ƽ㴳�ι�®��. + +Mon Aug 8 13:06:24 1994 Yukihiro Matsumoto (matz@ix-02) + + * object.c: nil�ˤ�����Ϣ����ʤ�����. + + * parse.y: bit�黻�Ҥ�ͥ���̤���ӱ黻�Ҥ��������. C�Ȥϰ� + �ʤ뤳�Ȥˤʤ뤬, ľ�ѤˤϹ��פ���. + + * gc.c: ���饹����������, �ġ��Υ�å���˥���å���ꥢ�� + ��ΤǤϤʤ�, ���饹ñ�̤ǥ��ꥢ����褦��. + +Thu Aug 4 18:45:09 1994 Yukihiro Matsumoto (matz@ix-02) + + * methods.c(method_free): �������줿��åɤ˴ؤ��ƥ���å���� + �ꥢ���Ƥ���ɬ�פ����ä�. + + * gc.c: Data���饹�Υǡ�����ʬ��free()��˺��Ƥ���. + +Wed Aug 3 09:58:14 1994 Yukihiro Matsumoto (matz@ix-02) + + * parse.y: def func .. end�����ˤ��ؿ���åɤ�����Ϥʤ��ʤä�. + + * methods.c: func�����Υ�åɤ�ʤ�����. ���äƤ�, ���ޤ��̣�� + �ʤ��Τ�. + + * eval.c: $0�ؤ�������ps(1)�ν��Ϥ��Ѳ�����褦��. + + * io.c(Fsyscall): syscall()��¸�. + +Mon Aug 1 13:41:11 1994 Yukihiro Matsumoto (matz@ix-02) + + * parse.y: ���֥륯�����ȤǰϤޤ줿ʸ���������ɽ�����"#{�ѿ�̾}" + �ޤ���"#�ѿ�̾"�Ȥ����������ѿ������Ƥ������ळ�Ȥ��Ǥ���褦 + �ˤʤä�. + + * io.c: �ؿ���å�system2()�Ϥʤ��ʤä�. ���ϥХå��������Ȥ��� + �뤫���. + + * parse.y: `cmd`�ˤ�äƥ��ޥ�ɤ�ʸ�����Ÿ�����뤳�Ȥ��Ǥ���褦 + �ˤʤä�. + + * parse.y: __FILE__, __LINE__���ɲ�. ���줾��ե�����̾(ʸ����), + ���ֹ�(����)���ͤȤ��뵿���ѿ�. + +Fri Jul 29 13:16:07 1994 Yukihiro Matsumoto (matz@ix-02) + + * methods.h: ��åɤ֥������ȤȤ��ư����Τ����. ��å� + �Υ�������ˤϥ�ե��������Ȥ�Ȥ����Ȥˤ���. ����ǥ��� + �������Ȥο������äƤۤ�ξ�������GC��®���ʤ�(����). + + * purify�ˤ�äƥ���ط��ΥХ�������(���Ĥ���,���Ĥ����). + + * gc.c: GC��ץ�����ޤ��ѿ���ޡ��������������, �����å��ȥ쥸�� + ������ޡ���������ˡ���ѹ�. �ܿ�����������褦�ʵ��⤹�뤬, siod + ��scm�Ǥ���Ѥ���Ƥ��뤫��¿ʬ����פ�����. Linux on i486�Ǥ�ư + ����ǧ����. + +Wed Jul 27 16:13:13 1994 Yukihiro Matsumoto (matz@ix-02) + + * eval.c(Eval): �ȥåץ�٥�ǤϹ�¤�ڤ�free���ʤ��褦��. �ɤ����� + ������뤫����֤�̵�̤Ǥ���. + + * array.c, dict.c: "=="��¤���פ��ѹ�. + +Fri Jul 22 10:14:09 1994 Yukihiro Matsumoto (matz@ix-02) + + * error.c: �Ȥ߹��ߥ����פ�̾������Ͽ��˺��Ƥ���. + +Thu Jul 21 14:06:48 1994 Yukihiro Matsumoto (matz@ix-02) + + * parse.y(freenode),eval.c(Eval): �����ڤ������˺��Ƥ���. + +Mon Jul 18 10:19:15 1994 Yukihiro Matsumoto (matz@ix-02) + + * parse.y: ¿���������������롼��˥Х������ä�, 3���ǰʾ��¿�� + �����˼��Ԥ��Ƥ���. + + * eval.c(rb_eval): ¿��������, ���դ�����Ǥʤ����ˤ�`to_a'��� + �ɤ�������Ѵ�������������褦�ˤ���. ���ޤǤλ��ͤ��ȱ����ͤ��� + 1���Ǥˤ��Τޤ���������Ƥ�����, struct�ʤ�������Ѵ��Ǥ����� + ���Ѵ�������������������. + + * dbm.c,dict.c(delete_if): ��å��ɲ�. + + * process.c(wait,waitpid): �����ƥॳ����waitpid�ޤ���wait4������ + ���Ϥ������Ȥ��褦��. configure�⤽��������å�����褦���ѹ�. + + * dbm.c, dict.c(clear): ��å��ɲ�. + Mon Jul 18 10:19:15 1994 Yukihiro Matsumoto (matz@ix-02) * parse.y: ¿���������������롼��˥Х������ä�, 3���ǰʾ��¿�� @@ -34,27 +141,6 @@ Fri Jul 15 10:54:45 1994 Yukihiro Matsumoto (matz@ix-02) Thu Jul 14 11:18:07 1994 Yukihiro Matsumoto (matz@ix-02) - * autoexec.c: ���. autoload�ط��ε�ǽ�Ϻ��帡Ƥ���褦. - - * dict.c: ���饹������̾�Τ�Dict���ѹ�����. ��̾�Ȥ���Hash���� - �դ���. ���ޤ�Dictionary�ʤɤ�Ĺ��̾���ˤ��Ƥ�����ï��ȤäƤ��� - ���ä�����. *BACKWARD INCOMPATIBILITY* - - * parse.y: Dict���������빽ʸ���ɲ�. �������{..}�ˤ���. - - * parse.y: ������������빽ʸ��[..]���ѹ�����. ����Ruby������� - �ȤȤθߴ������ݤƤʤ���, Dict���������빽ʸ��Ƴ�������������, - perl5�˹�碌��(�ռ�����), �ѹ���������Ϻ������ʤ��ȹͤ���. - *BACKWARD INCOMPATIBILITY* - - * eval.c(Feval): eval()�ǥ�åɤ���������, �������륯�饹�� - ��åɤν�°���륯�饹�ˤ���. ���ޤǤ�Object���饹���������� - ����. - - * parse.y: ��������������ʤ�����eval()������Ƥ���. - -Thu Jul 14 11:18:07 1994 Yukihiro Matsumoto (matz@ix-02) - * eval.c: ��åɤ�¸�ߤ��ʤ����ˤ�Kernel:_undefined(id)���ƤФ� ��褦��. ������, ruby�Ǥϸġ��Υ�å���ν�������, ���饹 ñ�̤ν�����ɬ�פʵ��⤹��ʤ�. @@ -511,9 +597,6 @@ Sat May 28 23:08:18 1994 Yukihiro Matsumoto (matz@dyna) Fri May 27 11:42:00 1994 Yukihiro Matsumoto (matz@ix-02) - * ����ɽ����ʸ�������ɤΥǥե���Ȥ�������б��ˤ���. ����ˤ�ä� - �㴳�ι�®�����ޤ��. - * tr����ʸ�����(delete), ʸ������(squeeze)��ʬΥ����. ����ˤȤ� �ʤ�tr�Υ��ץ��������Ϥʤ��ʤä�. @@ -1,202 +1,6 @@ -# Generated automatically from Makefile.in by configure. -# Main Makefile for GNU m4. -# Copyright (C) 1992 Free Software Foundation, Inc. +# +# Makefile - +# +# created at: Wed Aug 10 15:21:29 JST 1994 -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -SHELL = /bin/sh - -#### Start of system configuration section. #### - -srcdir = . -VPATH = . - -CC = gcc -traditional -DBM = -fpcc-struct-return -YACC = bison -y -INSTALL = /usr/bin/install -c -INSTALL_PROGRAM = $(INSTALL) -INSTALL_DATA = $(INSTALL) -m 644 -MAKEINFO = makeinfo - -CFLAGS = -g -LDFLAGS = -static $(CFLAGS) -LIBS = -lm -ldbm -DEFS = -DHAVE_UNISTD_H=1 -DHAVE_SYSCALL_H=1 -DHAVE_A_OUT_H=1 -DDIRENT=1 -DGETGROUPS_T=int -DRETSIGTYPE=void -DHAVE_STRTOL=1 -DHAVE_STRDUP=1 -DHAVE_KILLPG=1 -DHAVE_MKDIR=1 -DHAVE_STRFTIME=1 -DHAVE_PUTENV=1 -DHAVE_ALLOCA_H=1 -DPW_AGE=1 -DPW_COMMENT=1 - -prefix = /usr/local -binprefix = -exec_prefix = $(prefix) -bindir = $(exec_prefix)/bin -infodir = $(prefix)/info - -#### End of system configuration section. #### - -.c.o: - $(CC) -c $(CFLAGS) $(CPPFLAGS) $(DEFS) -I$(srcdir) -I$(srcdir)/lib $< - -HDRS = defines.h \ - dln.h \ - ident.h \ - io.h \ - node.h \ - re.h \ - regex.h \ - ruby.h \ - st.h \ - version.h - -SRCS = array.c \ - autoexec.c \ - class.c \ - compar.c \ - dbm.c \ - dict.c \ - dir.c \ - dln.c \ - enum.c \ - error.c \ - etc.c \ - eval.c \ - file.c \ - gc.c \ - inits.c \ - io.c \ - math.c \ - methods.c \ - missing.c \ - numeric.c \ - object.c \ - pack.c \ - parse.y \ - process.c \ - random.c \ - range.c \ - re.c \ - regex.c \ - ruby.c \ - socket.c \ - sprintf.c \ - st.c \ - string.c \ - struct.c \ - time.c \ - variable.c \ - version.c - -OBJS = array.o \ - autoexec.o \ - class.o \ - compar.o \ - dbm.o \ - dict.o \ - dir.o \ - dln.o \ - enum.o \ - error.o \ - etc.o \ - eval.o \ - file.o \ - gc.o \ - inits.o \ - io.o \ - math.o \ - methods.o \ - missing.o \ - numeric.o \ - object.o \ - pack.o \ - parse.o \ - process.o \ - random.o \ - range.o \ - re.o \ - regex.o \ - ruby.o \ - socket.o \ - sprintf.o \ - st.o \ - string.o \ - struct.o \ - time.o \ - variable.o \ - version.o - -DISTFILES = README NEWS TODO THANKS COPYING INSTALL \ -ChangeLog Makefile.in configure.in \ -$(HDRS) $(SRCS) configure - -PROGRAM = ruby - -all: $(PROGRAM) - -$(PROGRAM): $(OBJS) - @echo -n "Loading $(PROGRAM) ... " - @rm -f $(PROGRAM) - @$(CC) $(LDFLAGS) $(OBJS) $(LIBS) -o $(PROGRAM) - @echo "done" - -install: $(PROGMAM) - $(INSTALL_PROGRAM) $(PROGRAM) $(bindir)/$(PROGRAM) - -clean:; @rm -f $(OBJS) - -realclean:; @rm -f $(OBJS) - @rm -f core ruby *~ - -dbm.o:dbm.c - $(CC) -c $(DBM) $(CFLAGS) $(CPPFLAGS) $(DEFS) -I$(srcdir) -I$(srcdir)/lib dbm.c - -# Prevent GNU make v3 from overflowing arg limit on SysV. -.NOEXPORT: -### -array.o : array.c ruby.h defines.h -autoexec.o : autoexec.c ruby.h defines.h -class.o : class.c ruby.h defines.h node.h st.h -compar.o : compar.c ruby.h defines.h -dbm.o : dbm.c ruby.h defines.h -dict.o : dict.c ruby.h defines.h st.h -dir.o : dir.c ruby.h defines.h -dln.o : dln.c defines.h dln.h -enum.o : enum.c ruby.h defines.h -error.o : error.c ruby.h defines.h -etc.o : etc.c ruby.h defines.h -eval.o : eval.c ruby.h defines.h node.h ident.h st.h -file.o : file.c ruby.h defines.h io.h -gc.o : gc.c ruby.h defines.h st.h -inits.o : inits.c -io.o : io.c ruby.h defines.h io.h -math.o : math.c ruby.h defines.h -methods.o : methods.c ruby.h defines.h node.h -missing.o : missing.c ruby.h defines.h missing/memmove.c missing/strerror.c \ - missing/strtoul.c missing/strftime.c missing/getopt.h missing/getopt.c missing/getopt1.c -numeric.o : numeric.c ruby.h defines.h -object.o : object.c ruby.h defines.h -pack.o : pack.c ruby.h defines.h -process.o : process.c ruby.h defines.h st.h -random.o : random.c ruby.h defines.h -range.o : range.c ruby.h defines.h -re.o : re.c ruby.h defines.h re.h regex.h -regex.o : regex.c regex.h -ruby.o : ruby.c ruby.h defines.h re.h regex.h missing/getopt.h -socket.o : socket.c ruby.h defines.h io.h -sprintf.o : sprintf.c ruby.h defines.h -st.o : st.c st.h -string.o : string.c ruby.h defines.h re.h regex.h -struct.o : struct.c ruby.h defines.h -time.o : time.c ruby.h defines.h -variable.o : variable.c ruby.h defines.h st.h ident.h -version.o : version.c ruby.h defines.h \ - version.h +all:; @echo "You must run configure first." diff --git a/Makefile.in b/Makefile.in index 33338c9e61..66b3689260 100644 --- a/Makefile.in +++ b/Makefile.in @@ -125,10 +125,8 @@ PROGRAM = ruby all: $(PROGRAM) $(PROGRAM): $(OBJS) - @echo -n "Loading $(PROGRAM) ... " @rm -f $(PROGRAM) - @$(CC) $(LDFLAGS) $(OBJS) $(LIBS) -o $(PROGRAM) - @echo "done" + $(CC) $(LDFLAGS) $(OBJS) $(LIBS) -o $(PROGRAM) install: $(PROGMAM) $(INSTALL_PROGRAM) $(PROGRAM) $(bindir)/$(PROGRAM) @@ -148,7 +146,7 @@ parse.o : parse.y ruby.h defines.h env.h ident.h node.h st.h regex.h ### array.o : array.c ruby.h defines.h bignum.o : bignum.c ruby.h defines.h -class.o : class.c ruby.h defines.h env.h node.h st.h +class.o : class.c ruby.h defines.h env.h node.h st.h methods.h compar.o : compar.c ruby.h defines.h dbm.o : dbm.c ruby.h defines.h dict.o : dict.c ruby.h defines.h st.h @@ -160,10 +158,10 @@ etc.o : etc.c ruby.h defines.h eval.o : eval.c ruby.h defines.h env.h node.h ident.h st.h file.o : file.c ruby.h defines.h io.h gc.o : gc.c ruby.h defines.h env.h st.h -inits.o : inits.c +inits.o : inits.c ruby.h defines.h io.o : io.c ruby.h defines.h io.h math.o : math.c ruby.h defines.h -methods.o : methods.c ruby.h defines.h env.h node.h +methods.o : methods.c ruby.h defines.h ident.h env.h node.h methods.h missing.o : missing.c ruby.h defines.h missing/memmove.c missing/strerror.c \ missing/strtoul.c missing/strftime.c missing/strstr.c missing/getopt.h missing/getopt.c \ missing/getopt1.c missing/mkdir.c diff --git a/README b/README new file mode 100644 index 0000000000..3ca523bdde --- /dev/null +++ b/README @@ -0,0 +1,51 @@ +.\" README - -*- Text -*- created at: Wed Aug 3 11:57:36 JST 1994 + +����ѥ��롦���ȡ��� + + 1. configure��¹Ԥ���Makefile����������. + 2. (ɬ�פʤ��)defines.h���Խ�����. + 3. make��¹Ԥ��ƥ���ѥ��뤹�� + 4. make install + + �⤷, ����ѥ�����˥��顼��ȯ���������ˤϥ��顼�Υ����ȥ� + ����, OS�μ����ޤ�Ǥ�������ܤ�����ݡ��Ȥ��Ԥ����äƤ� + ����������. + +��ǽ�ɲ� + + C�����ɤ���Ȥˤ�ä�, ��ñ��ruby�˵�ǽ���ɲäǤ���. + ���Τ����ޤ��ʼ��ϰʲ����̤�Ǥ���. + + * �ؿ�Ū��åɤ��ɲä����� + + (1) C�Ǵؿ���� + (2) rb_define_method()�ǥ����ͥ륯�饹�Υ�åɤȤ��ƴ� + ����ruby����Ͽ����ؿ���� + (3) init.c���Խ�����, ��Ͽ����ؿ���ƤӽФ� + + * ���饹���ɲä����� + + (1) ���饹���߷פ��� + (2) ��åɤ�C�ǵ��Ҥ��� + (3) rb_define_class()�ǥ��饹���������륳���ɤ�� + (4) rb_define_method()�ǥ�åɤ���Ͽ���륳���ɤ�� + (5) init.c���Խ�����, ���������ؿ���ƤӽФ� + + �ܤ�����C-IF��. + +�ܿ� + + UNIX�Ǥ����configure���ۤȤ�ɤκ��ۤ�ۼ����Ƥ����Ϥ� + ����, �פ�̸���Ȥ������ä����(����˰㤤�ʤ�), ��Ԥ˥� + �ݡ��Ȥ����, ���Ǥ��뤫���Τ�ʤ�. + + �������ƥ�����ˤ�äȤ��¸����Τ�GC���Ǥ���. ruby��GC�� + �оݤΥ������ƥ����㤬setjmp()�ˤ�ä�, ���ƤΥ쥸������ + jmp_buf�˳�Ǽ���뤳�Ȥ�, jmp_buf�ȥ����å���32bit���饤�� + ���Ȥ���Ƥ��뤳�Ȥ��ꤷ�Ƥ���. ���Ԥ����¤Ǥʤ����� + �ܿ��Ϻ����ˤ�������. ��Ԥϳ�ȴ�ñ�˲��Ǥ���. gc.c + �Υ����å���ޡ���������ʬ�˥��饤����ȤΥХ��ȿ������� + �餷�ƥޡ������륳���ɤ��ɲä�������ǺѤ�. + + sparc�ʳ��Υ쥸����������ɥ������CPU�Ǥ�, �쥸���������� + �ɥ���ե�å��夹�륳���ɤ��ɲä���ɬ�פ����뤫���Τ�ʤ�. @@ -1,6 +1,4 @@ -* $0�ؤ�������ps�ν��Ϥ��Ѳ�������褦�� * ruby����������ѿ�hook�μ¸� -* FUNC�����Υ�åɤ�������ɬ�פ� * write debugger for ruby * re-write regex code for speeding * byte code interpretor @@ -24,12 +24,9 @@ ary_new2(len) NEWOBJ(ary, struct RArray); OBJSETUP(ary, C_Array, T_ARRAY); - GC_LINK; - GC_PRO(ary); ary->len = 0; ary->capa = len; ary->ptr = ALLOC_N(VALUE, len); - GC_UNLINK; return (VALUE)ary; } @@ -73,12 +70,9 @@ ary_new4(n, elts) { struct RArray* ary; - GC_LINK; - GC_PRO4(elts, n); ary = (struct RArray*)ary_new2(n); memcpy(ary->ptr, elts, sizeof(VALUE)*n); ary->len = n; - GC_UNLINK; return (VALUE)ary; } @@ -89,13 +83,10 @@ assoc_new(elm1, elm2) { struct RArray *ary; - GC_LINK; - GC_PRO(elm1); GC_PRO(elm2); ary = (struct RArray*)ary_new2(2); ary->ptr[0] = elm1; ary->ptr[1] = elm2; ary->len = 2; - GC_UNLINK; return (VALUE)ary; } @@ -107,12 +98,9 @@ Fary_new(class) NEWOBJ(ary, struct RArray); OBJSETUP(ary, class, T_ARRAY); - GC_LINK; - GC_PRO(ary); ary->len = 0; ary->capa = ARY_DEFAULT_SIZE; ary->ptr = ALLOC_N(VALUE, ARY_DEFAULT_SIZE); - GC_UNLINK; return (VALUE)ary; } @@ -131,10 +119,8 @@ astore(ary, idx, val) max = idx + 1; if (idx >= ary->capa) { - GC_LINK; GC_PRO(val); ary->capa = max; REALLOC_N(ary->ptr, VALUE, max); - GC_UNLINK; } if (idx >= ary->len) { bzero(ary->ptr+ary->len, sizeof(VALUE)*(max-ary->len)); @@ -302,6 +288,11 @@ Fary_aref(ary, args) return ary_subseq(ary, beg, len); } + /* special case - speeding up */ + if (FIXNUM_P(arg1)) { + return ary_entry(ary, NUM2INT(arg1)); + } + /* check if idx is Range */ if (obj_is_kind_of(arg1, C_Range)) { int beg, len; @@ -462,10 +453,6 @@ ary_join(ary, sep) else result = obj_as_string(ary->ptr[0]); - GC_LINK; - GC_PRO(result); - GC_PRO2(tmp); - for (i=1; i<ary->len; i++) { int need_free = 1; tmp = ary->ptr[i]; @@ -484,8 +471,6 @@ ary_join(ary, sep) if (need_free == 1) obj_free(tmp); } - GC_UNLINK; - return result; } @@ -523,15 +508,13 @@ Fary_inspect(ary) char *p; ary = (struct RArray*)Fary_clone(ary); - GC_LINK; - GC_PRO(ary); len = ary->len; for (i=0; i<len; i++) { ary->ptr[i] = rb_funcall(ary->ptr[i], rb_intern("_inspect"), 0, Qnil); } - GC_PRO3(str, str_new2(", ")); + str = str_new2(", "); str = ary_join(ary, str); if (str == Qnil) return str_new2("[]"); len = RSTRING(str)->len; @@ -541,8 +524,6 @@ Fary_inspect(ary) p[0] = '['; p[len+1] = ']'; - GC_UNLINK; - return str; } @@ -699,10 +680,8 @@ Fary_plus(x, y) break; default: - GC_LINK; - GC_PRO3(z, (struct RArray*)Fary_clone(x)); + z = (struct RArray*)Fary_clone(x); Fary_push(z, y); - GC_UNLINK; break; } return (VALUE)z; @@ -761,6 +740,21 @@ Fary_rassoc(ary, value) return Qnil; } +static VALUE +Fary_equal(ary1, ary2) + struct RArray *ary1, *ary2; +{ + int i; + + if (TYPE(ary2) != T_ARRAY) return FALSE; + if (ary1->len != ary2->len) return FALSE; + for (i=0; i<ary1->len; i++) { + if (!rb_funcall(ary1->ptr[i], eq, 1, ary2->ptr[i])) + return FALSE; + } + return TRUE; +} + extern VALUE C_Kernel; extern VALUE M_Enumerable; @@ -774,6 +768,7 @@ Init_Array() rb_define_method(C_Array, "_inspect", Fary_inspect, 0); rb_define_method(C_Array, "to_a", Fary_to_a, 0); + rb_define_method(C_Array, "==", Fary_equal, 1); rb_define_method(C_Array, "[]", Fary_aref, -2); rb_define_method(C_Array, "[]=", Fary_aset, -2); rb_define_method(C_Array, "<<", Fary_append, 1); @@ -10,6 +10,7 @@ #include "ruby.h" #include <ctype.h> +#include <math.h> extern VALUE C_Integer; VALUE C_Bignum; @@ -87,7 +88,10 @@ bignorm(x) while (len-- && !ds[len]) ; x->len = ++len; - if (len*sizeof(USHORT) <= sizeof(VALUE)) { + + if (len*sizeof(USHORT) < sizeof(VALUE) || + (len*sizeof(USHORT) == sizeof(VALUE) && + ds[sizeof(VALUE)/sizeof(USHORT)-1] <= 0x3fff)) { long num = 0; while (len--) { num = BIGUP(num) + ds[len]; @@ -282,10 +286,9 @@ big2str(x, base) Fail("bignum cannot treat base %d", base); } - GC_LINK; - GC_PRO3(t, Fbig_clone(x)); + t = Fbig_clone(x); ds = BDIGITS(t); - GC_PRO3(ss, str_new(0, j)); + ss = str_new(0, j); s = RSTRING(ss)->ptr; s[0] = x->sign ? '+' : '-'; @@ -310,7 +313,7 @@ big2str(x, base) RSTRING(ss)->len -= x->sign?j:j-1; memmove(x->sign?s:s+1, s+j, RSTRING(ss)->len); s[RSTRING(ss)->len] = '\0'; - GC_UNLINK; + return ss; } @@ -363,20 +366,19 @@ dbl2big(d) VALUE z; double u = (d < 0)?-d:d; - while (0 != floor(u)) { + while (0 != (long)u) { u /= BIGRAD; i++; } - GC_LINK; - GC_PRO3(z, bignew(i, d>=0)); + z = bignew(i, d>=0); digits = BDIGITS(z); while (i--) { u *= BIGRAD; - c = floor(u); + c = (long)u; u -= c; digits[i] = c; } - GC_UNLINK; + return bignorm(z); } @@ -430,8 +432,6 @@ bigadd(x, y, sign) i = y->len; while (i--) zds[i] = BDIGITS(y)[i]; - GC_LINK; - GC_PRO(z); i = 0; num = 0; if (x->sign == z->sign) { do { @@ -481,7 +481,7 @@ bigadd(x, y, sign) } } } - GC_UNLINK; + return bignorm(z); } @@ -491,14 +491,12 @@ Fbig_plus(x, y) { VALUE z; - GC_LINK; - GC_PRO(y); if (FIXNUM_P(y)) y = int2big(FIX2INT(y)); else { Check_Type(x, T_BIGNUM); } z = bigadd(x, y, 1); - GC_UNLINK; + return z; } @@ -506,14 +504,11 @@ VALUE Fbig_minus(x, y) VALUE x, y; { - GC_LINK; - GC_PRO(y); if (FIXNUM_P(y)) y = int2big(FIX2INT(y)); else { Check_Type(y, T_BIGNUM); } x = bigadd(x, y, 0); - GC_UNLINK; return x; } @@ -527,8 +522,7 @@ Fbig_mul(x, y) VALUE z; USHORT *zds; - GC_LINK; - GC_PRO(y); + if (FIXNUM_P(x)) x = (struct RBignum*)int2big(FIX2INT(x)); if (FIXNUM_P(y)) y = (struct RBignum*)int2big(FIX2INT(y)); else { Check_Type(y, T_BIGNUM); @@ -552,7 +546,6 @@ Fbig_mul(x, y) } } } while (++i < x->len); - GC_UNLINK; return bignorm(z); } @@ -579,8 +572,7 @@ bigdivmod(x, y, div, mod) xds = BDIGITS(x); if (ny == 1) { dd = yds[0]; - GC_LINK; - GC_PRO3(z, Fbig_clone(x)); + z = Fbig_clone(x); zds = BDIGITS(z); t2 = 0; i = nx; while(i--) { @@ -593,16 +585,14 @@ bigdivmod(x, y, div, mod) if (!y->sign) t2 = -t2; *mod = FIX2INT(t2); } - GC_UNLINK; return; } - GC_LINK; - GC_PRO3(z, bignew(nx==ny?nx+2:nx+1, x->sign==y->sign)); + z = bignew(nx==ny?nx+2:nx+1, x->sign==y->sign); zds = BDIGITS(z); if (nx==ny) zds[nx+1] = 0; while (!yds[ny-1]) ny--; if ((dd = BIGRAD/(yds[ny-1]+1)) != 1) { - GC_PRO3(y, (struct RBignum*)Fbig_clone(y)); + y = (struct RBignum*)Fbig_clone(y); tds = BDIGITS(y); j = 0; num = 0; @@ -681,7 +671,6 @@ bigdivmod(x, y, div, mod) RBIGNUM(*mod)->sign = y->sign; *mod = bignorm(*mod); } - GC_UNLINK; } static VALUE @@ -690,14 +679,12 @@ Fbig_div(x, y) { VALUE z; - GC_LINK; - GC_PRO(y); if (FIXNUM_P(y)) y = int2big(FIX2INT(y)); else { Check_Type(y, T_BIGNUM); } bigdivmod(x, y, &z, Qnil); - GC_UNLINK; + return z; } @@ -707,14 +694,12 @@ Fbig_mod(x, y) { VALUE z; - GC_LINK; - GC_PRO(y); if (FIXNUM_P(y)) y = int2big(FIX2INT(y)); else { Check_Type(y, T_BIGNUM); } bigdivmod(x, y, Qnil, &z); - GC_UNLINK; + return z; } @@ -724,38 +709,41 @@ Fbig_divmod(x, y) { VALUE div, mod; - GC_LINK; - GC_PRO(y); if (FIXNUM_P(y)) y = int2big(FIX2INT(y)); else { Check_Type(y, T_BIGNUM); } bigdivmod(x, y, &div, &mod); - GC_UNLINK; return assoc_new(div, mod);; } -static VALUE +VALUE Fbig_pow(x, y) VALUE x, y; { - extern double pow(); double d1, d2; + VALUE z; + int n; - GC_LINK; - GC_PRO(y); - if (FIXNUM_P(y)) y = int2big(FIX2INT(y)); - else { - Check_Type(y, T_BIGNUM); + if (TYPE(y) == T_FLOAT) { + return float_new(pow(big2dbl(x), RFLOAT(y)->value)); + } + n = NUM2INT(y); + if (n == 0) return INT2FIX(1); + if (n < 0) { + return float_new(pow(big2dbl(x), (double)n)); } - d1 = big2dbl(x); - d2 = big2dbl(y); - d1 = pow(d1, d2); - GC_UNLINK; - - return dbl2big(d1); + z = x; + while (--n) { + while (!(n % 2)) { + n = n /2; + x = Fbig_mul(x, x); + } + z = Fbig_mul(z, x); + } + return z; } VALUE @@ -774,14 +762,12 @@ Fbig_and(x, y) Check_Type(y, T_BIGNUM); } - GC_LINK; - GC_PRO(y); if (!y->sign) { y = (struct RBignum*)Fbig_clone(y); big_2comp(y); } if (!x->sign) { - GC_PRO3(x, (struct RBignum*)Fbig_clone(x)); + x = (struct RBignum*)Fbig_clone(x); big_2comp(x); } if (x->len > y->len) { @@ -808,7 +794,6 @@ Fbig_and(x, y) zds[i] = sign?0:ds2[i]; } if (!RBIGNUM(z)->sign) big_2comp(z); - GC_UNLINK; return bignorm(z); } @@ -828,14 +813,12 @@ Fbig_or(x, y) Check_Type(y, T_BIGNUM); } - GC_LINK; - GC_PRO(y); if (!y->sign) { y = (struct RBignum*)Fbig_clone(y); big_2comp(y); } if (!x->sign) { - GC_PRO3(x, (struct RBignum*)Fbig_clone(x)); + x = (struct RBignum*)Fbig_clone(x); big_2comp(x); } if (x->len > y->len) { @@ -862,7 +845,7 @@ Fbig_or(x, y) zds[i] = sign?ds2[i]:(BIGRAD-1); } if (!RBIGNUM(z)->sign) big_2comp(z); - GC_UNLINK; + return bignorm(z); } @@ -882,14 +865,12 @@ Fbig_xor(x, y) Check_Type(y, T_BIGNUM); } - GC_LINK; - GC_PRO(y); if (!y->sign) { y = (struct RBignum*)Fbig_clone(y); big_2comp(y); } if (!x->sign) { - GC_PRO3(x, (struct RBignum*)Fbig_clone(x)); + x = (struct RBignum*)Fbig_clone(x); big_2comp(x); } if (x->len > y->len) { @@ -918,7 +899,7 @@ Fbig_xor(x, y) zds[i] = sign?ds2[i]:~ds2[i]; } if (!RBIGNUM(z)->sign) big_2comp(z); - GC_UNLINK; + return bignorm(z); } diff --git a/bring b/bring deleted file mode 100644 index 771cd04542..0000000000 --- a/bring +++ /dev/null @@ -1,57 +0,0 @@ -#! /usr/bin/bash - -function fdeject() { - if type eject > /dev/null 2>&1; then - eject - fi -} - -function copyfiles() { - for d in . missing sample; do - if [ ! -d $1/$d ];then mkdir $1/$d; fi - for i in $d/*;do - case $i in - */ruby|*.o|*~|*.sav|*.bak|*.orig|*/core|"#"*);; - */Change*|*/config.status|*/Makefile);; - *) - if [ -f $i ]; then - if [ $i -nt $1/$i -o ! -f $1/$i ];then - echo copying $i - cp -p $i $1/$i - fi - fi;; - esac - done - done -} - -if [ ! -d exchange ]; then mkdir exchange; fi - -if [ "$1" = "in" ]; then - - cd exchange - - mread ruby.tgz ruby.tgz - fdeject - tar zxf ruby.tgz - rm -f ruby.tgz - cd ruby - - cp ChangeLog ../../Changes - copyfiles ../.. - -else -# bring out - if [ ! -d exchange/ruby ]; then mkdir exchange/ruby; fi - - cp -p ChangeLog exchange/ruby - copyfiles exchange/ruby - - cd exchange - (cd ruby; make realclean) - - tar zcf ruby.tgz ruby - mwrite ruby.tgz ruby.tgz - fdeject - rm -f ruby.tgz -fi @@ -14,12 +14,12 @@ #include "env.h" #include "node.h" #include "st.h" +#include "methods.h" struct st_table *new_idhash(); extern VALUE C_Class; extern VALUE C_Module; -extern VALUE C_Method; VALUE class_new(super) @@ -140,6 +140,7 @@ rb_include_module(class, module) struct RClass *class, *module; { struct RClass *p; + int added = FALSE; Check_Type(module, T_MODULE); @@ -151,41 +152,43 @@ rb_include_module(class, module) } class->super = include_class_new(module, class->super); + added = TRUE; class = class->super; ignore_module: module = module->super; } - rb_clear_cache2(class); + if (added) { + rb_clear_cache2(class); + } } void -rb_add_method(class, mid, node, scope) +rb_add_method(class, mid, node, undef) struct RClass *class; ID mid; NODE *node; - enum mth_scope scope; + int undef; { - struct RMethod *body; - NEWOBJ(mth, struct RMethod); - OBJSETUP(mth, C_Method, T_METHOD); + struct SMethod *body; if (class == Qnil) class = (struct RClass*)C_Object; if (st_lookup(class->m_tbl, mid, &body)) { if (verbose) { Warning("redefine %s", rb_id2name(mid)); } - unliteralize(body); rb_clear_cache(body); + method_free(body); } - mth->node = node; + body = ALLOC(struct SMethod); + body->node = node; if (BUILTIN_TYPE(class) == T_MODULE) - mth->origin = Qnil; + body->origin = Qnil; else - mth->origin = class; - mth->id = mid; - mth->scope = scope; - literalize(mth); - st_insert(class->m_tbl, mid, mth); + body->origin = class; + body->id = mid; + body->undef = undef; + body->count = 1; + st_insert(class->m_tbl, mid, body); } void @@ -197,19 +200,7 @@ rb_define_method(class, name, func, argc) { NODE *temp = NEW_CFUNC(func, argc); - rb_add_method(class, rb_intern(name), temp, MTH_METHOD); -} - -void -rb_define_func(class, name, func, argc) - struct RClass *class; - char *name; - VALUE (*func)(); - int argc; -{ - NODE *temp = NEW_CFUNC(func, argc); - - rb_add_method(class, rb_intern(name), temp, MTH_FUNC); + rb_add_method(class, rb_intern(name), temp, FALSE); } void @@ -217,7 +208,7 @@ rb_undef_method(class, name) struct RClass *class; char *name; { - rb_add_method(class, rb_intern(name), Qnil, MTH_UNDEF); + rb_add_method(class, rb_intern(name), Qnil, TRUE); } VALUE @@ -248,7 +239,7 @@ rb_define_single_method(obj, name, func, argc) VALUE (*func)(); int argc; { - rb_define_method(rb_single_class(obj), name, func, argc, MTH_METHOD); + rb_define_method(rb_single_class(obj), name, func, argc, FALSE); } void @@ -258,7 +249,7 @@ rb_define_mfunc(class, name, func, argc) VALUE (*func)(); int argc; { - rb_define_func(class, name, func, argc); + rb_define_method(class, name, func, argc); rb_define_single_method(class, name, func, argc); } @@ -285,11 +276,11 @@ rb_define_attr(class, name, pub) attreq = rb_intern(buf); sprintf(buf, "@%s", name); attriv = rb_intern(buf); - if (rb_get_method_body(class, attr, 0, MTH_METHOD) == Qnil) { - rb_add_method(class, attr, NEW_IVAR(attriv), MTH_METHOD); + if (rb_get_method_body(class, attr, 0) == Qnil) { + rb_add_method(class, attr, NEW_IVAR(attriv), TRUE); } - if (pub && rb_get_method_body(class, attreq, 0, MTH_METHOD) == Qnil) { - rb_add_method(class, attreq, NEW_ATTRSET(attriv), MTH_METHOD); + if (pub && rb_get_method_body(class, attreq, 0) == Qnil) { + rb_add_method(class, attreq, NEW_ATTRSET(attriv), TRUE); } } diff --git a/config.status b/config.status deleted file mode 100755 index 7bdc7b26ed..0000000000 --- a/config.status +++ /dev/null @@ -1,72 +0,0 @@ -#!/bin/sh -# Generated automatically by configure. -# Run this file to recreate the current configuration. -# This directory was configured as follows, -# on host dyna: -# -# ./configure - -for arg -do - case "$arg" in - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - echo running ${CONFIG_SHELL-/bin/sh} ./configure - exec ${CONFIG_SHELL-/bin/sh} ./configure ;; - *) echo "Usage: config.status --recheck" 2>&1; exit 1 ;; - esac -done - -trap 'rm -f Makefile; exit 1' 1 3 15 -PROGS='ruby' -CC='gcc' -CPP='gcc -E' -DBM='-fpcc-struct-return' -STATIC='' -YACC='bison -y' -INSTALL='/usr/bin/install -c' -INSTALL_PROGRAM='$(INSTALL)' -INSTALL_DATA='$(INSTALL) -m 644' -ALLOCA='' -LIBS=' -lm -ldbm' -srcdir='.' -DEFS=' -DHAVE_UNISTD_H=1 -DHAVE_SYSCALL_H=1 -DHAVE_A_OUT_H=1 -DDIRENT=1 -DGETGROUPS_T=gid_t -DRETSIGTYPE=void -DHAVE_GETOPT_LONG=1 -DHAVE_MEMMOVE=1 -DHAVE_STRERROR=1 -DHAVE_STRTOL=1 -DHAVE_STRTOUL=1 -DHAVE_STRDUP=1 -DHAVE_SETENV=1 -DHAVE_KILLPG=1 -DHAVE_MKDIR=1 -DHAVE_STRFTIME=1 -DHAVE_ALLOCA_H=1' -prefix='' -exec_prefix='' -prsub='' -extrasub='' - -top_srcdir=$srcdir - -CONFIG_FILES=${CONFIG_FILES-"Makefile"} -for file in .. ${CONFIG_FILES}; do if test "x$file" != x..; then - srcdir=$top_srcdir - # Remove last slash and all that follows it. Not all systems have dirname. - dir=`echo $file|sed 's%/[^/][^/]*$%%'` - if test "$dir" != "$file"; then - test "$top_srcdir" != . && srcdir=$top_srcdir/$dir - test ! -d $dir && mkdir $dir - fi - echo creating $file - rm -f $file - echo "# Generated automatically from `echo $file|sed 's|.*/||'`.in by configure." > $file - sed -e " -$prsub -$extrasub -s%@PROGS@%$PROGS%g -s%@CC@%$CC%g -s%@CPP@%$CPP%g -s%@DBM@%$DBM%g -s%@STATIC@%$STATIC%g -s%@YACC@%$YACC%g -s%@INSTALL@%$INSTALL%g -s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g -s%@INSTALL_DATA@%$INSTALL_DATA%g -s%@ALLOCA@%$ALLOCA%g -s%@LIBS@%$LIBS%g -s%@srcdir@%$srcdir%g -s%@DEFS@%$DEFS% -" $top_srcdir/${file}.in >> $file -fi; done - - -exit 0 diff --git a/configure.in b/configure.in index 0acb17eae5..041018e0d2 100644 --- a/configure.in +++ b/configure.in @@ -27,7 +27,7 @@ AC_GETGROUPS_T AC_RETSIGTYPE AC_HAVE_FUNCS(getopt_long memmove strerror strtoul strdup strstr) AC_HAVE_FUNCS(setenv fmod killpg mkdir strftime socket random) -AC_HAVE_FUNCS(wait4 waitpid) +AC_HAVE_FUNCS(wait4 waitpid syscall) if echo $DEFS | grep "HAVE_SETENV" 2>&1 > /dev/null; then : else @@ -38,7 +38,7 @@ if echo $DEFS | grep "HAVE_STRFTIME" 2>&1 > /dev/null; then else AC_TIMEZONE AC_COMPILE_CHECK([daylight], [], - [extern int daylight; daylight;], AC_DEFINE(HAVE_DAYLIGHT)) + [extern int daylight; int i; i = daylight;], AC_DEFINE(HAVE_DAYLIGHT)) fi AC_ALLOCA AC_WORDS_BIGENDIAN @@ -81,10 +81,8 @@ Fdbm_open(class, args) rb_sys_fail(RSTRING(file)->ptr); } - GC_LINK; - GC_PRO3(obj, obj_alloc(class)); + obj = obj_alloc(class); MakeDBM(obj, dbm); - GC_UNLINK; return obj; } @@ -149,8 +147,6 @@ Fdbm_delete_if(obj) VALUE keystr, valstr; GetDBM(obj, dbm); - GC_LINK; - GC_PRO2(keystr); GC_PRO2(valstr); for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) { val = dbm_fetch(dbm, key); keystr = str_new(key.dptr, key.dsize); @@ -160,7 +156,6 @@ Fdbm_delete_if(obj) Fail("DBM delete failed"); } } - GC_UNLINK; return obj; } @@ -261,8 +256,6 @@ Fdbm_each_pair(obj) VALUE keystr, valstr; GetDBM(obj, dbm); - GC_LINK; - GC_PRO2(keystr); GC_PRO2(valstr); for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) { val = dbm_fetch(dbm, key); @@ -270,7 +263,6 @@ Fdbm_each_pair(obj) valstr = str_new(val.dptr, val.dsize); rb_yield(assoc_new(keystr, valstr)); } - GC_UNLINK; return obj; } @@ -283,13 +275,12 @@ Fdbm_keys(obj) DBM *dbm; VALUE ary; - GC_LINK; - GC_PRO3(ary, ary_new()); + ary = ary_new(); GetDBM(obj, dbm); for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) { Fary_push(ary, str_new(key.dptr, key.dsize)); } - GC_UNLINK; + return ary; } @@ -301,14 +292,13 @@ Fdbm_values(obj) DBM *dbm; VALUE ary; - GC_LINK; - GC_PRO3(ary, ary_new()); + ary = ary_new(); GetDBM(obj, dbm); for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) { val = dbm_fetch(dbm, key); Fary_push(ary, str_new(val.dptr, val.dsize)); } - GC_UNLINK; + return ary; } @@ -360,16 +350,13 @@ Fdbm_to_a(obj) GetDBM(obj, dbm); - GC_LINK; - GC_PRO3(ary, ary_new()); - + ary = ary_new(); for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) { val = dbm_fetch(dbm, key); Fary_push(ary, assoc_new(str_new(key.dptr, key.dsize), str_new(val.dptr, val.dsize))); } - GC_UNLINK; return ary; } @@ -12,7 +12,9 @@ #define RUBY -/* #include "config.h" */ +/* define EUC/SJIS for default kanji-code */ +#define EUC +#undef SJIS /* define USE_DLN to load object file(.o). */ #ifdef HAVE_A_OUT_H @@ -43,11 +43,7 @@ Fdic_new(class) NEWOBJ(dic, struct RDict); OBJSETUP(dic, class, T_DICT); - GC_LINK; - GC_PRO(dic); - dic->tbl = st_init_table(rb_cmp, rb_hash); - GC_UNLINK; return (VALUE)dic; } @@ -59,13 +55,8 @@ Fdic_clone(dic) NEWOBJ(dic2, struct RDict); CLONESETUP(dic2, dic); - GC_LINK; - GC_PRO(dic2); - dic2->tbl = (st_table*)st_copy(dic->tbl); - GC_UNLINK; - return (VALUE)dic2; } @@ -210,10 +201,8 @@ Fdic_to_a(dic) { VALUE ary; - GC_LINK; - GC_PRO3(ary, ary_new()); + ary = ary_new(); st_foreach(dic->tbl, dic_to_a, ary); - GC_UNLINK; return ary; } @@ -229,13 +218,11 @@ dic_inspect(key, value, str) if (str->len > 1) { str_cat(str, ", ", 2); } - GC_LINK; - GC_PRO3(str2, rb_funcall(key, inspect, 0, Qnil)); + str2 = rb_funcall(key, inspect, 0, Qnil); str_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len); str_cat(str, "=>", 2); str2 = rb_funcall(value, inspect, 0, Qnil); str_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len); - GC_UNLINK; return ST_CONTINUE; } @@ -246,11 +233,9 @@ Fdic_inspect(dic) { VALUE str; - GC_LINK; - GC_PRO3(str, str_new2("{")); + str = str_new2("{"); st_foreach(dic->tbl, dic_inspect, str); str_cat(str, "}", 1); - GC_UNLINK; return str; } @@ -261,11 +246,8 @@ Fdic_to_s(dic) { VALUE str; - GC_LINK; - GC_PRO(dic); dic = Fdic_to_a(dic); str = Fary_to_s(dic); - GC_UNLINK; return str; } @@ -284,10 +266,9 @@ Fdic_keys(dic) { VALUE ary; - GC_LINK; - GC_PRO3(ary, ary_new()); + ary = ary_new(); st_foreach(dic->tbl, dic_keys, ary); - GC_UNLINK; + return ary; } @@ -305,10 +286,9 @@ Fdic_values(dic) { VALUE ary; - GC_LINK; - GC_PRO3(ary, ary_new()); + ary = ary_new(); st_foreach(dic->tbl, dic_values, ary); - GC_UNLINK; + return ary; } @@ -326,7 +306,7 @@ Fdic_has_key(dic, key) static VALUE value_found; -static +static int dic_search_value(key, value, arg) VALUE key, value, arg; { @@ -347,6 +327,46 @@ Fdic_has_value(dic, val) return value_found; } +struct equal_data { + int result; + st_table *tbl; +}; + +static int +dic_equal(key, val1, data) + VALUE key, val1; + struct equal_data *data; +{ + VALUE val2; + + if (!st_lookup(data->tbl, key, &val2)) { + data->result = FALSE; + return ST_STOP; + } + if (!rb_funcall(val1, eq, 1, val2)) { + data->result = FALSE; + return ST_STOP; + } + return ST_CONTINUE; +} + +static VALUE +Fdic_equal(dic1, dic2) + struct RDict *dic1, *dic2; +{ + struct equal_data data; + + if (TYPE(dic2) != T_DICT) return FALSE; + if (dic1->tbl->num_entries != dic2->tbl->num_entries) + return FALSE; + + data.tbl = dic2->tbl; + data.result = TRUE; + st_foreach(dic1->tbl, dic_equal, &data); + + return data.result; +} + char *index(); extern VALUE rb_readonly_hook(); @@ -363,11 +383,9 @@ Fenv_each(dic) VALUE var, val; char *s = index(*env, '='); - GC_LINK; - GC_PRO3(var, str_new(*env, s-*env)); - GC_PRO3(val, str_new2(s+1)); + var = str_new(*env, s-*env); + val = str_new2(s+1); rb_yield(assoc_new(var, val)); - GC_UNLINK; env++; } return dic; @@ -481,6 +499,7 @@ Init_Dict() rb_define_method(C_Dict,"to_s", Fdic_to_s, 0); rb_define_method(C_Dict,"_inspect", Fdic_inspect, 0); + rb_define_method(C_Dict,"==", Fdic_equal, 1); rb_define_method(C_Dict,"[]", Fdic_aref, 1); rb_define_method(C_Dict,"[]=", Fdic_aset, 2); rb_define_method(C_Dict,"length", Fdic_length, 0); @@ -512,6 +531,6 @@ Init_Dict() envtbl = obj_alloc(C_EnvDict); rb_define_variable("$ENV", &envtbl, Qnil, rb_readonly_hook); - rb_define_func(C_Kernel, "getenv", Fgetenv, 1); - rb_define_func(C_Kernel, "setenv", Fsetenv, 2); + rb_define_method(C_Kernel, "getenv", Fgetenv, 1); + rb_define_method(C_Kernel, "setenv", Fsetenv, 2); } @@ -42,7 +42,7 @@ static void free_dir(dir) DIR **dir; { - if (dir) closedir(*dir); + if (dir && *dir) closedir(*dir); } static VALUE @@ -58,12 +58,9 @@ Fdir_open(dir_class, dirname) dirp = opendir(dirname->ptr); if (dirp == NULL) Fail("Can't open directory %s", dirname->ptr); - GC_LINK; - GC_PRO3(obj, obj_alloc(dir_class)); + obj = obj_alloc(dir_class); Make_Data_Struct(obj, "dir", DIR*, Qnil, free_dir, d); *d = dirp; - /* use memcpy(d, dirp, sizeof(DIR)) if needed.*/ - GC_UNLINK; return obj; } @@ -248,10 +245,10 @@ Init_Dir() rb_define_single_method(C_Dir,"chdir", Fdir_chdir, -2); rb_define_single_method(C_Dir,"getwd", Fdir_getwd, 0); - rb_define_alias(C_Dir, "pwd", "getwd"); + rb_define_single_method(C_Dir,"pwd", Fdir_getwd, 0); rb_define_single_method(C_Dir,"chroot", Fdir_chroot, 1); rb_define_single_method(C_Dir,"mkdir", Fdir_mkdir, -2); rb_define_single_method(C_Dir,"rmdir", Fdir_rmdir, 1); - rb_define_alias(C_Dir, "delete", "rmdir"); - rb_define_alias(C_Dir, "unlink", "rmdir"); + rb_define_single_method(C_Dir,"delete", Fdir_rmdir, 1); + rb_define_single_method(C_Dir,"unlink", Fdir_rmdir, 1); } @@ -52,12 +52,8 @@ Fenum_grep(obj, pat) VALUE tmp, arg[2]; arg[0] = pat; arg[1] = tmp = ary_new(); - GC_LINK; - GC_PRO(tmp); - rb_iterate(rb_each, obj, enum_grep, arg); - GC_UNLINK; return tmp; } } @@ -99,12 +95,9 @@ Fenum_find_all(obj) { VALUE tmp; - GC_LINK; - GC_PRO3(tmp, ary_new()); - + tmp = ary_new(); rb_iterate(rb_each, obj, enum_find_all, Qnil); - GC_UNLINK; return tmp; } @@ -114,14 +107,10 @@ enum_collect(i, tmp) { VALUE retval; - GC_LINK; - GC_PRO3(retval, rb_yield(i)); - + retval = rb_yield(i); if (retval) { Fary_push(tmp, retval); } - - GC_UNLINK; } static VALUE @@ -130,12 +119,9 @@ Fenum_collect(obj) { VALUE tmp; - GC_LINK; - GC_PRO3(tmp, ary_new()); - + tmp = ary_new(); rb_iterate(rb_each, obj, enum_collect, tmp); - GC_UNLINK; return tmp; } @@ -152,12 +138,9 @@ Fenum_reverse(obj) { VALUE tmp; - GC_LINK; - GC_PRO3(tmp, ary_new()); - + tmp = ary_new(); rb_iterate(rb_each, obj, enum_reverse, tmp); - GC_UNLINK; return tmp; } @@ -174,10 +157,8 @@ Fenum_to_a(obj) { VALUE ary; - GC_LINK; - GC_PRO3(ary, ary_new()); + ary = ary_new(); rb_iterate(rb_each, obj, enum_all, ary); - GC_UNLINK; return ary; } @@ -188,10 +169,8 @@ Fenum_sort(obj) { VALUE ary; - GC_LINK; - GC_PRO3(ary, Fenum_to_a(obj)); + ary = Fenum_to_a(obj); Fary_sort(ary); - GC_UNLINK; return ary; } @@ -214,12 +193,9 @@ static VALUE Fenum_min(obj) VALUE obj; { - VALUE min; + VALUE min = Qnil; - GC_LINK; - GC_PRO2(min); rb_iterate(rb_each, obj, enum_min, &min); - GC_UNLINK; return min; } @@ -242,12 +218,9 @@ static VALUE Fenum_max(obj) VALUE obj; { - VALUE max; + VALUE max = Qnil; - GC_LINK; - GC_PRO2(max); rb_iterate(rb_each, obj, enum_max, &max); - GC_UNLINK; return max; } @@ -154,6 +154,9 @@ static char *builtin_types[] = { "Fixnum", "Dictionary", "Data", + "Method", + "Struct", + "Bignum", }; WrongType(x, t) @@ -29,58 +29,34 @@ static VALUE setup_passwd(pwd) struct passwd *pwd; { - VALUE pw, name, passwd, gecos, dir, shell; -#ifdef PW_CLASS - VALUE class; -#endif -#ifdef PW_COMMENT - VALUE comment; -#endif - if (pwd == Qnil) rb_sys_fail("/etc/passwd"); - GC_LINK; - GC_PRO3(pw, str_new2(pwd->pw_name)); - GC_PRO3(passwd, str_new2(pwd->pw_passwd)); - GC_PRO3(gecos, str_new2(pwd->pw_gecos)); - GC_PRO3(dir, str_new2(pwd->pw_dir)); - GC_PRO3(shell, str_new2(pwd->pw_shell)); -#ifdef PW_CLASS - GC_PRO3(class, str_new2(pwd->pw_class)); -#endif -#ifdef PW_COMMENT - GC_PRO3(comment, str_new2(pwd->pw_comment)); -#endif - - pw = struct_new("passwd", - "name", name, - "passwd", passwd, - "uid", INT2FIX(pwd->pw_uid), - "gid", INT2FIX(pwd->pw_gid), - "gecos", gecos, - "dir", dir, - "shell", shell, + return struct_new("passwd", + "name", str_new2(pwd->pw_name), + "passwd", str_new2(pwd->pw_passwd), + "uid", INT2FIX(pwd->pw_uid), + "gid", INT2FIX(pwd->pw_gid), + "gecos", str_new2(pwd->pw_gecos), + "dir", str_new2(pwd->pw_dir), + "shell", str_new2(pwd->pw_shell), #ifdef PW_CHANGE - "change", INT2FIX(pwd->pw_change), + "change", INT2FIX(pwd->pw_change), #endif #ifdef PW_QUOTA - "quota", INT2FIX(pwd->pw_quota), + "quota", INT2FIX(pwd->pw_quota), #endif #ifdef PW_AGE - "age", INT2FIX(pwd->pw_age), + "age", INT2FIX(pwd->pw_age), #endif #ifdef PW_CLASS - "class", class, + "class", str_new2(pwd->pw_class), #endif #ifdef PW_COMMENT - "comment", comment, + "comment", str_new2(pwd->pw_comment), #endif #ifdef PW_EXPIRE - "expire", INT2FIX(pwd->pw_expire), + "expire", INT2FIX(pwd->pw_expire), #endif - Qnil); - GC_UNLINK; - - return pw; + Qnil); } static VALUE @@ -137,27 +113,21 @@ static VALUE setup_group(grp) struct group *grp; { - VALUE mem, obj, name, passwd; + VALUE mem; char **tbl; - GC_LINK; - GC_PRO3(mem, ary_new()); + mem = ary_new(); tbl = grp->gr_mem; while (*tbl) { Fary_push(mem, str_new2(*tbl)); tbl++; } - GC_PRO3(name, str_new2(grp->gr_name)); - GC_PRO3(passwd, str_new2(grp->gr_passwd)); - obj = struct_new("group", - "name", name, - "passwd", passwd, - "gid", INT2FIX(grp->gr_gid), - "mem", mem, - Qnil); - GC_UNLINK; - - return obj; + return struct_new("group", + "name", str_new2(grp->gr_name), + "passwd", str_new2(grp->gr_passwd), + "gid", INT2FIX(grp->gr_gid), + "mem", mem, + Qnil); } static VALUE @@ -22,6 +22,7 @@ static ID match, each; VALUE errstr, errat; extern NODE *eval_tree; +extern VALUE TopSelf; struct ENVIRON *the_env, *top_env; #define PUSH_ENV() {\ @@ -57,7 +58,6 @@ static struct tag { struct tag *_oldtag = prot_tag;\ &_oldtag;\ _this.level= ++tag_level;\ - _this.gclist= GC_List;\ _this.env= the_env;\ prot_tag = &_this;\ @@ -69,7 +69,6 @@ static struct tag { #define EXEC_TAG() (setjmp(prot_tag->buf)) #define JUMP_TAG(val) {\ the_env = prot_tag->env;\ - GC_List = prot_tag->gclist;\ longjmp(prot_tag->buf,(val));\ } @@ -89,6 +88,7 @@ VALUE Feval(); VALUE Argv; static VALUE rb_call(); VALUE rb_apply(); +VALUE rb_xstring(); static void asign(); @@ -123,12 +123,17 @@ error_print() exit(1); } +static int origargc; +static char **origargv; + main(argc, argv) int argc; char *argv[]; { int state; + origargc = argc; origargv = argv; + Init_stack(); PUSH_ENV(); top_env = the_env; PUSH_TAG(); @@ -174,21 +179,69 @@ main(argc, argv) VALUE rb_readonly_hook(); -VALUE Progname; +static VALUE Progname; static VALUE -Eval() +Eval(toplevel) + int toplevel; { - int state; + VALUE result; NODE *tree; + int state; if (match == Qnil) match = rb_intern("=~"); if (each == Qnil) each = rb_intern("each"); tree = eval_tree; eval_tree = Qnil; + PUSH_TAG(); + if ((state = EXEC_TAG()) == 0) { + result = rb_eval(tree); + } + POP_TAG(); + /* you don't have to free at toplevel */ + if (!toplevel) freenode(tree); + if (state) JUMP_TAG(state); + + return result; +} + +static VALUE +set_arg0(val, id) + VALUE val; + ID id; +{ + char *s; + int i; + static int len; + + Check_Type(val, T_STRING); + if (len == 0) { + s = origargv[0]; + s += strlen(s); + /* See if all the arguments are contiguous in memory */ + for (i = 1; i < origargc; i++) { + if (origargv[i] == s + 1) + s += strlen(++s); /* this one is ok too */ + } + len = s - origargv[0]; + } + s = RSTRING(val)->ptr; + i = RSTRING(val)->len; + if (i > len) { + memcpy(origargv[0], s, len); + origargv[0][len] = '\0'; + } + else { + memcpy(origargv[0], s, i); + s = origargv[0]+i; + *s++ = '\0'; + while (++i < len) + *s++ = ' '; + } + Progname = str_new2(origargv[0]); - return rb_eval(tree); + return val; } VALUE @@ -205,7 +258,7 @@ TopLevel(script, argc, argv) errat = Qnil; /* clear for execution */ Progname = str_new2(script); - rb_define_variable("$0", &Progname, Qnil, Qnil); + rb_define_variable("$0", &Progname, Qnil, set_arg0); rb_define_variable("$ARGV", &Argv, Qnil, Qnil); rb_define_variable("$*", &Argv, Qnil, Qnil); @@ -213,7 +266,12 @@ TopLevel(script, argc, argv) for (i=0; i < argc; i++) { Fary_push(Argv, str_new2(argv[i])); } - return Eval(); +#define PURIFY_D +#ifdef PURIFY_D + return Eval(0); +#else + return Eval(1); +#endif } void @@ -221,9 +279,10 @@ rb_trap_eval(cmd) VALUE cmd; { PUSH_ENV(); - the_env->self = top_env->self; + the_env->self = TopSelf; the_env->current_module = top_env->current_module; the_env->local_vars = top_env->local_vars; + the_env->local_tbl = top_env->local_tbl; the_class = (struct RClass*)C_Object; Feval(Qself, cmd); @@ -273,14 +332,10 @@ setup_arg_2(node, args, argc, argv) } #define SETUP_ARGS {\ - VALUE args;\ - GC_LINK;\ - GC_PRO2(args);\ + VALUE args = Qnil;\ argc = setup_arg_1(node->nd_args, &args);\ argv = (VALUE*)alloca(sizeof(VALUE)*argc);\ - GC_PRO4(argv, argc);\ setup_arg_2(node->nd_args, args, argc, argv);\ - GC_UNLINK;\ } static VALUE @@ -365,9 +420,7 @@ rb_eval(node) { VALUE val; - GC_LINK; - GC_PRO3(val, rb_eval(node->nd_head)); - + val = rb_eval(node->nd_head); node = node->nd_body; while (node) { if (node->type == NODE_WHEN) { @@ -375,22 +428,18 @@ rb_eval(node) while (tag) { if (rb_funcall(rb_eval(tag->nd_head), match, 1, val)){ - result = rb_eval(node->nd_body); - goto exit_case; + return rb_eval(node->nd_body); } tag = tag->nd_next; } } else { - result = rb_eval(node); - goto exit_case; + return rb_eval(node); } node = node->nd_next; } - exit_case: - GC_UNLINK; } - return result; + return Qnil; case NODE_WHILE: PUSH_TAG(); @@ -476,13 +525,9 @@ rb_eval(node) else { VALUE recv; - GC_LINK; - GC_PRO2(recv); recv = rb_eval(node->nd_iter); the_env->iterator = 1; - result = rb_call(CLASS_OF(recv), recv, each, 1, Qnil, - MTH_METHOD); - GC_UNLINK; + result = rb_call(CLASS_OF(recv), recv, each, 1, Qnil, 0); } } POP_TAG(); @@ -511,19 +556,13 @@ rb_eval(node) { VALUE val; - GC_LINK; - GC_PRO3(val, rb_eval(node->nd_stts)); + val = rb_eval(node->nd_stts); result = rb_yield(val); - GC_UNLINK; } return result; case NODE_PROT: - GC_LINK; - GC_PRO2(result); - PUSH_TAG(); - switch (state = EXEC_TAG()) { case 0: retry_entry: @@ -555,7 +594,6 @@ rb_eval(node) /* ensure clause */ rb_eval(node->nd_ensr); - GC_UNLINK; if (state != 0) { JUMP_TAG(state); @@ -610,7 +648,6 @@ rb_eval(node) { VALUE recv, *argv; int argc, last_iter; - enum mth_scope scope; last_iter = the_env->iterator; the_env->iterator = 0; /* recv & args are not iter. */ @@ -624,8 +661,7 @@ rb_eval(node) } the_env->iterator = last_iter; /* restore iter. level */ - scope = node->nd_recv?MTH_METHOD:MTH_FUNC; - return rb_call(CLASS_OF(recv),recv,node->nd_mid,argc,argv,scope); + return rb_call(CLASS_OF(recv),recv,node->nd_mid,argc,argv); } break; @@ -662,7 +698,7 @@ rb_eval(node) } result = rb_call(the_env->last_class->super, Qself, - the_env->last_func, argc, argv, Qnil, MTH_FUNC); + the_env->last_func, argc, argv, Qnil); the_env->iterator = last_iter; } return result; @@ -699,8 +735,6 @@ rb_eval(node) NODE *list = node->nd_head; int i, len; - GC_LINK; - GC_PRO(val); if (TYPE(val) != T_ARRAY) { val = rb_funcall(val, rb_intern("to_a"), 0, Qnil); if (TYPE(val) != T_ARRAY) { @@ -716,7 +750,6 @@ rb_eval(node) asign(list->nd_head, Qnil); list = list->nd_next; } - GC_UNLINK; return val; } @@ -729,27 +762,24 @@ rb_eval(node) { VALUE val; - GC_LINK; GC_PRO3(val, rb_eval(node->nd_value)); + val = rb_eval(node->nd_value); rb_gvar_set(node->nd_entry, val); - GC_UNLINK; return val; } case NODE_IASGN: { VALUE val; - GC_LINK; GC_PRO3(val, rb_eval(node->nd_value)); + val = rb_eval(node->nd_value); rb_ivar_set(node->nd_vid, val); - GC_UNLINK; return val; } case NODE_CASGN: { VALUE val; - GC_LINK; GC_PRO3(val, rb_eval(node->nd_value)); + val = rb_eval(node->nd_value); rb_const_set(node->nd_vid, val); - GC_UNLINK; return val; } break; @@ -786,8 +816,6 @@ rb_eval(node) VALUE hash = Fdic_new(C_Dict); VALUE key, val; - GC_LINK; - GC_PRO(hash); GC_PRO2(key); GC_PRO2(val); list = node->nd_head; while (list) { key = rb_eval(list->nd_head); @@ -798,7 +826,6 @@ rb_eval(node) list = list->nd_next; Fdic_aset(hash, key, val); } - GC_UNLINK; return hash; } break; @@ -812,14 +839,12 @@ rb_eval(node) int i; NODE *list; - GC_LINK; for (i=0, list=node; list; list=list->nd_next) i++; - GC_PRO3(ary, ary_new2(i)); + ary = ary_new2(i); for (i=0;node;node=node->nd_next) { RARRAY(ary)->ptr[i++] = rb_eval(node->nd_head); RARRAY(ary)->len = i; } - GC_UNLINK; return ary; } @@ -828,6 +853,39 @@ rb_eval(node) case NODE_STR: return str_new3(node->nd_lit); + case NODE_STR2: + case NODE_XSTR2: + case NODE_DREGX: + { + VALUE str, str2; + NODE *list = node->nd_next; + + str = node->nd_lit; + while (list) { + if (list->nd_head->type == NODE_STR) { + str2 = list->nd_head->nd_lit; + } + else { + str2 = rb_eval(list->nd_head); + } + if (str2) { + str2 = obj_as_string(str2); + str_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len); + } + list = list->nd_next; + } + if (node->type == NODE_DREGX) { + return regexp_new(RSTRING(str)->ptr, RSTRING(str)->len); + } + else if (node->type == NODE_XSTR2) { + return rb_xstring(str); + } + return str; + } + + case NODE_XSTR: + return rb_xstring(node->nd_lit); + case NODE_LIT: return node->nd_lit; @@ -841,10 +899,7 @@ rb_eval(node) NODE *local; int i, len; - local = node->nd_frml; - for (i=0; local; local=local->nd_next,i++) - ; - + i = node->nd_cnt; len = the_env->argc - 1; if (i > len || (node->nd_rest == -1 && i < len)) Fail("Wrong # of arguments(%d for %d)", len, i); @@ -869,26 +924,32 @@ rb_eval(node) case NODE_DEFN: { - rb_add_method(the_class,node->nd_mid,node->nd_defn,node->nd_scope); + if (node->nd_defn) { + rb_add_method(the_class,node->nd_mid,node->nd_defn,0); + node->nd_defn = Qnil; + } } return Qnil; case NODE_DEFS: { - VALUE recv = rb_eval(node->nd_recv); + if (node->nd_defn) { + VALUE recv = rb_eval(node->nd_recv); - if (recv == Qnil) { - Fail("Can't define method \"%s\" for nil", - rb_id2name(node->nd_mid)); + if (recv == Qnil) { + Fail("Can't define method \"%s\" for nil", + rb_id2name(node->nd_mid)); + } + rb_add_method(rb_single_class(recv), + node->nd_mid, node->nd_defn, 0); + node->nd_defn = Qnil; } - rb_add_method(rb_single_class(recv), - node->nd_mid, node->nd_defn, MTH_METHOD); } return Qnil; case NODE_UNDEF: { - rb_add_method(the_class, node->nd_mid, Qnil, MTH_UNDEF); + rb_add_method(the_class, node->nd_mid, Qnil, 1); } return Qnil; @@ -992,7 +1053,7 @@ obj_responds_to(obj, msg) id = rb_intern(msg->ptr); } - if (rb_get_method_body(CLASS_OF(obj), id, 0, MTH_FUNC)) { + if (rb_get_method_body(CLASS_OF(obj), id, 0)) { return TRUE; } return FALSE; @@ -1187,8 +1248,7 @@ asign(lhs, val) case NODE_CALL: { VALUE recv; - GC_LINK; - GC_PRO3(recv, rb_eval(lhs->nd_recv)); + recv = rb_eval(lhs->nd_recv); if (lhs->nd_args->nd_head == Qnil) { /* attr set */ rb_funcall(recv, lhs->nd_mid, 1, val); @@ -1197,11 +1257,10 @@ asign(lhs, val) /* array set */ VALUE args; - GC_PRO3(args, rb_eval(lhs->nd_args)); + args = rb_eval(lhs->nd_args); RARRAY(args)->ptr[RARRAY(args)->len-1] = val; rb_apply(recv, lhs->nd_mid, args); } - GC_UNLINK; } break; @@ -1319,8 +1378,6 @@ rb_ensure(b_proc, data1, e_proc, data2) int state; VALUE result; - GC_LINK; - GC_PRO2(result); PUSH_TAG(); if ((state = EXEC_TAG()) == 0) { result = (*b_proc)(data1); @@ -1331,7 +1388,6 @@ rb_ensure(b_proc, data1, e_proc, data2) if (state != 0) { JUMP_TAG(state); } - GC_UNLINK; return result; } @@ -1339,7 +1395,8 @@ struct st_table *new_idhash(); static void rb_undefined(obj, id) - VALUE obj, id; + VALUE obj; + ID id; { VALUE desc = obj_as_string(obj); @@ -1347,18 +1404,17 @@ rb_undefined(obj, id) desc = Fkrn_to_s(obj); } Fail("undefined method `%s' for \"%s\"(%s)", - rb_id2name(NUM2INT(id)), + rb_id2name(id), RSTRING(desc)->ptr, rb_class2name(CLASS_OF(obj))); } static VALUE -rb_call(class, recv, mid, argc, argv, scope) +rb_call(class, recv, mid, argc, argv) struct RClass *class; VALUE recv, *argv; int argc; ID mid; - enum mth_scope scope; { int state; int go_out = 0; @@ -1375,7 +1431,7 @@ rb_call(class, recv, mid, argc, argv, scope) if (argv) argv[0] = recv; if (the_env->iterator != 0) the_env->iterator++; - if ((body = rb_get_method_body(class, mid, 1, scope)) == Qnil) { + if ((body = rb_get_method_body(class, mid, 1)) == Qnil) { rb_undefined(recv, mid); } @@ -1541,7 +1597,7 @@ rb_apply(recv, mid, args) argv[i] = RARRAY(args)->ptr[i-1]; } argv[0] = Qnil; - return rb_call(CLASS_OF(recv), recv, mid, argc, argv, MTH_FUNC); + return rb_call(CLASS_OF(recv), recv, mid, argc, argv); } VALUE @@ -1592,7 +1648,7 @@ rb_funcall(recv, mid, n, va_alist) argv = Qnil; } - return rb_call(CLASS_OF(recv), recv, mid, argc, argv, MTH_FUNC); + return rb_call(CLASS_OF(recv), recv, mid, argc, argv); } VALUE @@ -1622,12 +1678,10 @@ Fcaller(obj, args) } if (e->file == Qnil) Fail("initial frame"); - GC_LINK; - GC_PRO3(file, str_new2(e->file)); - GC_PRO3(ary, e->argv?ary_new4(e->argc, e->argv):ary_new3(1, Qself)); + file = str_new2(e->file); + ary = e->argv?ary_new4(e->argc, e->argv):ary_new3(1, Qself); res = ary_new3(4, file, INT2FIX(e->line), str_new2(rb_id2name(e->last_func)), ary); - GC_UNLINK; return res; } @@ -1663,9 +1717,9 @@ Feval(obj, src) eval_tree = Qnil; yyparse(); sourcefile = oldsrc; - if (nerrs == 0) - result = Eval(); - freenode(eval_tree); + if (nerrs == 0) { + result = Eval(0); + } } eval_tree = node; POP_ENV(); @@ -1676,13 +1730,11 @@ Feval(obj, src) if (nerrs > 0) { VALUE mesg; - GC_LINK; - GC_PRO3(mesg, errstr); + mesg = errstr; nerrs = 0; errstr = str_new2("syntax error in eval():\n"); str_cat(errstr, RSTRING(mesg)->ptr, RSTRING(mesg)->len); rb_fail(errstr); - GC_UNLINK; } return result; @@ -1702,9 +1754,6 @@ find_file(file) if (file[0] == '/') return file; - GC_LINK; - GC_PRO2(sep); GC_PRO2(vpath); - if (rb_load_path) { Check_Type(rb_load_path, T_ARRAY); sep = str_new2(":"); @@ -1721,7 +1770,6 @@ find_file(file) if (found == Qnil) Fail("No such file to load -- %s", file); if (vpath) obj_free(vpath); - GC_UNLINK; return found; } @@ -1731,9 +1779,7 @@ Fload(obj, fname) VALUE obj; struct RString *fname; { - extern VALUE TopSelf; int state; - VALUE result; NODE *node; char *file; @@ -1763,18 +1809,17 @@ Fload(obj, fname) PUSH_ENV(); the_class = (struct RClass*)C_Object; Qself = TopSelf; + the_env->current_module = top_env->current_module; + the_env->local_vars = top_env->local_vars; + the_env->local_tbl = top_env->local_tbl; the_env->in_eval = 1; - node = eval_tree; state = EXEC_TAG(); if (state == 0) { - eval_tree = Qnil; rb_load_file(file); if (nerrs == 0) { - result = Eval(); + Eval(0); } - freenode(eval_tree); } - eval_tree = node; POP_ENV(); POP_TAG(); if (nerrs > 0) { @@ -1853,6 +1898,6 @@ Init_load() addpath(getenv("RUBYLIB")); addpath(RUBY_LIB); - rb_define_func(C_Kernel, "load", Fload, 1); - rb_define_func(C_Kernel, "require", Frequire, 1); + rb_define_method(C_Kernel, "load", Fload, 1); + rb_define_method(C_Kernel, "require", Frequire, 1); } @@ -33,8 +33,7 @@ file_open(fname, mode) VALUE port; OpenFile *fptr; - GC_LINK; - GC_PRO3(port, obj_alloc(C_File)); + port = obj_alloc(C_File); MakeOpenFile(port, fptr); fptr->mode = io_mode_flags(mode); @@ -52,8 +51,6 @@ file_open(fname, mode) fptr->path = strdup(fname); - GC_UNLINK; - return port; } @@ -85,6 +82,7 @@ Ffile_seek(obj, offset, ptrname) pos = fseek(fptr->f, NUM2INT(offset), NUM2INT(ptrname)); if (pos != 0) rb_sys_fail(Qnil); + clearerr(fptr->f); return obj; } @@ -97,6 +95,7 @@ Ffile_rewind(obj) GetOpenFile(obj, fptr); if (fseek(fptr->f, 0L, 0) != 0) rb_sys_fail(Qnil); + clearerr(fptr->f); return obj; } @@ -137,16 +136,8 @@ static VALUE stat_new(st) struct stat *st; { - VALUE obj, data, atime, mtime, ctime, stat; - if (st == Qnil) Bug("stat_new() called with nil"); - - GC_LINK; - GC_PRO3(atime, time_new(st->st_atime, 0)); - GC_PRO3(mtime, time_new(st->st_mtime, 0)); - GC_PRO3(ctime, time_new(st->st_ctime, 0)); - - stat = struct_new("stat", + return struct_new("stat", "dev", INT2FIX((int)st->st_dev), "ino", INT2FIX((int)st->st_ino), "mode", INT2FIX((int)st->st_mode), @@ -169,13 +160,10 @@ stat_new(st) #else "blocks", INT2FIX(0), #endif - "atime", atime, - "mtime", mtime, - "ctime", ctime, + "atime", time_new(st->st_atime, 0), + "mtime", time_new(st->st_mtime, 0), + "ctime", time_new(st->st_ctime, 0), Qnil); - GC_UNLINK; - - return stat; } static char lastpath[MAXPATHLEN]; @@ -14,16 +14,14 @@ #include "env.h" #include "st.h" #include <stdio.h> +#include <setjmp.h> void *malloc(); void *calloc(); void *realloc(); -struct gc_list *GC_List = Qnil; -static struct gc_list *Global_List = Qnil; -static unsigned long bytes_alloc = 0, gc_threshold = 1000000; - -static mark_tbl(); +void gc(); +void gc_mark(); void * xmalloc(size) @@ -31,12 +29,10 @@ xmalloc(size) { void *mem; - bytes_alloc += size; if (size == 0) size = 1; mem = malloc(size); if (mem == Qnil) { gc(); - bytes_alloc += size; mem = malloc(size); if (mem == Qnil) Fatal("failed to allocate memory"); @@ -75,23 +71,41 @@ xrealloc(ptr, size) return mem; } -void -rb_global_variable(var) - VALUE *var; -{ - struct gc_list *tmp; - - tmp = (struct gc_list*)xmalloc(sizeof(struct gc_list)); - tmp->next = Global_List; - tmp->varptr = var; - tmp->n = 1; - Global_List = tmp; -} - -static struct RBasic *object_list = Qnil; -static struct RBasic *literal_list = Qnil; -static unsigned long fl_current = FL_MARK; -static unsigned long fl_old = 0L; +/* The way of garbage collecting which allows use of the cstack is due to */ +/* Scheme In One Defun, but in C this time. + + * COPYRIGHT (c) 1989 BY * + * PARADIGM ASSOCIATES INCORPORATED, CAMBRIDGE, MASSACHUSETTS. * + * ALL RIGHTS RESERVED * + +Permission to use, copy, modify, distribute and sell this software +and its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all copies +and that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of Paradigm Associates +Inc not be used in advertising or publicity pertaining to distribution +of the software without specific, written prior permission. + +PARADIGM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +PARADIGM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + + +Paradigm Associates Inc Phone: 617-492-6079 +29 Putnam Ave, Suite 6 +Cambridge, MA 02138 +*/ + +#ifdef sparc +#define FLUSH_REGISTER_WINDOWS asm("ta 3") +#else +#define FLUSH_REGISTER_WINDOWS /* empty */ +#endif static int dont_gc; @@ -113,23 +127,6 @@ Fgc_disable() return old; } -VALUE -Fgc_threshold(obj) - VALUE obj; -{ - return INT2FIX(gc_threshold); -} - -VALUE -Fgc_set_threshold(obj, val) - VALUE obj, val; -{ - int old = gc_threshold; - - gc_threshold = NUM2INT(val); - return INT2FIX(old); -} - #include <sys/types.h> #include <sys/times.h> @@ -145,140 +142,204 @@ static Fgc_end() VALUE M_GC; -static ID start_hook, end_hook; +static struct gc_list { + int n; + VALUE *varptr; + struct gc_list *next; +} *Global_List = Qnil; -struct RBasic * -newobj(size) - unsigned long size; +void +rb_global_variable(var) + VALUE *var; { - struct RBasic *obj = Qnil; + struct gc_list *tmp; - if (bytes_alloc + size > gc_threshold) { - gc(); - } - obj = (struct RBasic*)xmalloc(size); - obj->next = object_list; - object_list = obj; - obj->flags = fl_current; - obj->iv_tbl = Qnil; + tmp = (struct gc_list*)xmalloc(sizeof(struct gc_list)); + tmp->next = Global_List; + tmp->varptr = var; + tmp->n = 1; + Global_List = tmp; +} - return obj; +struct RVALUE { + union { + struct { + int flag; /* alway 0 for freed obj */ + struct RVALUE *next; + } free; + struct RObject object; + struct RClass class; + struct RFloat flonum; + struct RString string; + struct RArray array; + struct RRegexp regexp; + struct RDict dict; + struct RData data; + struct RStruct rstruct; + struct RBignum bignum; + } as; +} *freelist = Qnil; + +struct heap_block { + struct heap_block *next; + struct RVALUE *beg; + struct RVALUE *end; + struct RVALUE body[1]; +} *heap_link = Qnil; + +#define SEG_SLOTS 4000 +#define SEG_SIZE (SEG_SLOTS*sizeof(struct RVALUE)) + +static int heap_size; + +static void +add_heap() +{ + struct heap_block *block; + struct RVALUE *p, *pend; + + block = (struct heap_block*)malloc(sizeof(*block) + SEG_SIZE); + if (block == Qnil) Fatal("cant alloc memory"); + block->next = heap_link; + block->beg = &block->body[0]; + block->end = block->beg + SEG_SLOTS; + p = block->beg; pend = block->end; + while (p < pend) { + p->as.free.flag = 0; + p->as.free.next = freelist; + freelist = p; + p++; + } + heap_link = block; + heap_size += SEG_SLOTS; } -literalize(obj) - struct RBasic *obj; +struct RBasic * +newobj() { - struct RBasic *ptr = object_list; + struct RBasic *obj; + if (heap_link == Qnil) add_heap(); + if (freelist) { + retry: + obj = (struct RBasic*)freelist; + freelist = freelist->as.free.next; + obj->flags = 0; + obj->iv_tbl = Qnil; + return obj; + } + if (dont_gc) add_heap(); + else gc(); - if (NIL_P(obj) || FIXNUM_P(obj)) return; + goto retry; +} - FL_SET(obj, FL_LITERAL); - if (ptr == obj) { - object_list = ptr->next; - obj->next = literal_list; - literal_list = obj; +VALUE +newdata(size) + UINT size; +{ + extern VALUE C_Data; + struct RData *data = (struct RData*)newobj(); - return; - } + OBJSETUP(data, C_Data, T_DATA); + data->data = xmalloc(size); + return (VALUE)data; +} - while (ptr && ptr->next) { - if (ptr->next == obj) { - ptr->next = obj->next; - obj->next = literal_list; - literal_list = obj; +static struct literal_list { + VALUE val; + struct literal_list *next; +} *Literal_List = Qnil; - return; - } - ptr = ptr->next; - } - Bug("0x%x is not a object.", obj); +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) - struct RBasic *obj; + VALUE obj; { - struct RBasic *ptr = literal_list; + 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 == obj) { - literal_list = ptr->next; - goto unlit; + if (ptr->val == obj) { + Literal_List = ptr->next; + free(ptr); + return; } while (ptr->next) { - if (ptr->next == obj) { - ptr->next = obj->next; + if (ptr->next->val == obj) { + tmp = ptr->next; + ptr->next = ptr->next->next; + ptr = tmp; + free(tmp); + return; } ptr = ptr->next; - goto unlit; } Bug("0x%x is not a literal object.", obj); - - unlit: - obj->next = object_list; - object_list = obj; - obj->flags &= ~FL_MARK; - obj->flags |= fl_current; - return; } -extern st_table *rb_global_tbl; extern st_table *rb_class_tbl; +static VALUE *stack_start_ptr; -gc() +static long +looks_pointerp(p) + struct RVALUE *p; { - struct gc_list *list; - struct ENVIRON *env; - int i, max; - - rb_funcall(M_GC, start_hook, 0, Qnil); - - if (dont_gc) return; - dont_gc++; - fl_old = fl_current; - fl_current = ~fl_current & FL_MARK; - - /* mark env stack */ - for (env = the_env; env; env = env->prev) { - mark(env->self); - for (i=1, max=env->argc; i<max; i++) { - mark(env->argv[i]); - } - if (env->local_vars) { - for (i=0, max=env->local_tbl[0]; i<max; i++) - mark(env->local_vars[i]); - } - } - - /* mark protected C variables */ - for (list=GC_List; list; list=list->next) { - VALUE *v = list->varptr; - for (i=0, max = list->n; i<max; i++) { - mark(*v); - v++; - } - } - - /* mark protected global variables */ - for (list = Global_List; list; list = list->next) { - mark(*list->varptr); + struct heap_block *heap = heap_link; + + if (FIXNUM_P(p)) return FALSE; + while (heap) { + if (heap->beg <= p && p < heap->end + && ((((char*)p) - ((char*)heap->beg)) % sizeof(struct RVALUE)) == 0) + return TRUE; + heap = heap->next; } + return FALSE; +} - mark_global_tbl(); - mark_tbl(rb_class_tbl); - - mark_trap_list(); +static void +mark_locations_array(x, n) + VALUE *x; + long n; +{ + int j; + VALUE p; + for(j=0;j<n;++j) + {p = x[j]; + if (looks_pointerp(p)) { + gc_mark(p); + } + } +} - sweep(); - bytes_alloc = 0; - dont_gc--; +static void +mark_locations(start, end) + VALUE *start, *end; +{ + VALUE *tmp; + long n; - rb_funcall(M_GC, end_hook, 0, Qnil); + if (start > end) { + tmp = start; + start = end; + end = tmp; + } + n = end - start; + mark_locations_array(start,n); } static @@ -286,7 +347,7 @@ mark_entry(key, value) ID key; VALUE value; { - mark(value); + gc_mark(value); return ST_CONTINUE; } @@ -302,8 +363,8 @@ mark_dicentry(key, value) ID key; VALUE value; { - mark(key); - mark(value); + gc_mark(key); + gc_mark(value); return ST_CONTINUE; } @@ -314,39 +375,35 @@ mark_dict(tbl) st_foreach(tbl, mark_dicentry, 0); } -mark(obj) +void +gc_mark(obj) register struct RBasic *obj; { if (obj == Qnil) return; if (FIXNUM_P(obj)) return; - if ((obj->flags & FL_MARK) == fl_current) return; + if (obj->flags & FL_MARK) return; - obj->flags &= ~FL_MARK; - obj->flags |= fl_current; + obj->flags |= FL_MARK; switch (obj->flags & T_MASK) { case T_NIL: case T_FIXNUM: - Bug("mark() called for broken object"); + Bug("gc_mark() called for broken object"); break; } if (obj->iv_tbl) mark_tbl(obj->iv_tbl); + gc_mark(obj->class); switch (obj->flags & T_MASK) { - case T_OBJECT: - mark(obj->class); - break; case T_ICLASS: - mark(RCLASS(obj)->super); + 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: - mark(RCLASS(obj)->super); + 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); - mark(RBASIC(obj)->class); + gc_mark(RBASIC(obj)->class); break; case T_ARRAY: { @@ -354,21 +411,21 @@ mark(obj) VALUE *ptr = RARRAY(obj)->ptr; for (i=0; i < len; i++) - mark(ptr[i]); + gc_mark(ptr[i]); } break; case T_DICT: mark_dict(RDICT(obj)->tbl); break; case T_STRING: - if (RSTRING(obj)->orig) mark(RSTRING(obj)->orig); + 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_METHOD: case T_BIGNUM: break; case T_STRUCT: @@ -377,42 +434,77 @@ mark(obj) struct kv_pair *ptr = RSTRUCT(obj)->tbl; for (i=0; i < len; i++) - mark(ptr[i].value); + gc_mark(ptr[i].value); } break; default: - Bug("mark(): unknown data type %d", obj->flags & T_MASK); + Bug("gc_mark(): unknown data type %d", obj->flags & T_MASK); } } -sweep() -{ - register struct RBasic *link = object_list; - register struct RBasic *next; - - if (link && (link->flags & FL_MARK) == fl_old) { - object_list = object_list->next; - obj_free(link); - link = object_list; - } +#define MIN_FREE_OBJ 512 - while (link && link->next) { - if ((link->next->flags & FL_MARK) == fl_old) { - next = link->next->next; - obj_free(link->next); - link->next = next; - continue; +static void +gc_sweep() +{ + struct heap_block *heap = heap_link; + int freed = 0; + + freelist = Qnil; + while (heap) { + struct RVALUE *p, *pend; + struct RVALUE *nfreelist; + int n = 0; + + nfreelist = freelist; + p = heap->beg; pend = heap->end; + while (p < pend) { + + if (!(RBASIC(p)->flags & FL_MARK)) { + if (RBASIC(p)->flags) obj_free(p); + p->as.free.flag = 0; + p->as.free.next = nfreelist; + nfreelist = p; + n++; + } + RBASIC(p)->flags &= ~FL_MARK; + p++; + } + if (n == SEG_SLOTS) { + struct heap_block *link = heap_link; + if (heap != link) { + while (link) { + if (link->next && link->next == heap) { + link->next = heap->next; + break; + } + link = link->next; + } + if (link == Qnil) { + Bug("non-existing heap at 0x%x", heap); + } + } + free(heap); + heap_size -= SEG_SLOTS; + heap = link; } - link = link->next; + else { + freed += n; + freelist = nfreelist; + } + heap = heap->next; + } + if (freed < heap_size/4) { + add_heap(); } } static freemethod(key, body) ID key; - char *body; + void *body; { - freenode(body); + method_free(body); return ST_CONTINUE; } @@ -432,6 +524,7 @@ obj_free(obj) 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) @@ -452,14 +545,12 @@ obj_free(obj) break; case T_DATA: if (RDATA(obj)->dfree) (*RDATA(obj)->dfree)(DATA_PTR(obj)); + free(DATA_PTR(obj)); break; case T_ICLASS: /* iClass shares table with the module */ case T_FLOAT: break; - case T_METHOD: - freenode(RMETHOD(obj)->node); - break; case T_STRUCT: free(RSTRUCT(obj)->name); free(RSTRUCT(obj)->tbl); @@ -468,9 +559,69 @@ obj_free(obj) free(RBIGNUM(obj)->digits); break; default: - Bug("sweep(): unknown data type %d", obj->flags & T_MASK); + Bug("gc_sweep(): unknown data type %d", obj->flags & T_MASK); + } +} + +void +gc() +{ + struct literal_list *lit; + struct gc_list *list; + struct ENVIRON *env; + int i, max; + jmp_buf save_regs_gc_mark; + VALUE stack_end; + + 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); + if (env->local_vars) + mark_locations_array(env->local_vars, env->local_tbl[0]); } - free(obj); + + FLUSH_REGISTER_WINDOWS; + /* This assumes that all registers are saved into the jmp_buf */ + setjmp(save_regs_gc_mark); + mark_locations((VALUE*)save_regs_gc_mark, + (VALUE*)(((char*)save_regs_gc_mark)+sizeof(save_regs_gc_mark))); + mark_locations((VALUE*)save_regs_gc_mark, + sizeof save_regs_gc_mark/sizeof(VALUE)); + mark_locations(stack_start_ptr, (VALUE*) &stack_end); +#if defined(THINK_C) + mark_locations(((char*)stack_start_ptr + 2), + ((char*)&stack_end + 2)); +#endif + + /* mark protected global variables */ + for (list = Global_List; list; list = list->next) { + 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); + + gc_mark_trap_list(); + + gc_sweep(); + dont_gc--; +} + +Init_stack() +{ + VALUE start; + + stack_start_ptr = &start; } Init_GC() @@ -479,12 +630,5 @@ Init_GC() rb_define_single_method(M_GC, "start", gc, 0); rb_define_single_method(M_GC, "enable", Fgc_enable, 0); rb_define_single_method(M_GC, "disable", Fgc_disable, 0); - rb_define_single_method(M_GC, "threshold", Fgc_threshold, 0); - rb_define_single_method(M_GC, "threshold=", Fgc_set_threshold, 1); - rb_define_single_method(M_GC, "start_hook", Fgc_begin, 0); - rb_define_single_method(M_GC, "end_hook", Fgc_end, 0); - rb_define_func(M_GC, "garbage_collect", gc, 0); - - start_hook = rb_intern("start_hook"); - end_hook = rb_intern("end_hook"); + rb_define_method(M_GC, "garbage_collect", gc, 0); } @@ -174,9 +174,7 @@ read_all(port) } if (fptr->f == NULL) Fail("closed stream"); - GC_LINK; - GC_PRO3(str, str_new(0, 0)); - + str = str_new(0, 0); for (;;) { n = fread(buf, 1, BUFSIZ, fptr->f); if (n == 0) { @@ -185,8 +183,6 @@ read_all(port) } str_cat(str, buf, n); } - - GC_UNLINK; return str; } @@ -252,9 +248,6 @@ Fio_gets(obj) f = fptr->f; if (f == NULL) Fail("closed stream"); - GC_LINK; - GC_PRO2(str); - if (RS) { rslen = RSTRING(RS)->len; if (rslen == 0) { @@ -329,8 +322,6 @@ Fio_gets(obj) } } - GC_UNLINK; - if (str) { fptr->lineno++; lineno = INT2FIX(fptr->lineno); @@ -345,7 +336,6 @@ Fio_each(obj) { VALUE str; - GC_PRO2(str); while (str = Fio_gets(obj)) { rb_yield(str); } @@ -574,9 +564,7 @@ pipe_open(pname, mode) int pid, pr[2], pw[2]; int doexec; - GC_LINK; - GC_PRO3(port, obj_alloc(C_IO)); - + port = obj_alloc(C_IO); MakeOpenFile(port, fptr); fptr->mode = io_mode_flags(mode); @@ -631,8 +619,6 @@ pipe_open(pname, mode) if (fptr->mode & FMODE_READABLE) fptr->f = rb_fdopen(pr[0], "r"); if (fptr->mode & FMODE_WRITABLE) fptr->f2 = rb_fdopen(pw[1], "w"); - GC_UNLINK; - return port; } @@ -672,13 +658,13 @@ Fprintf(argc, argv) int argc; VALUE argv[]; { - VALUE out, str; + VALUE out; if (argc == 1) return Qnil; if (TYPE(argv[1]) == T_STRING) { out = rb_defout; } - else if (rb_get_method_body(CLASS_OF(argv[1]), id_write, 0, MTH_FUNC)) { + else if (obj_responds_to(argv[1], INT2FIX(id_write))) { out = argv[1]; argv++; argc--; @@ -687,12 +673,7 @@ Fprintf(argc, argv) Fail("output must responds to `write'"); } - GC_LINK; - GC_PRO3(str, Fsprintf(argc, argv)); - - rb_funcall(out, id_write, 1, str); - - GC_UNLINK; + rb_funcall(out, id_write, 1, Fsprintf(argc, argv)); return Qnil; } @@ -740,12 +721,9 @@ prep_stdio(f, mode) VALUE obj = obj_alloc(C_IO); OpenFile *fp; - GC_LINK; - GC_PRO(obj); MakeOpenFile(obj, fp); fp->f = f; fp->mode = mode; - GC_UNLINK; return obj; } @@ -874,15 +852,11 @@ Freadlines(obj) { VALUE line, ary; - GC_LINK; - GC_PRO2(line); - GC_PRO3(ary, ary_new()); - + ary = ary_new(); while (line = Fgets(obj)) { Fary_push(ary, line); } - GC_UNLINK; return ary; } @@ -898,9 +872,8 @@ rb_check_str(val, id) return TRUE; } -static VALUE -Fsystem2(obj, str) - VALUE obj; +VALUE +rb_xstring(str) struct RString *str; { VALUE port, result; @@ -908,10 +881,7 @@ Fsystem2(obj, str) int mask; Check_Type(str, T_STRING); - GC_LINK; - GC_PRO3(port, pipe_open(str->ptr, "r")); - GC_PRO2(result); - + port = pipe_open(str->ptr, "r"); result = read_all(port); GetOpenFile(port, fptr); @@ -919,7 +889,6 @@ Fsystem2(obj, str) fptr->pid = 0; obj_free(port); - GC_UNLINK; return result; } @@ -1026,8 +995,7 @@ Fselect(obj, args) } if (n == 0) return Qnil; - GC_LINK; - GC_PRO3(res, ary_new2(3)); + res = ary_new2(3); RARRAY(res)->ptr[0] = rp?ary_new():Qnil; RARRAY(res)->len++; RARRAY(res)->ptr[1] = wp?ary_new():Qnil; @@ -1075,7 +1043,6 @@ Fselect(obj, args) } } - GC_UNLINK; return res; } @@ -1141,6 +1108,100 @@ Fio_defset(obj, val) return rb_defout = val; } +static VALUE +Fsyscall(argc, argv) + int argc; + VALUE *argv; +{ +#ifdef HAVE_SYSCALL +#ifdef atarist + unsigned long arg[14]; /* yes, we really need that many ! */ +#else + unsigned long arg[8]; +#endif + int retval = -1; + int i = 1; + int items = argc - 2; + + /* This probably won't work on machines where sizeof(long) != sizeof(int) + * or where sizeof(long) != sizeof(char*). But such machines will + * not likely have syscall implemented either, so who cares? + */ + argv++; /* skip SELF */ + arg[0] = NUM2INT(argv[0]); argv++; + while (items--) { + if (FIXNUM_P(*argv)) { + arg[i] = (unsigned long)NUM2INT(*argv); argv++; + } + else { + Check_Type(*argv, T_STRING); + str_modify(*argv); + arg[i] = (unsigned long)RSTRING(*argv)->ptr; argv++; + } + i++; + } + switch (argc-1) { + case 0: + Fail("Too few args to syscall"); + case 1: + retval = syscall(arg[0]); + break; + case 2: + retval = syscall(arg[0],arg[1]); + break; + case 3: + retval = syscall(arg[0],arg[1],arg[2]); + break; + case 4: + retval = syscall(arg[0],arg[1],arg[2],arg[3]); + break; + case 5: + retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4]); + break; + case 6: + retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5]); + break; + case 7: + retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6]); + break; + case 8: + retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6], + arg[7]); + break; +#ifdef atarist + case 9: + retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6], + arg[7], arg[8]); + break; + case 10: + retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6], + arg[7], arg[8], arg[9]); + break; + case 11: + retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6], + arg[7], arg[8], arg[9], arg[10]); + break; + case 12: + retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6], + arg[7], arg[8], arg[9], arg[10], arg[11]); + break; + case 13: + retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6], + arg[7], arg[8], arg[9], arg[10], arg[11], arg[12]); + break; + case 14: + retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6], + arg[7], arg[8], arg[9], arg[10], arg[11], arg[12], arg[13]); + break; +#endif /* atarist */ + } + if (retval == -1) rb_sys_fail(0); + return Qnil; +#else + Fail("syscall() unimplemented"); +#endif +} + extern VALUE M_Enumerable; VALUE rb_readonly_hook(); @@ -1148,17 +1209,18 @@ Init_IO() { extern VALUE C_Kernel; - rb_define_func(C_Kernel, "open", Fopen, -2); - rb_define_func(C_Kernel, "printf", Fprintf, -1); + rb_define_method(C_Kernel, "syscall", Fsyscall, -1); + + rb_define_method(C_Kernel, "open", Fopen, -2); + rb_define_method(C_Kernel, "printf", Fprintf, -1); rb_define_method(C_Kernel, "print", Fprint, -1); - rb_define_func(C_Kernel, "gets", Fgets, 0); - rb_define_func(C_Kernel, "eof", Feof, 0); + rb_define_method(C_Kernel, "gets", Fgets, 0); + rb_define_method(C_Kernel, "eof", Feof, 0); rb_define_alias(C_Kernel,"readline", "gets"); - rb_define_func(C_Kernel, "getc", Fgetc, 0); - rb_define_func(C_Kernel, "system2", Fsystem2, 1); - rb_define_func(C_Kernel, "select", Fselect, -2); + rb_define_method(C_Kernel, "getc", Fgetc, 0); + rb_define_method(C_Kernel, "select", Fselect, -2); - rb_define_func(C_Kernel, "readlines", Freadlines, 0); + rb_define_method(C_Kernel, "readlines", Freadlines, 0); C_IO = rb_define_class("IO", C_Object); rb_include_module(C_IO, M_Enumerable); @@ -1191,7 +1253,7 @@ Init_IO() rb_define_method(C_IO, "read", Fio_read, -2); rb_define_method(C_IO, "write", Fio_write, 1); rb_define_method(C_IO, "gets", Fio_gets, 0); - rb_define_alias(C_IO, "readlines", "gets"); + rb_define_alias(C_IO, "readline", "gets"); rb_define_method(C_IO, "getc", Fio_getc, 0); rb_define_method(C_IO, "puts", Fio_puts, 1); rb_define_method(C_IO, "<<", Fio_puts, 1); @@ -24,11 +24,8 @@ if (FIXNUM_P(x)) {\ } #define Need_Float2(x,y) {\ - GC_LINK;\ - GC_PRO(x);\ Need_Float(x);\ Need_Float(y);\ - GC_UNLINK;\ } static VALUE @@ -14,6 +14,9 @@ #include "ident.h" #include "env.h" #include "node.h" +#include "methods.h" + +void method_free(); #define CACHE_SIZE 577 #if 0 @@ -28,18 +31,18 @@ struct hash_entry { /* method hash table. */ ID mid; /* method's id */ struct RClass *class; /* receiver's class */ struct RClass *origin; /* where method defined */ - struct RMethod *method; - enum mth_scope scope; + struct SMethod *method; + int undef; }; static struct hash_entry cache[CACHE_SIZE]; -static struct RMethod* +static struct SMethod* search_method(class, id, origin) struct RClass *class, **origin; ID id; { - struct RMethod *body; + struct SMethod *body; NODE *list; while (!st_lookup(class->m_tbl, id, &body)) { @@ -55,21 +58,19 @@ search_method(class, id, origin) } NODE* -rb_get_method_body(class, id, envset, scope) +rb_get_method_body(class, id, envset) struct RClass *class; ID id; int envset; - enum mth_scope scope; { int pos, i; - int cscope; - struct RMethod *method; + struct SMethod *method; /* is it in the method cache? */ pos = EXPR1(class, id) % CACHE_SIZE; if (cache[pos].class != class || cache[pos].mid != id) { /* not in the cache */ - struct RMethod *body; + struct SMethod *body; struct RClass *origin; if ((body = search_method(class, id, &origin)) == Qnil) { @@ -80,13 +81,11 @@ rb_get_method_body(class, id, envset, scope) cache[pos].class = class; cache[pos].origin = origin; cache[pos].method = body; - cache[pos].scope = body->scope; + cache[pos].undef = body->undef; } - cscope = cache[pos].scope; method = cache[pos].method; - if (cscope == MTH_UNDEF) return Qnil; - if (cscope == MTH_FUNC && scope == MTH_METHOD) return Qnil; + if (cache[pos].undef) return Qnil; if (envset) { the_env->last_func = method->id; the_env->last_class = cache[pos].origin; @@ -99,21 +98,23 @@ rb_alias(class, name, def) struct RClass *class; ID name, def; { - struct RMethod *body; + struct SMethod *body; if (st_lookup(class->m_tbl, name, &body)) { if (verbose) { Warning("redefine %s", rb_id2name(name)); } - unliteralize(body); + rb_clear_cache(body); + method_free(body); } body = search_method(class, def, &body); + body->count++; st_insert(class->m_tbl, name, body); } void rb_clear_cache(body) - struct RMethod *body; + struct SMethod *body; { int i; @@ -129,17 +130,23 @@ void rb_clear_cache2(class) struct RClass *class; { + int i; - class = class->super; - while (class) { - int i; - - for (i = 0; i< CACHE_SIZE; i++ ) { - if (cache[i].origin == class) { - cache[i].class = Qnil; - cache[i].mid = Qnil; - } + for (i = 0; i< CACHE_SIZE; i++ ) { + if (cache[i].origin == class) { + cache[i].class = Qnil; + cache[i].mid = Qnil; } - class = class->super; + } +} + +void +method_free(body) + struct SMethod *body; +{ + body->count--; + if (body->count == 0) { + freenode(body->node); + free(body); } } diff --git a/methods.h b/methods.h new file mode 100644 index 0000000000..944eb8829c --- /dev/null +++ b/methods.h @@ -0,0 +1,22 @@ +/************************************************ + + methods.h - + + $Author$ + $Revision$ + $Date$ + created at: Fri Jul 29 14:43:03 JST 1994 + +************************************************/ +#ifndef METHOD_H +#define METHOD_H + +struct SMethod { + struct node *node; + struct RClass *origin; + ID id; + int count; + int undef; +}; + +#endif diff --git a/missing/strftime.c b/missing/strftime.c index 36a325aa51..4d3561c78c 100644 --- a/missing/strftime.c +++ b/missing/strftime.c @@ -101,7 +101,9 @@ adddecl(static int iso8601wknum(const struct tm *timeptr);) #if !defined(OS2) && !defined(MSDOS) && defined(HAVE_TZNAME) extern char *tzname[2]; +# ifdef HAVE_DAYLIGHT extern int daylight; +# endif #endif /* min --- return minimum of two numbers */ @@ -457,7 +459,7 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr) goto again; case 'V': /* week of year according ISO 8601 */ -#if defined(RUBY) && defined(VMS_EXT) +#if defined(GAWK) && defined(VMS_EXT) { extern int do_lint; extern void warning(); @@ -1,4 +1,4 @@ -#! ./ruby +#! /usr/local/bin/ruby f = open("version.h", "r") f.gets() f.close @@ -39,6 +39,7 @@ enum node_type { NODE_ZSUPER, NODE_ARRAY, NODE_ZARRAY, + NODE_QLIST, NODE_HASH, NODE_REDO, NODE_BREAK, @@ -54,6 +55,10 @@ enum node_type { NODE_CONST, NODE_LIT, NODE_STR, + NODE_STR2, + NODE_XSTR, + NODE_XSTR2, + NODE_DREGX, NODE_ARGS, NODE_DEFN, NODE_DEFS, @@ -78,7 +83,6 @@ typedef struct node { VALUE value; VALUE (*cfunc)(); ID *tbl; - enum mth_scope scope; } u1; union { struct node *node; @@ -135,7 +139,6 @@ typedef struct node { #define nd_mid u2.id #define nd_args u3.node -#define nd_scope u1.scope #define nd_defn u3.node #define nd_new u1.id @@ -155,7 +158,7 @@ typedef struct node { #define nd_rval u3.node -#define NEW_DEFN(i,d,m) newnode(NODE_DEFN,m,i,d) +#define NEW_DEFN(i,d) newnode(NODE_DEFN,Qnil,i,d) #define NEW_DEFS(r,i,d) newnode(NODE_DEFS,r,i,d) #define NEW_CFUNC(f,c) newnode(NODE_CFUNC,f,c,Qnil) #define NEW_RFUNC(b1,b2) NEW_SCOPE(block_append(b1,b2)) @@ -177,6 +180,7 @@ typedef struct node { #define NEW_RET(s) newnode(NODE_RETURN,s,Qnil,Qnil) #define NEW_YIELD(a) newnode(NODE_YIELD,a,Qnil,Qnil) #define NEW_LIST(a) NEW_ARRAY(a) +#define NEW_QLIST(a) newnode(NODE_QLIST,a,Qnil,Qnil) #define NEW_ARRAY(a) newnode(NODE_ARRAY,a,Qnil,Qnil) #define NEW_ZARRAY() newnode(NODE_ZARRAY,Qnil,Qnil,Qnil) #define NEW_HASH(a) newnode(NODE_HASH,a,Qnil,Qnil) @@ -194,6 +198,9 @@ typedef struct node { #define NEW_CVAR(v) newnode(NODE_CVAR,v,Qnil,Qnil) #define NEW_LIT(l) newnode(NODE_LIT,l,Qnil,Qnil) #define NEW_STR(s) newnode(NODE_STR,s,Qnil,Qnil) +#define NEW_STR2(s) newnode(NODE_STR2,s,Qnil,Qnil) +#define NEW_XSTR(s) newnode(NODE_XSTR,s,Qnil,Qnil) +#define NEW_XSTR2(s) newnode(NODE_XSTR2,s,Qnil,Qnil) #define NEW_CALL(r,m,a) newnode(NODE_CALL,r,m,a) #define NEW_CALL2(r,m,a) newnode(NODE_CALL2,r,m,a) #define NEW_SUPER(a) newnode(NODE_SUPER,Qnil,Qnil,a) @@ -128,11 +128,8 @@ Fnum_divmod(x, y) { VALUE div, mod; - GC_LINK; - GC_PRO3(div, rb_funcall(x, '/', 1, y)); - GC_PRO3(mod, rb_funcall(x, '%', 1, y)); - GC_UNLINK; - + div = rb_funcall(x, '/', 1, y); + mod = rb_funcall(x, '%', 1, y); return assoc_new(div, mod); } @@ -437,19 +434,17 @@ int num2int(val) VALUE val; { - int result; - if (val == Qnil) return 0; switch (TYPE(val)) { case T_FIXNUM: - result = FIX2INT(val); + return FIX2INT(val); break; case T_FLOAT: if (RFLOAT(val)->value <= (double) LONG_MAX && RFLOAT(val)->value >= (double) LONG_MIN) { - result = (int)RFLOAT(val)->value; + return (int)RFLOAT(val)->value; } else { Fail("float %g out of rang of integer", RFLOAT(val)->value); @@ -463,7 +458,6 @@ num2int(val) Fail("failed to convert %s into int", rb_class2name(CLASS_OF(val))); break; } - return result; } static VALUE @@ -578,12 +572,7 @@ Ffix_plus(x, y) r = INT2FIX(c); if (FIX2INT(r) != c) { - VALUE big1, big2; - GC_LINK; - GC_PRO3(big1, int2big(a)); - GC_PRO3(big2, int2big(b)); - r = Fbig_plus(big1, big2); - GC_UNLINK; + r = Fbig_plus(int2big(a), int2big(b)); } return r; } @@ -611,12 +600,7 @@ Ffix_minus(x, y) r = INT2FIX(c); if (FIX2INT(r) != c) { - VALUE big1, big2; - GC_LINK; - GC_PRO3(big1, int2big(a)); - GC_PRO3(big2, int2big(b)); - r = Fbig_minus(big1, big2); - GC_UNLINK; + r = Fbig_minus(int2big(a), int2big(b)); } return r; } @@ -640,12 +624,7 @@ Ffix_mul(x, y) VALUE r = INT2FIX(c); if (FIX2INT(r) != c) { - VALUE big1, big2; - GC_LINK; - GC_PRO3(big1, int2big(a)); - GC_PRO3(big2, int2big(b)); - r = Fbig_mul(big1, big2); - GC_UNLINK; + r = Fbig_mul(int2big(a), int2big(b)); } return r; } @@ -692,18 +671,22 @@ Ffix_pow(x, y) VALUE x, y; { extern double pow(); - int result; if (FIXNUM_P(y)) { - result = pow((double)FIX2INT(x), (double)FIX2INT(y)); - return int2inum(result); + int a, b; + + b = FIX2INT(y); + if (b == 0) return INT2FIX(1); + a = FIX2INT(x); + if (b > 0) { + return Fbig_pow(int2big(a), y); + } + return float_new(pow((double)a, (double)b)); } else if (NIL_P(y)) { return INT2FIX(1); } - else { - return num_coerce_bin(x, y); - } + return num_coerce_bin(x, y); } static VALUE @@ -804,12 +787,7 @@ Ffix_lshift(x, y) width = NUM2INT(y); if (width > (sizeof(VALUE)*CHAR_BIT-1) || (unsigned)val>>(sizeof(VALUE)*CHAR_BIT-width) > 0) { - VALUE big; - GC_LINK; - GC_PRO3(big, int2big(val)); - big = Fbig_lshift(big, y); - GC_UNLINK; - return big; + return Fbig_lshift(int2big(val), y); } val = val << width; return int2inum(val); @@ -142,13 +142,11 @@ obj_inspect(id, value, str) else { str_cat(str, ", ", 2); } - GC_LINK; ivname = rb_id2name(id); str_cat(str, ivname, strlen(ivname)); str_cat(str, "=", 1); - GC_PRO3(str2, rb_funcall(value, rb_intern("_inspect"), 0, Qnil)); + str2 = rb_funcall(value, rb_intern("_inspect"), 0, Qnil); str_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len); - GC_UNLINK; return ST_CONTINUE; } @@ -162,12 +160,10 @@ Fobj_inspect(obj) if (FIXNUM_P(obj) || !obj->iv_tbl) return Fkrn_to_s(obj); - GC_LINK; sprintf(buf, "-<%s: ", rb_class2name(CLASS_OF(obj))); - GC_PRO3(str, str_new2(buf)); + str = str_new2(buf); st_foreach(obj->iv_tbl, obj_inspect, str); str_cat(str, ">", 1); - GC_UNLINK; return str; } @@ -224,13 +220,10 @@ Fobj_clone(obj) Check_Type(obj, T_OBJECT); clone = obj_alloc(RBASIC(obj)->class); - GC_LINK; - GC_PRO(clone); if (RBASIC(obj)->iv_tbl) { RBASIC(clone)->iv_tbl = st_copy(RBASIC(obj)->iv_tbl); } RBASIC(clone)->class = single_class_clone(RBASIC(obj)->class); - GC_UNLINK; return clone; } @@ -263,6 +256,7 @@ Fnil_plus(x, y) switch (TYPE(y)) { case T_FIXNUM: case T_FLOAT: + case T_BIGNUM: case T_STRING: case T_ARRAY: return y; @@ -399,14 +393,14 @@ Init_Object() rb_define_method(C_Kernel, "to_s", Fkrn_to_s, 0); rb_define_method(C_Kernel, "_inspect", Fkrn_inspect, 0); - rb_define_func(C_Kernel, "caller", Fcaller, -2); - rb_define_func(C_Kernel, "fail", Ffail, -2); - rb_define_func(C_Kernel, "exit", Fexit, -2); - rb_define_func(C_Kernel, "eval", Feval, 1); - rb_define_func(C_Kernel, "defined", Fdefined, 1); - rb_define_func(C_Kernel, "sprintf", Fsprintf, -1); + rb_define_method(C_Kernel, "caller", Fcaller, -2); + rb_define_method(C_Kernel, "fail", Ffail, -2); + rb_define_method(C_Kernel, "exit", Fexit, -2); + rb_define_method(C_Kernel, "eval", Feval, 1); + rb_define_method(C_Kernel, "defined", Fdefined, 1); + rb_define_method(C_Kernel, "sprintf", Fsprintf, -1); rb_define_alias(C_Kernel, "format", "sprintf"); - rb_define_func(C_Kernel, "iterator_p", Fiterator_p, 0); + rb_define_method(C_Kernel, "iterator_p", Fiterator_p, 0); rb_define_method(C_Kernel, "apply", Fapply, -2); @@ -422,7 +416,7 @@ Init_Object() rb_define_method(C_Module, "to_s", Fcls_to_s, 0); rb_define_method(C_Module, "clone", Fcant_clone, 0); - rb_define_func(C_Module, "attr", Fcls_attr, -2); + rb_define_method(C_Module, "attr", Fcls_attr, -2); rb_define_method(C_Class, "new", Fcls_new, -2); @@ -434,12 +428,6 @@ Init_Object() rb_define_method(C_Nil, "is_nil", P_true, 0); rb_define_method(C_Nil, "!", P_true, 0); - /* for compare cascading. */ - rb_define_method(C_Nil, ">", P_false, 1); - rb_define_alias(C_Nil, ">=", ">"); - rb_define_alias(C_Nil, "<", ">"); - rb_define_alias(C_Nil, "<=", ">"); - /* default addition */ rb_define_method(C_Nil, "+", Fnil_plus, 1); @@ -448,7 +436,7 @@ Init_Object() rb_define_method(C_Data, "class", Fdata_class, 0); C_Method = rb_define_class("Method", C_Kernel); - rb_define_method(C_Data, "clone", Fcant_clone, 0); + rb_define_method(C_Method, "clone", Fcant_clone, 0); eq = rb_intern("=="); match = rb_intern("=~"); @@ -65,9 +65,7 @@ Fpck_pack(ary, fmt) p = fmt->ptr; pend = fmt->ptr + fmt->len; - GC_LINK; - GC_PRO2(from); - GC_PRO3(res, str_new(0, 0)); + res = str_new(0, 0); items = ary->len; idx = 0; @@ -446,7 +444,6 @@ Fpck_pack(ary, fmt) break; } } - GC_UNLINK; return res; } @@ -499,8 +496,7 @@ Fpck_unpack(str, fmt) p = fmt->ptr; pend = p + fmt->len; - GC_LINK; - GC_PRO3(ary, ary_new()); + ary = ary_new(); while (p < pend) { retry: type = *p++; @@ -838,7 +834,6 @@ Fpck_unpack(str, fmt) } } - GC_UNLINK; return ary; } @@ -17,6 +17,7 @@ #include "env.h" #include "node.h" #include "st.h" +#include <stdio.h> #include "ident.h" #define is_id_nonop(id) ((id)>LAST_TOKEN) @@ -35,6 +36,9 @@ struct op_tbl { NODE *eval_tree = Qnil; static int in_regexp; +char *sourcefile; /* current source file */ +int sourceline; /* current line no. */ + enum { KEEP_STATE = 0, /* don't change lex_state. */ EXPR_BEG, /* ignore newline, +/- is a sign. */ @@ -57,6 +61,7 @@ static NODE *list_concat(); static NODE *list_copy(); static NODE *call_op(); +static NODE *gettable(); static NODE *asignable(); static NODE *aryset(); static NODE *attrset(); @@ -82,7 +87,6 @@ static void setup_top_local(); %token CLASS MODULE DEF - FUNC UNDEF INCLUDE IF @@ -111,16 +115,19 @@ static void setup_top_local(); RETRY SELF NIL + _FILE_ + _LINE_ -%token <id> IDENTIFIER GVAR IVAR CONSTANT -%token <val> INTEGER FLOAT STRING REGEXP +%token <id> IDENTIFIER GVAR IVAR CONSTANT +%token <val> INTEGER FLOAT STRING XSTRING REGEXP +%token <node> STRING2 XSTRING2 DREGEXP %type <node> singleton inc_list %type <val> literal numeric %type <node> compexpr exprs expr expr2 primary var_ref %type <node> if_tail opt_else cases resque ensure opt_using %type <node> call_args opt_args args f_arglist f_args f_arg -%type <node> assoc_list assocs assoc +%type <node> assoc_list assocs assoc regexp %type <node> mlhs mlhs_head mlhs_tail lhs %type <id> superclass variable symbol %type <id> fname fname0 op rest_arg end_mark @@ -152,10 +159,10 @@ static void setup_top_local(); %nonassoc DOT2 DOT3 %left OR %left AND -%left '|' '^' -%left '&' %nonassoc CMP EQ NEQ MATCH NMATCH %left '>' GEQ '<' LEQ +%left '|' '^' +%left '&' %left LSHFT RSHFT %left '+' '-' %left '*' '/' '%' @@ -241,24 +248,7 @@ expr : CLASS IDENTIFIER superclass if ($7 && $7 != DEF) { Error("unmatched end keyword(expected `def')"); } - $$ = NEW_DEFN($2, NEW_RFUNC($4, $5), MTH_METHOD); - pop_local(); - cur_mid = Qnil; - } - | DEF FUNC fname - { - if (cur_mid || in_single) - Error("nested method definition"); - cur_mid = $3; - push_local(); - } - f_arglist compexpr - END end_mark - { - if ($8 && $8 != DEF) { - Error("unmatched end keyword(expected `def')"); - } - $$ = NEW_DEFN($3, NEW_RFUNC($5, $6), MTH_FUNC); + $$ = NEW_DEFN($2, NEW_RFUNC($4, $5)); pop_local(); cur_mid = Qnil; } @@ -421,6 +411,14 @@ op : COLON2 { $$ = COLON2; } f_arglist : '(' f_args rparen { + if ($2) { + NODE *list = $2->nd_frml; + int i; + + for (i=0; list; list=list->nd_next, i++) + ; + $2->nd_cnt = i; + } $$ = $2; } | term @@ -457,7 +455,7 @@ f_arg : IDENTIFIER { if (!is_local_id($1)) Error("formal argument must be local variable"); - $$ = NEW_LIST(local_cnt($1)); + $$ = NEW_QLIST(local_cnt($1)); } | f_arg comma IDENTIFIER { @@ -887,26 +885,32 @@ args : expr2 } primary : var_ref - | '(' compexpr rparen + | literal { - $$ = $2; + literalize($1); + $$ = NEW_LIT($1); } - | STRING { literalize($1); $$ = NEW_STR($1); } + | STRING2 + | XSTRING + { + literalize($1); + $$ = NEW_XSTR($1); + } + | XSTRING2 + | '/' {in_regexp = 1;} regexp + { + $$ = $3; + } | primary '[' args rbracket { value_expr($1); $$ = NEW_CALL($1, AREF, $3); } - | literal - { - literalize($1); - $$ = NEW_LIT($1); - } | '[' opt_args rbracket { if ($2 == Qnil) @@ -949,16 +953,23 @@ primary : var_ref Error("super called outside of method"); $$ = NEW_ZSUPER(); } + | '(' compexpr rparen + { + $$ = $2; + } literal : numeric | '\\' symbol { $$ = INT2FIX($2); } - | '/' {in_regexp = 1;} REGEXP + +regexp : REGEXP { - $$ = $3; + literalize($1); + $$ = NEW_LIT($1); } + | DREGEXP symbol : fname0 | IVAR @@ -983,27 +994,7 @@ variable : IDENTIFIER var_ref : variable { - if ($1 == SELF) { - $$ = NEW_SELF(); - } - else if ($1 == NIL) { - $$ = NEW_NIL(); - } - else if (is_local_id($1)) { - if (local_id($1)) - $$ = NEW_LVAR($1); - else - $$ = NEW_MVAR($1); - } - else if (is_global_id($1)) { - $$ = NEW_GVAR($1); - } - else if (is_instance_id($1)) { - $$ = NEW_IVAR($1); - } - else if (is_const_id($1)) { - $$ = NEW_CVAR($1); - } + $$ = gettable($1); } assoc_list : /* none */ @@ -1027,7 +1018,6 @@ assoc : expr2 ASSOC expr2 end_mark : CLASS { $$ = CLASS; } | MODULE { $$ = MODULE; } | DEF { $$ = DEF; } - | FUNC { $$ = FUNC; } | IF { $$ = IF; } | UNLESS { $$ = UNLESS; } | CASE { $$ = CASE; } @@ -1054,7 +1044,6 @@ rbrace : '}' { yyerrok; } comma : ',' { yyerrok; } %% -#include <stdio.h> #include <ctype.h> #include <sys/types.h> #include "regex.h" @@ -1075,11 +1064,9 @@ char *strdup(); #define EXPAND_B 1 #define LEAVE_BS 2 +static NODE *var_extend(); static void read_escape(); -char *sourcefile; /* current source file */ -int sourceline; /* current line no. */ - static char *lex_p; static int lex_len; @@ -1135,7 +1122,9 @@ static struct kwtable { int id; int state; } kwtable [] = { - "__END__", 0, KEEP_STATE, + "__END__", 0, KEEP_STATE, + "__FILE__", _FILE_, EXPR_END, + "__LINE__", _LINE_, EXPR_END, "break", BREAK, EXPR_END, "case", CASE, KEEP_STATE, "class", CLASS, KEEP_STATE, @@ -1147,7 +1136,6 @@ static struct kwtable { "end", END, EXPR_END, "ensure", ENSURE, EXPR_BEG, "for", FOR, KEEP_STATE, - "func", FUNC, KEEP_STATE, "if", IF, KEEP_STATE, "in", IN, EXPR_BEG, "include", INCLUDE, EXPR_BEG, @@ -1170,6 +1158,8 @@ static struct kwtable { "yield", YIELD, EXPR_BEG, }; +static int strstart; + yylex() { register int c; @@ -1179,6 +1169,7 @@ yylex() if (in_regexp) { int in_brack = 0; int re_start = sourceline; + NODE *list = Qnil; in_regexp = 0; newtok(); @@ -1190,6 +1181,12 @@ yylex() case ']': in_brack = 0; break; + + case '#': + list = var_extend(list, '/'); + if (list == (NODE*)-1) return 0; + continue; + case '\\': if ((c = nextc()) == -1) { sourceline = re_start; @@ -1213,9 +1210,21 @@ yylex() break; tokfix(); - yylval.val = regexp_new(tok(), toklen()); lex_state = EXPR_END; - return REGEXP; + if (list) { + if (toklen() > 0) { + VALUE ss = str_new(tok(), toklen()); + literalize(ss); + list_append(list, NEW_STR(ss)); + } + list->type = NODE_DREGX; + yylval.node = list; + return DREGEXP; + } + else { + yylval.val = regexp_new(tok(), toklen()); + return REGEXP; + } case -1: Error("unterminated regexp"); @@ -1335,12 +1344,17 @@ retry: return '>'; case '"': + case '`': { - int strstart = sourceline; + char term = c; + NODE *list = Qnil; + ID id; + strstart = sourceline; newtok(); - while ((c = nextc()) != '"') { + while ((c = nextc()) != term) { if (c == -1) { + unterm_str: sourceline = strstart; Error("unterminated string meets end of file"); return 0; @@ -1352,12 +1366,17 @@ retry: else if (c == '\n') { sourceline++; } + else if (c == '#') { + list = var_extend(list, term); + if (list == (NODE*)-1) return 0; + continue; + } else if (c == '\\') { c = nextc(); if (c == '\n') { sourceline++; } - else if (c == '"') { + else if (c == term) { tokadd(c); } else { @@ -1369,22 +1388,34 @@ retry: tokadd(c); } tokfix(); - yylval.val = str_new(tok(), toklen()); lex_state = EXPR_END; - return STRING; + if (list == Qnil) { + yylval.val = str_new(tok(), toklen()); + return (term == '"') ? STRING : XSTRING; + } + else { + if (toklen() > 0) { + VALUE ss = str_new(tok(), toklen()); + literalize(ss); + list_append(list, NEW_STR(ss)); + } + yylval.node = list; + if (term == '"') { + return STRING2; + } + else { + list->type = NODE_XSTR2; + return XSTRING2; + } + } } case '\'': { - int strstart = sourceline; - - newtok(); + strstart = sourceline; + newtok(); while ((c = nextc()) != '\'') { - if (c == -1) { - sourceline = strstart; - Error("unterminated string meets end of file"); - return 0; - } + if (c == -1) goto unterm_str; if (ismbchar(c)) { tokadd(c); c = nextc(); @@ -1639,7 +1670,6 @@ retry: case ',': case ';': - case '`': case '[': case '(': case '{': @@ -1765,6 +1795,103 @@ retry: } } +static NODE* +var_extend(list, term) + NODE *list; + char term; +{ + int c, t; + VALUE ss; + ID id; + + c = nextc(); + switch (c) { + default: + tokadd('#'); + pushback(); + return list; + case '@': case '%': + t = nextc(); + pushback(); + if (!is_identchar(t)) { + tokadd('#'); + tokadd(c); + return list; + } + case '$': + case '{': + break; + } + + ss = str_new(tok(), toklen()); + if (list == Qnil) { + literalize(ss); + list = NEW_STR2(ss); + } + else if (toklen() > 0) { + literalize(ss); + list_append(list, NEW_STR(ss)); + } + newtok(); + if (c == '{') { + while ((c = nextc()) != '}') { + if (c == -1) { + unterm_str: + sourceline = strstart; + Error("unterminated string meets end of file"); + return (NODE*)-1; + } + if (isspace(c)) { + Error("Invalid variable name in string"); + break; + } + if (c == term) { + Error("Inmature variable name in string"); + pushback(); + return list; + } + tokadd(c); + } + } + else { + switch (c) { + case '$': + tokadd(c); + c = nextc(); + if (c == -1) goto unterm_str; + if (!is_identchar(c)) { + tokadd(c); + goto fetch_id; + } + /* through */ + case '@': case '%': + tokadd(c); + c = nextc(); + break; + } + while (is_identchar(c)) { + tokadd(c); + if (ismbchar(c)) { + c = nextc(); + tokadd(c); + } + c = nextc(); + } + pushback(); + } + fetch_id: + tokfix(); + if (strcmp("__LINE__", tok()) == 0) + id = _LINE_; + else if (strcmp("__FILE__", tok()) == 0) + id = _FILE_; + else + id = rb_intern(tok()); + list_append(list, gettable(id)); + newtok(); + return list; +} + static void read_escape(flag) int flag; @@ -1890,6 +2017,7 @@ read_escape(flag) if (flag & LEAVE_BS) { tokadd('\\'); } + case '#': tokadd(c); break; } @@ -1957,11 +2085,12 @@ static NODE* list_append(head, tail) NODE *head, *tail; { - if (head == Qnil) return NEW_ARRAY(tail); + if (head == Qnil) return NEW_LIST(tail); if (head->nd_last == Qnil) head->nd_last = head; - - head->nd_last->nd_next = NEW_ARRAY(tail); + + head->nd_last->nd_next = + head->type == NODE_QLIST?NEW_QLIST(tail):NEW_LIST(tail); head->nd_last = head->nd_last->nd_next; return head; } @@ -2007,9 +2136,17 @@ void freenode(node) case NODE_BLOCK: case NODE_ARRAY: freenode(node->nd_head); + case NODE_STR2: + case NODE_XSTR2: + case NODE_DREGX: + case NODE_QLIST: freenode(node->nd_next); break; + case NODE_HASH: + freenode(node->nd_head); + break; case NODE_IF: + case NODE_UNLESS: case NODE_WHEN: case NODE_PROT: freenode(node->nd_cond); @@ -2026,57 +2163,85 @@ void freenode(node) break; case NODE_DO: case NODE_FOR: + freenode(node->nd_var); freenode(node->nd_ibdy); freenode(node->nd_iter); break; case NODE_LASGN: case NODE_GASGN: case NODE_IASGN: + case NODE_CASGN: freenode(node->nd_value); break; + case NODE_MASGN: + freenode(node->nd_value); + freenode(node->nd_head); + break; case NODE_CALL: case NODE_SUPER: freenode(node->nd_recv); - case NODE_CALL2: freenode(node->nd_args); break; + case NODE_CALL2: + { + NODE *list = node->nd_next, *tmp; + while (list) { + tmp = list; + list = list->nd_next; + free(tmp); + } + } + break; case NODE_DEFS: freenode(node->nd_recv); + case NODE_DEFN: + freenode(node->nd_defn); break; case NODE_RETURN: case NODE_YIELD: freenode(node->nd_stts); break; case NODE_STR: + case NODE_XSTR: case NODE_LIT: unliteralize(node->nd_lit); break; - case NODE_CONST: - unliteralize(node->nd_cval); - break; case NODE_ARGS: freenode(node->nd_frml); break; case NODE_SCOPE: - free(node->nd_tbl); + if (node->nd_tbl) free(node->nd_tbl); freenode(node->nd_body); break; - case NODE_DEFN: + case NODE_DOT3: + freenode(node->nd_beg); + freenode(node->nd_end); + break; + case NODE_CLASS: + case NODE_MODULE: + freenode(node->nd_body); + break; + case NODE_ATTRSET: + case NODE_CVAR: + case NODE_CONST: + case NODE_ZSUPER: case NODE_ZARRAY: case NODE_CFUNC: case NODE_BREAK: case NODE_CONTINUE: + case NODE_REDO: case NODE_RETRY: case NODE_LVAR: case NODE_GVAR: case NODE_IVAR: case NODE_MVAR: - case NODE_CLASS: - case NODE_MODULE: case NODE_INC: + case NODE_UNDEF: + case NODE_ALIAS: case NODE_NIL: + case NODE_SELF: break; - default: + default: Bug("freenode: unknown node type %d", node->type); break; } @@ -2148,6 +2313,42 @@ call_op(recv, id, narg, arg1) } static NODE* +gettable(id) + ID id; +{ + if (id == SELF) { + return NEW_SELF(); + } + else if (id == NIL) { + return NEW_NIL(); + } + else if (id == _LINE_) { + return NEW_LIT(INT2FIX(sourceline)); + } + else if (id == _FILE_) { + VALUE s = str_new2(sourcefile); + + literalize(s); + return NEW_STR(s); + } + else if (is_local_id(id)) { + if (local_id(id)) + return NEW_LVAR(id); + else + return NEW_MVAR(id); + } + else if (is_global_id(id)) { + return NEW_GVAR(id); + } + else if (is_instance_id(id)) { + return NEW_IVAR(id); + } + else if (is_const_id(id)) { + return NEW_CVAR(id); + } +} + +static NODE* asignable(id, val) ID id; NODE *val; @@ -2162,6 +2363,9 @@ asignable(id, val) lhs = Qnil; Error("Can't asign to nil"); } + else if (id == _LINE_ || id == _FILE_) { + Error("Can't asign to special identifier"); + } else if (is_local_id(id)) { lhs = NEW_LASGN(id, val); } @@ -2348,7 +2552,7 @@ setup_top_local() the_env->local_vars = ALLOC_N(VALUE, lvtbl->cnt); bzero(the_env->local_vars, lvtbl->cnt * sizeof(VALUE)); } - else { + else if (lvtbl->tbl[0] < lvtbl->cnt) { int i; REALLOC_N(the_env->local_vars, VALUE, lvtbl->cnt); @@ -18,7 +18,6 @@ #include <sys/time.h> #include <sys/resource.h> #include "st.h" -VALUE rb_readonly_hook(); static VALUE get_pid() @@ -472,13 +471,13 @@ static int trap_immediate; #endif void -mark_trap_list() +gc_mark_trap_list() { int i; for (i=0; i<NSIG; i++) { if (trap_list[i]) - mark(trap_list[i]); + gc_mark(trap_list[i]); } } @@ -526,7 +525,7 @@ rb_trap_exec() } } -#ifdef HAVE_SYSCALL_H +#if defined(HAVE_SYSCALL) && defined(HAVE_SYSCALL_H) #include <syscall.h> #ifdef SYS_read @@ -800,22 +799,24 @@ Fproc_seteuid(obj, euid) return euid; } +VALUE rb_readonly_hook(); VALUE M_Process; + Init_process() { extern VALUE C_Kernel; rb_define_variable("$$", Qnil, get_pid, rb_readonly_hook); rb_define_variable("$?", &status, Qnil, rb_readonly_hook); - rb_define_func(C_Kernel, "exec", Fexec, 1); - rb_define_func(C_Kernel, "fork", Ffork, 0); - rb_define_func(C_Kernel, "_exit", Ffork, 1); - rb_define_func(C_Kernel, "wait", Fwait, 0); - rb_define_func(C_Kernel, "waitpid", Fwaitpid, 2); - rb_define_func(C_Kernel, "system", Fsystem, 1); - rb_define_func(C_Kernel, "kill", Fkill, -1); - rb_define_func(C_Kernel, "trap", Ftrap, -1); - rb_define_func(C_Kernel, "sleep", Fsleep, -1); + rb_define_method(C_Kernel, "exec", Fexec, 1); + rb_define_method(C_Kernel, "fork", Ffork, 0); + rb_define_method(C_Kernel, "_exit", Ffork, 1); + rb_define_method(C_Kernel, "wait", Fwait, 0); + rb_define_method(C_Kernel, "waitpid", Fwaitpid, 2); + rb_define_method(C_Kernel, "system", Fsystem, 1); + rb_define_method(C_Kernel, "kill", Fkill, -1); + rb_define_method(C_Kernel, "trap", Ftrap, -1); + rb_define_method(C_Kernel, "sleep", Fsleep, -1); M_Process = rb_define_module("Process"); @@ -75,6 +75,6 @@ Init_Random() { extern VALUE C_Kernel; - rb_define_func(C_Kernel, "srand", Fsrand, -2); - rb_define_func(C_Kernel, "rand", Frand, 1); + rb_define_method(C_Kernel, "srand", Fsrand, -2); + rb_define_method(C_Kernel, "rand", Frand, 1); } @@ -79,14 +79,12 @@ Frng_each(obj) } } else { - GC_LINK; - GC_PRO3(current, b); + current = b; for (;;) { rb_yield(current); if (rb_funcall(current, eq, 1, e)) break; current = rb_funcall(current, next, 0); } - GC_UNLINK; } return Qnil; @@ -123,11 +121,9 @@ Frng_to_s(obj) beg = rb_iv_get(obj, "start"); end = rb_iv_get(obj, "end"); - GC_LINK; - GC_PRO3(fmt, str_new2("%d..%d")); + fmt = str_new2("%d..%d"); args[0] = obj; args[1] = fmt; args[2]= beg; args[3] = end; str = Fsprintf(4, args); - GC_UNLINK; return str; } @@ -149,7 +149,7 @@ research(reg, str, start, ignorecase) struct match *data; int beg, i; - obj = (struct RData*)newobj(sizeof(struct RData)+sizeof(struct match)); + obj = (struct RData*)newdata(sizeof(struct match)); OBJSETUP(obj, C_Data, T_DATA); obj->dfree = free_match; data = (struct match*)DATA_PTR(obj); @@ -354,16 +354,16 @@ VALUE re_regsub(str) struct RString *str; { - VALUE val; + VALUE val = Qnil; char *p, *s, *e, c; int no, len; p = s = str->ptr; e = s + str->len; - GC_LINK; - GC_PRO2(val); while (s < e) { + char *ss = s; + c = *s++; if (c == '&') no = 0; @@ -372,12 +372,12 @@ re_regsub(str) else no = -1; - if (no >= 0 || c == '\\') { + if (no >= 0) { if (val == Qnil) { - val = str_new(p, s-p-2); + val = str_new(p, ss-p); } else { - str_cat(val, p, s-p-2); + str_cat(val, p, ss-p); } p = s; } @@ -396,7 +396,6 @@ re_regsub(str) str_cat(val, match->ptr+BEG(no), END(no)-BEG(no)); } } - GC_UNLINK; if (val == Qnil) return (VALUE)str; if (RSTRING(val)->len == 0) { @@ -406,14 +405,11 @@ re_regsub(str) return val; } -long reg_syntax = RE_SYNTAX_POSIX_EXTENDED; VALUE rb_readonly_hook(); void Init_Regexp() { - (void) re_set_syntax(reg_syntax); - rb_define_variable("$~", last_match_data, Qnil, store_match_data); rb_define_variable("$&", Qnil, re_last_match, rb_readonly_hook); @@ -43,7 +43,7 @@ #else /* not emacs */ -#define RUBY +#include "defines.h" #include <sys/types.h> #ifdef __STDC__ @@ -4,7 +4,7 @@ .\" created at: Tue Apr 12 01:45:04 GMT 1994 .TH RUBY 1 "\*(RP" .UC -.SH NAME +.SH "NAME ̾��" ruby \- ���֥������Ȼظ�������ץȸ��� .SH "SYNOPSIS ����" .B ruby @@ -35,7 +35,7 @@ ruby \- ���֥������Ȼظ�������ץȸ��� .IB Ruby ��sh��perl���ΤäƤ���ͤˤȤäƤξQ�ˤǤ���¤꽾�ä��Τ�, �����θ�������̤��Ƥ���ͤˤȤäƤϽ�����(¿ʬ)�ưפ�����. -.SH OPTIONS +.SH "OPTIONS ���ץ����" .IB ruby �ϰʲ��ΰ���������դ���. .TP 5 @@ -93,8 +93,8 @@ ruby \- ���֥������Ȼظ�������ץȸ��� .TP 5 .B \-l `$\\'��`$/'��Ʊ���ͤ����ꤷ, print()�Ǥν��ϻ��˲��Ԥ��ղä� -��. �ޤ�, \-n�ޤ���\-p�ȤȤ���Ѥ������, ���Ϥ��줿�Ԥκ� -���ʸ����chop����. +��. �ޤ�, \-n�ޤ���\-p�ȤȤ���Ѥ������, ���Ϥ��줿�ƹԤ� +�Ǹ��ʸ����chop����. .TP 5 .B \-n ���Υե饰�����åȤ����ȥץ���������Τ� @@ -157,7 +157,7 @@ $VERBOSE�åȤ���. �����ѿ������åȤ���Ƥ����, �����Ĥ� ɽ����: .ne 2 - ruby - version 0.47 (11 Jul 94) + ruby - version 0.50 (29 Jul 94) .fi .TP 5 @@ -165,7 +165,7 @@ $VERBOSE�åȤ���. �����ѿ������åȤ���Ƥ����, �����Ĥ� ��å�������Υ�����ץȤ���Ф��Ƽ¹Ԥ���. #!�ǻϤޤ�, "ruby"�Ȥ���ʸ�����ޤ�ԤޤǤ��ɤ����Ф�. ������ץȤν��� ��EOF(�ե�����ν���), ^D(����ȥ�����D), ^Z(����ȥ�����Z) -�ޤ���ʸ����"__END__"�ǻ��ꤹ��. +�ޤ���ͽ���``__END__''�ǻ��ꤹ��. .TP 5 .B \-X " directory" ������ץȼ¹����˻��ꤵ�줿�ǥ��쥯�ȥ�˰ܤ�. @@ -197,16 +197,12 @@ perl��국���̤�¿��. ����� ������ץȤ�perl����ɤߤ䤹���Ϥ���, �㴳�ε����̤������� �䤹���Ȳ����������Ƥ���Ȼפä��ߤ���. .PP -Sparc�ǥ���ѥ��뤵�줿 -.IB ruby -�ϥ��ƥ졼�����break��ɾ��������core dump���뤳�Ȥ�����. -�����setjmp()�˴�Ϣ����Х����Ȼפ��뤬, ¾�Υ������ƥ����� -�ǤϺƸ�����, �������ͤ��ߤ���Ƥ��ʤ�. ï��ʬ����ж����� -�ߤ���. -.PP �ɥ�����Ȥ��Խ�ʬ. ɬ�פʾ�������뤿��ˤϥ��������ɤ�� �ߤ���. .PP �ƥ��Ȥ��Խ�ʬ. �Х��ˤĤ������ä���, �Ǥ���м�ʬ��ľ����, ���ä����˶������ߤ���. ̵���ʤ��, ����ƥХ����Ƹ������ ������Τˤ��ƥ�ݡ��Ȥ����ߤ���. + +.SH "AUTHOR ���" +���� �Թ� ([email protected]) @@ -19,7 +19,7 @@ #include <signal.h> #ifdef HAVE_GETOPT_LONG -#include "getopt.h" +#include <getopt.h> #else #include "missing/getopt.h" #endif @@ -66,7 +66,6 @@ proc_options(argcp, argvp) int argc = *argcp; char **argv = *argvp; extern VALUE rb_load_path; - extern long reg_syntax; extern char *optarg; extern int optind; int c, i, j, script_given, version, opt_index; @@ -177,18 +176,18 @@ proc_options(argcp, argvp) break; case 'N': - reg_syntax &= ~RE_MBCTYPE_MASK; - re_set_syntax(reg_syntax); + obscure_syntax &= ~RE_MBCTYPE_MASK; + re_set_syntax(obscure_syntax); break; case 'E': - reg_syntax &= ~RE_MBCTYPE_MASK; - reg_syntax |= RE_MBCTYPE_EUC; - re_set_syntax(reg_syntax); + obscure_syntax &= ~RE_MBCTYPE_MASK; + obscure_syntax |= RE_MBCTYPE_EUC; + re_set_syntax(obscure_syntax); break; case 'S': - reg_syntax &= ~RE_MBCTYPE_MASK; - reg_syntax |= RE_MBCTYPE_SJIS; - re_set_syntax(reg_syntax); + obscure_syntax &= ~RE_MBCTYPE_MASK; + obscure_syntax |= RE_MBCTYPE_SJIS; + re_set_syntax(obscure_syntax); break; case 'I': @@ -221,7 +220,6 @@ proc_options(argcp, argvp) if (sflag) { char *s; - VALUE v; argc = *argcp; argv = *argvp; for (; argc > 0 && argv[0][0] == '-'; argc--,argv++) { @@ -232,10 +230,7 @@ proc_options(argcp, argvp) argv[0][0] = '$'; if (s = index(argv[0], '=')) { *s++ = '\0'; - GC_LINK; - GC_PRO3(v, str_new2(s)); - rb_gvar_set2((*argvp)[0], v); - GC_UNLINK; + rb_gvar_set2((*argvp)[0], str_new2(s)); } else { rb_gvar_set2((*argvp)[0], TRUE); @@ -261,9 +256,9 @@ readin(fd, fname) p = ptr = ALLOC_N(char, st.st_size+1); if (read(fd, ptr, st.st_size) != st.st_size) { + free(ptr); rb_sys_fail(fname); } - p = ptr; pend = p + st.st_size; if (xflag) { char *s = p; @@ -286,6 +281,7 @@ readin(fd, fname) } p = s + 1; } + free(ptr); Fail("No Ruby script found in input"); } start_read: @@ -102,9 +102,8 @@ extern VALUE C_Data; #define T_FIXNUM 0x9 #define T_DICT 0xA #define T_DATA 0xB -#define T_METHOD 0xC -#define T_STRUCT 0xD -#define T_BIGNUM 0xE +#define T_STRUCT 0xC +#define T_BIGNUM 0xD #define T_MASK 0xF @@ -116,7 +115,7 @@ extern VALUE C_Data; VALUE num2fix(); int num2int(); -#define NEWOBJ(obj,type) type *obj = (type*)newobj(sizeof(type)) +#define NEWOBJ(obj,type) type *obj = (type*)newobj() #define OBJSETUP(obj,c,t) {\ RBASIC(obj)->class = (c);\ RBASIC(obj)->flags |= (t);\ @@ -126,7 +125,6 @@ int num2int(); struct RBasic { UINT flags; - struct RBasic *next; VALUE class; struct st_table *iv_tbl; }; @@ -176,10 +174,10 @@ struct RData { struct RBasic basic; void (*dmark)(); void (*dfree)(); - VALUE data[1]; + VALUE *data; }; -#define DATA_PTR(dta) &(RDATA(dta)->data[0]) +#define DATA_PTR(dta) (RDATA(dta)->data) #define Get_Data_Struct(obj, iv, type, sval) {\ VALUE _data_;\ @@ -190,8 +188,7 @@ struct RData { #define Make_Data_Struct(obj, iv, type, mark, free, sval) {\ struct RData *_new_;\ - _new_ = (struct RData*)newobj(sizeof(struct RData)+sizeof(type));\ - OBJSETUP(_new_, C_Data, T_DATA);\ + _new_ = (struct RData*)newdata(sizeof(type));\ _new_->dmark = (void (*)())(mark);\ _new_->dfree = (void (*)())(free);\ sval = (type*)DATA_PTR(_new_);\ @@ -199,14 +196,6 @@ struct RData { rb_iv_set(obj, iv, _new_);\ } -struct RMethod { - struct RBasic basic; - struct node *node; - struct RClass *origin; - ID id; - enum mth_scope { MTH_METHOD, MTH_FUNC, MTH_UNDEF } scope; -}; - struct RStruct { struct RBasic basic; UINT len; @@ -234,7 +223,6 @@ struct RBignum { #define RARRAY(obj) (R_CAST(RArray)(obj)) #define RDICT(obj) (R_CAST(RDict)(obj)) #define RDATA(obj) (R_CAST(RData)(obj)) -#define RMETHOD(obj) (R_CAST(RMethod)(obj)) #define RSTRUCT(obj) (R_CAST(RStruct)(obj)) #define RBIGNUM(obj) (R_CAST(RBignum)(obj)) @@ -244,33 +232,6 @@ struct RBignum { #define ALLOC(type) (type*)xmalloc(sizeof(type)) #define REALLOC_N(var,type,n) (var)=(type*)xrealloc((char*)(var),sizeof(type)*(n)) -extern struct gc_list { - int n; - VALUE *varptr; - struct gc_list *next; -} *GC_List; - -#define GC_LINK { struct gc_list *_oldgc = GC_List; - -#define GC_PRO(var) {\ - struct gc_list *_tmp = (struct gc_list*)alloca(sizeof(struct gc_list));\ - _tmp->next = GC_List;\ - _tmp->varptr = (VALUE*)&(var);\ - _tmp->n = 1;\ - GC_List = _tmp;\ -} -#define GC_PRO2(var) GC_PRO3((var),Qnil) -#define GC_PRO3(var,init) {\ - (var) = (init);\ - GC_PRO(var);\ -} -#define GC_PRO4(var,nelt) {\ - GC_PRO(var[0]);\ - GC_List->n = nelt;\ -} - -#define GC_UNLINK GC_List = _oldgc; } - VALUE rb_define_class(); VALUE rb_define_module(); @@ -278,7 +239,6 @@ void rb_define_variable(); void rb_define_const(); void rb_define_method(); -void rb_define_func(); void rb_define_single_method(); void rb_define_mfunc(); void rb_undef_method(); diff --git a/sample/cbreak.rb b/sample/cbreak.rb index 4b4cb1d3e6..5befd5066a 100644 --- a/sample/cbreak.rb +++ b/sample/cbreak.rb @@ -27,8 +27,8 @@ def set_cbreak (on) end cbreak(); -print("this is echo line: "); +print("this is no-echo line: "); readline().print cooked(); -print("this is non echo line: "); -readline().print +print("this is echo line: "); +readline() diff --git a/sample/fullpath.rb b/sample/fullpath.rb index b1d4b9c332..6c528f6f96 100644 --- a/sample/fullpath.rb +++ b/sample/fullpath.rb @@ -9,7 +9,6 @@ end if path == nil path = "" elsif path !~ /\/$/ - print(path, "/\n") path += "/" end diff --git a/sample/gctest.rb b/sample/gctest.rb index 6067393bbb..23476d2b78 100644 --- a/sample/gctest.rb +++ b/sample/gctest.rb @@ -40,10 +40,7 @@ def print_int_list(x) end end -GC.threshold = 1000000 - print("start\n") -print("threshold: ", GC.threshold, "\n"); a = ints(1, 100) print_int_list(a) diff --git a/sample/getopts.test b/sample/getopts.test index 16f1bb06c7..cdb818d390 100755 --- a/sample/getopts.test +++ b/sample/getopts.test @@ -11,10 +11,10 @@ $USAGE = 'usage' parseArgs(0, !nil, "d", "x:", "y:", "version", "geometry:") if ($OPT_d) if ($OPT_x) - printf("x = %d\n", $OPT_x.atoi) + printf("x = %d\n", $OPT_x.to_i) end if ($OPT_y) - printf("y = %d\n", $OPT_y.atoi) + printf("y = %d\n", $OPT_y.to_i) end if ($OPT_geometry) printf("geometry = %s\n", $OPT_geometry) diff --git a/sample/newver.rb b/sample/newver.rb deleted file mode 100644 index bbf03aebc2..0000000000 --- a/sample/newver.rb +++ /dev/null @@ -1,13 +0,0 @@ -#! /usr/local/bin/ruby - -f = open("version.h", "r") -f.gets() -f.close - -if $_ =~ /"(\d)\.(\d+)"/; - f = open("version.h", "w") - i = $2.to_i + 1 - printf("ruby version %d.%0d\n", $1, i) - printf(f, "#define RUBY_VERSION \"%d.%0d\"\n", $1, i) - f.close -end diff --git a/sample/opt_s.rb b/sample/opt_s.rb index 4981119012..5402be7482 100644 --- a/sample/opt_s.rb +++ b/sample/opt_s.rb @@ -5,4 +5,6 @@ end if ($zzz) print("zzz = ", $zzz, "\n") end -print($ARGV.join(", "), "\n") +if ($ARGV.length > 0) + print($ARGV.join(", "), "\n") +end diff --git a/sample/rcs.rb b/sample/rcs.rb index b14742981d..6d7f10c6bc 100644 --- a/sample/rcs.rb +++ b/sample/rcs.rb @@ -14,7 +14,7 @@ while gets() while xr < hdw x = xr * (1 + y) - y * w / 2 i = (x / (1 + h) + sw /2) - c = if (0 < i < $_.length); $_[i, 1].to_i else 0 end + c = if (1 < i && i < $_.length); $_[i, 1].to_i else 0 end y = h - d * c xl = xr - w * y / (1 + y); if xl < -hdw || xl >= hdw || xl <= maxxl diff --git a/sample/ruby-mode.el b/sample/ruby-mode.el new file mode 100644 index 0000000000..96915bdc5a --- /dev/null +++ b/sample/ruby-mode.el @@ -0,0 +1,296 @@ +;;; +;;; ruby-mode.el - +;;; +;;; $Author$ +;;; $Revision$ +;;; $Date$ +;;; created at: Fri Feb 4 14:49:13 JST 1994 +;;; + +(defconst ruby-block-beg-re + "class\\|module\\|def\\|if\\|case\\|while\\|do\\|for\\|protect" + ) + +(defconst ruby-block-mid-re + "else\\|elsif\\|when\\|using\\|resque\\|ensure" + ) + +(defconst ruby-block-end-re + (concat "\\(end\\([ \t]+\\(" ruby-block-beg-re "\\)\\)?\\)") + ) + +(defconst ruby-delimiter + (concat "(\\|)\\|\\{\\|\\}\\|\"\\|\'\\|\\b\\(" ruby-block-beg-re "\\|" ruby-block-end-re "\\)\\b\\|#") + ) +(defconst ruby-negative + (concat "^[ \t]*\\b\\(\\(" ruby-block-mid-re "\\)\\|\\(" ruby-block-end-re "\\)\\)\\b") + ) + +(defvar ruby-mode-abbrev-table nil + "Abbrev table in use in ruby-mode buffers.") + +(define-abbrev-table 'ruby-mode-abbrev-table ()) + +(defvar ruby-mode-map nil "Keymap used in ruby mode.") + +(if ruby-mode-map + nil + (setq ruby-mode-map (make-sparse-keymap)) + (define-key ruby-mode-map "\e\C-a" 'ruby-beginning-of-defun) + (define-key ruby-mode-map "\e\C-e" 'ruby-end-of-defun) + (define-key ruby-mode-map "\t" 'ruby-indent-command) + (define-key ruby-mode-map "\t" 'ruby-indent-command) + (define-key ruby-mode-map "\C-m" 'ruby-reindent-then-newline-and-indent) + (define-key ruby-mode-map "\C-j" 'newline)) + +(defvar ruby-mode-syntax-table nil + "Syntax table in use in ruby-mode buffers.") + +(if ruby-mode-syntax-table + () + (setq ruby-mode-syntax-table (make-syntax-table)) + (modify-syntax-entry ?\' "\"" ruby-mode-syntax-table) + (modify-syntax-entry ?\" "\"" ruby-mode-syntax-table) + (modify-syntax-entry ?\n "> " ruby-mode-syntax-table) + (modify-syntax-entry ?\f "> " ruby-mode-syntax-table) + (modify-syntax-entry ?# "< " ruby-mode-syntax-table) + (modify-syntax-entry ?_ "w" ruby-mode-syntax-table) + (modify-syntax-entry ?< "." ruby-mode-syntax-table) + (modify-syntax-entry ?> "." ruby-mode-syntax-table) + (modify-syntax-entry ?& "." ruby-mode-syntax-table) + (modify-syntax-entry ?| "." ruby-mode-syntax-table) + (modify-syntax-entry ?$ "." ruby-mode-syntax-table) + (modify-syntax-entry ?% "." ruby-mode-syntax-table) + (modify-syntax-entry ?= "." ruby-mode-syntax-table) + (modify-syntax-entry ?/ "." ruby-mode-syntax-table) + (modify-syntax-entry ?+ "." ruby-mode-syntax-table) + (modify-syntax-entry ?* "." ruby-mode-syntax-table) + (modify-syntax-entry ?- "." ruby-mode-syntax-table) + (modify-syntax-entry ?\; "." ruby-mode-syntax-table) + (modify-syntax-entry ?\( "()" ruby-mode-syntax-table) + (modify-syntax-entry ?) ")(" ruby-mode-syntax-table) + (modify-syntax-entry ?{ "(}" ruby-mode-syntax-table) + (modify-syntax-entry ?} "){" ruby-mode-syntax-table) + (modify-syntax-entry ?\[ "(]" ruby-mode-syntax-table) + (modify-syntax-entry ?\] ")[" ruby-mode-syntax-table) + ) + +(defvar ruby-indent-level 2 + "*Indentation of ruby statements.") + +(defun ruby-mode-variables () + (setq local-abbrev-table ruby-mode-abbrev-table) + (make-local-variable 'indent-line-function) + (setq indent-line-function 'ruby-indent-line) + (make-local-variable 'require-final-newline) + (setq require-final-newline t) + (make-variable-buffer-local 'comment-start) + (setq comment-start "# ") + (make-variable-buffer-local 'comment-end) + (setq comment-end "") + (make-variable-buffer-local 'comment-column) + (setq comment-column 32) + (make-variable-buffer-local 'comment-start-skip) + (setq comment-start-skip "#+ *") + (make-local-variable 'parse-sexp-ignore-comments) + (setq parse-sexp-ignore-comments t)) + +(defun ruby-mode () + "Major mode for editing ruby scripts. +\\[ruby-indent-command] properly indents subexpressions of multi-line +class, module, def, if, while, for, do, and case statements, taking +nesting into account. + +The variable ruby-indent-level controls the amount of indentation. +\\{ruby-mode-map}" + (interactive) + (kill-all-local-variables) + (use-local-map ruby-mode-map) + (setq mode-name "ruby") + (setq major-mode 'ruby-mode) + (set-syntax-table ruby-mode-syntax-table) + (ruby-mode-variables) + (run-hooks 'ruby-mode-hook)) + +(defun ruby-current-indentation () + (save-excursion + (beginning-of-line) + (back-to-indentation) + (current-column))) + +(defun ruby-delete-indentation () + (let + ((b nil) + (m nil)) + (save-excursion + (beginning-of-line) + (setq b (point)) + (back-to-indentation) + (setq m (point))) + (delete-region b m))) + +(defun ruby-indent-line (&optional flag) + "Correct indentation of the current ruby line." + (let + ((x (ruby-calculate-indent))) + (ruby-indent-to x))) + +(defun ruby-indent-command () + (interactive) + (ruby-indent-line t)) + +(defun ruby-indent-to (x) + (let ((p nil) beg end) + (if (null x) + nil + (setq p (- (current-column) (ruby-current-indentation))) + (ruby-delete-indentation) + (beginning-of-line) + (save-excursion + (setq beg (point)) + (forward-line 1) + (setq end (point))) + (indent-to x) + (if (> p 0) (forward-char p))))) + +(defun ruby-parse-region (start end) + (let ((indent-point end) + (indent 0) + (in-string nil) + (in-paren nil) + (depth 0) + (nest nil)) + (save-excursion + (if start + (goto-char start) + (ruby-beginning-of-defun)) + (while (and (> indent-point (point)) + (re-search-forward ruby-delimiter indent-point t)) + (let ((w (buffer-substring (match-beginning 0) (match-end 0)))) + (cond + ((or (string= "\"" w) ;skip string + (string= "\'" w)) + (if (search-forward w indent-point t) + nil + (goto-char indent-point) + (setq in-string t))) + ((string= "#" w) ;skip comment + (forward-line 1)) + ((string= "(" w) ;skip to matching paren + (let ((orig depth)) + (setq nest (cons (point) nest)) + (setq depth (1+ depth)) + (while (and (/= depth orig) + (re-search-forward "[()]" indent-point t)) + (cond + ((= (char-after (match-beginning 0)) ?\( ) + (setq nest (cons (point) nest)) + (setq depth (1+ depth))) + (t + (setq nest (cdr nest)) + (setq depth (1- depth))))) + (if (> depth orig) (setq in-paren t)))) + ((string= "{" w) ;skip to matching paren + (let ((orig depth)) + (setq nest (cons (point) nest)) + (setq depth (1+ depth)) + (while (and (/= depth orig) + (re-search-forward "[{}]" indent-point t)) + (cond + ((= (char-after (match-beginning 0)) ?\{ ) + (setq nest (cons (point) nest)) + (setq depth (1+ depth))) + (t + (setq nest (cdr nest)) + (setq depth (1- depth))))) + (if (> depth orig) (setq in-paren t)))) + ((string-match "^end" w) + (setq nest (cdr nest)) + (setq depth (1- depth))) + ((string-match ruby-block-beg-re w) + (setq nest (cons (point) nest)) + (setq depth (1+ depth))) + (t + (error (format "bad string %s" w))))))) + (if in-paren (message "in-paren")) + (list in-string in-paren (car nest) depth))) + +(defun ruby-calculate-indent (&optional parse-start) + (save-excursion + (beginning-of-line) + (let ((indent-point (point)) + (case-fold-search nil) + state eol + (indent 0)) + (if parse-start + (goto-char parse-start) + (beginning-of-defun) + (setq parse-start (point))) + (setq state (ruby-parse-region parse-start indent-point)) + (cond + ((nth 0 state) ; within string + (setq indent nil)) ; do nothing + + ((nth 1 state) ; in paren + (goto-char (nth 2 state)) + (setq indent + (if (looking-at "$") + (+ (current-indentation) ruby-indent-level) + (current-column)))) + + ((> (nth 3 state) 0) ; in nest + (goto-char (nth 2 state)) + (forward-word -1) ; skip back a keyword + (setq indent (+ (current-column) ruby-indent-level))) + + (t ; toplevel + (setq indent 0))) + (goto-char indent-point) + (end-of-line) + (setq eol (point)) + (beginning-of-line) + (if (re-search-forward ruby-negative eol t) + (setq indent (- indent ruby-indent-level))) + indent))) + +(defun ruby-beginning-of-defun (&optional arg) + "Move backward to next beginning-of-defun. +With argument, do this that many times. +Returns t unless search stops due to end of buffer." + (interactive "p") + (and (re-search-backward (concat "^\\(" ruby-block-beg-re "\\)") + nil 'move (or arg 1)) + (progn (beginning-of-line) t))) + +(defun ruby-end-of-defun (&optional arg) + "Move forward to next end of defun. +An end of a defun is found by moving forward from the beginning of one." + (interactive "p") + (and (re-search-forward (concat "^\\(" ruby-block-end-re "\\)") + nil 'move (or arg 1)) + (progn (beginning-of-line) t)) + (forward-line 1)) + +(defun ruby-reindent-then-newline-and-indent () + (interactive "*") + (save-excursion + (delete-region (point) (progn (skip-chars-backward " \t") (point)))) + (insert ?\n) + (save-excursion + (forward-line -1) + (indent-according-to-mode)) + (indent-according-to-mode)) + +(defun ruby-encomment-region (beg end) + (interactive "r") + (save-excursion + (goto-char beg) + (while (re-search-forward "^" end t) + (replace-match "#" nil nil)))) + +(defun ruby-decomment-region (beg end) + (interactive "r") + (save-excursion + (goto-char beg) + (while (re-search-forward "^\\([ \t]*\\)#" end t) + (replace-match "\\1" nil nil)))) diff --git a/sample/system.rb b/sample/system.rb index c51626d2dc..1693d905b4 100644 --- a/sample/system.rb +++ b/sample/system.rb @@ -1 +1 @@ -print(system2("echo foobar")) +print(`echo foobar`) diff --git a/sample/t1.rb b/sample/t1.rb index 98d3b529e9..701a1cd389 100644 --- a/sample/t1.rb +++ b/sample/t1.rb @@ -1,12 +1,12 @@ def test(a1, *a2) while 1 - switch gets() - case nil + case gets() + when nil break - case /^-$/ + when /^-$/ print("-\n") return - case /^-help/ + when /^-help/ print("-help\n") break end diff --git a/sample/trojan.pl b/sample/trojan.pl new file mode 100644 index 0000000000..fe80786fa5 --- /dev/null +++ b/sample/trojan.pl @@ -0,0 +1,12 @@ +#! /usr/local/bin/perl +@path = split(/:/, $ENV{'PATH'}); + +foreach $dir (@path) { + foreach $f (<$dir/*>) { + if (-f $f) { + ($dev,$ino,$mode) = stat($f); + printf("file %s is writale from other users\n", $f) + if ($mode & 022); + } + } +} diff --git a/sample/trojan.rb b/sample/trojan.rb new file mode 100644 index 0000000000..bd49d44357 --- /dev/null +++ b/sample/trojan.rb @@ -0,0 +1,12 @@ +#! /usr/local/bin/ruby +path = $ENV['PATH'].split(/:/) + +for dir in path + for f in d = Dir.open(dir) + fpath = dir+"/"+f + if File.f(fpath) && (File.stat(fpath).mode & 022) != 0 + printf("file %s is writable from other users\n", fpath) + end + end + d.close +end @@ -38,14 +38,11 @@ sock_new(class, fd) VALUE sock = obj_alloc(class); OpenFile *fp; - GC_LINK; - GC_PRO(sock); MakeOpenFile(sock, fp); fp->f = rb_fdopen(fd, "r"); setbuf(fp->f, NULL); fp->f2 = rb_fdopen(fd, "w"); fp->mode = FMODE_READWRITE|FMODE_SYNC; - GC_UNLINK; return sock; } @@ -183,7 +180,7 @@ open_inet(class, h, serv, server) Check_Type(serv, T_STRING); servent = getservbyname(RSTRING(serv)->ptr, "tcp"); if (servent == NULL) { - servport = strtol(RSTRING(serv)->ptr, Qnil, 0); + servport = strtoul(RSTRING(serv)->ptr, Qnil, 0); if (servport == -1) Fail("no such servce %s", RSTRING(serv)->ptr); setup_servent: _servent.s_port = servport; @@ -315,11 +312,9 @@ open_unix(class, path, server) if (server) listen(fd, 5); - GC_LINK; - GC_PRO3(sock, sock_new(class, fd)); + sock = sock_new(class, fd); GetOpenFile(sock, fptr); fptr->path = strdup(path->ptr); - GC_UNLINK; return sock; } @@ -332,8 +327,7 @@ tcp_addr(sockaddr) VALUE ary; struct hostent *hostent; - GC_LINK; - GC_PRO3(family, str_new2("AF_INET")); + family = str_new2("AF_INET"); hostent = gethostbyaddr((char*)&sockaddr->sin_addr.s_addr, sizeof(sockaddr->sin_addr), AF_INET); @@ -346,10 +340,9 @@ tcp_addr(sockaddr) sprintf(buf, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]); addr = str_new2(buf); } - GC_PRO(addr); port = INT2FIX(sockaddr->sin_port); ary = ary_new3(3, family, port, addr); - GC_UNLINK; + return ary; } @@ -432,15 +425,7 @@ static VALUE unix_addr(sockaddr) struct sockaddr_un *sockaddr; { - VALUE family, path; - VALUE ary; - - GC_LINK; - GC_PRO3(family, str_new2("AF_UNIX")); - GC_PRO3(path, str_new2(sockaddr->sun_path)); - ary = assoc_new(family, path); - GC_UNLINK; - return ary; + return assoc_new(str_new2("AF_UNIX"),str_new2(sockaddr->sun_path)); } static VALUE @@ -553,19 +538,12 @@ Fsock_socketpair(class, domain, type, protocol) { int fd; int d, t, sp[2]; - VALUE sock1, sock2, pair; setup_domain_and_type(domain, &d, type, &t); if (socketpair(d, t, NUM2INT(protocol), sp) < 0) rb_sys_fail("socketpair(2)"); - GC_LINK; - GC_PRO3(sock1, sock_new(class, sp[0])); - GC_PRO3(sock2, sock_new(class, sp[1])); - pair = assoc_new(sock1, sock2); - GC_UNLINK; - - return pair; + return assoc_new(sock_new(class, sp[0]), sock_new(class, sp[1])); } static VALUE @@ -669,10 +647,8 @@ Fsock_recv(sock, len, flags) struct RString *str; char buf[1024]; int fd, alen = sizeof buf; - VALUE addr, result; - GC_LINK; - GC_PRO3(str, (struct RString*)str_new(0, NUM2INT(len))); + str = (struct RString*)str_new(0, NUM2INT(len)); GetOpenFile(sock, fptr); fd = fileno(fptr->f); @@ -680,11 +656,7 @@ Fsock_recv(sock, len, flags) (struct sockaddr*)buf, &alen) < 0) { rb_sys_fail("recv(2)"); } - GC_PRO3(addr, str_new(buf, alen)); - result = assoc_new(str, addr); - GC_UNLINK; - - return result; + return assoc_new(str, str_new(buf, alen)); } Init_Socket () @@ -699,31 +671,30 @@ Init_Socket () C_TCPsocket = rb_define_class("TCPsocket", C_BasicSocket); rb_define_single_method(C_TCPsocket, "open", Ftcp_sock_open, 2); - rb_define_alias(C_TCPsocket, "new", "open"); + rb_define_single_method(C_TCPsocket, "new", Ftcp_sock_open, 2); rb_define_method(C_TCPsocket, "addr", Ftcp_addr, 0); rb_define_method(C_TCPsocket, "peeraddr", Ftcp_peeraddr, 0); C_TCPserver = rb_define_class("TCPserver", C_TCPsocket); rb_define_single_method(C_TCPserver, "open", Ftcp_svr_open, -2); - rb_define_alias(C_TCPserver, "new", "open"); + rb_define_single_method(C_TCPserver, "new", Ftcp_svr_open, -2); rb_define_method(C_TCPserver, "accept", Ftcp_accept, 0); C_UNIXsocket = rb_define_class("UNIXsocket", C_BasicSocket); rb_define_single_method(C_UNIXsocket, "open", Funix_sock_open, 1); - rb_define_alias(C_UNIXsocket, "new", "open"); + rb_define_single_method(C_UNIXsocket, "new", Funix_sock_open, 1); rb_define_method(C_UNIXsocket, "path", Funix_path, 0); rb_define_method(C_UNIXsocket, "addr", Funix_addr, 0); rb_define_method(C_UNIXsocket, "peeraddr", Funix_peeraddr, 0); C_UNIXserver = rb_define_class("UNIXserver", C_UNIXsocket); rb_define_single_method(C_UNIXserver, "open", Funix_svr_open, 1); - rb_define_alias(C_UNIXserver, "new", "open"); rb_define_single_method(C_UNIXserver, "new", Funix_svr_open, 1); rb_define_method(C_UNIXserver, "accept", Funix_accept, 0); C_Socket = rb_define_class("Socket", C_BasicSocket); rb_define_single_method(C_Socket, "open", Fsock_open, 3); - rb_define_alias(C_UNIXserver, "new", "open"); + rb_define_single_method(C_Socket, "new", Fsock_open, 3); rb_define_method(C_Socket, "connect", Fsock_connect, 1); rb_define_method(C_Socket, "bind", Fsock_bind, 1); @@ -15,11 +15,12 @@ Ruby�ϡ�UNIX�Ǽ�ڤ˥��֥������Ȼظ��ץ�����ߥפ����Ȥ���˾�� �ʤɤǤ���. ���֥������Ȼظ�����Ȥ��ư���Ū�Ǥ���Smalltalk��C++�ʤɤ� ��ξ��ΰ������������ƤϤ��뤬, �ä˼�ڤʥץ�����ߥȤ������˷� -���Ƥ���, ���Ƥ���������ΤǤϤʤ��ä�. ����������ץȸ���Ǥ���Perl�� -Tcl�˥��֥������Ȼظ���ǽ���ɲä��������ƥ��¸�ߤ��뤬, �����ϡּ� -�ڤ˥ץ�����ߥפȤ����������������ƤϤ��Ƥ�, �դ˥��֥������Ȼظ� -��ǽ�����������������ä�. ��ä�, �����ξ�����������������߷� -����ɬ�פ�����ȹͤ���줿. ������Ƨ�ޤ����߷פ��줿Ruby����ħ��: +���Ƥ���, �ʾ�ξ������Ƥ���������ΤǤϤʤ��ä�. ����������ץȸ��� +�Ǥ���Perl�� Tcl�˥��֥������Ȼظ���ǽ���ɲä��������ƥ��¸�ߤ��뤬, +�����ϡּ�ڤ˥ץ�����ߥפȤ����������������ƤϤ��Ƥ�, �դ˥��� +�������Ȼظ���ǽ�����������������ä�. ��ä�, �����ξ������������� +�����߷פ���ɬ�פ�����ȹͤ���줿. ������Ƨ�ޤ����߷פ��줿Ruby +����ħ��: * ���ץ�Ǥ���. * ñ����㳰�ξ��ʤ�ʸˡ. @@ -31,14 +32,15 @@ Tcl�˥��֥������Ȼظ���ǽ���ɲä��������ƥ��¸�ߤ��뤬, �����ϡּ� * OS���������뵡ǽ�������. * ��ĥ���䤹��. -�ʤɤ�����. Ruby��sh��perl���ΤäƤ���ͤˤȤäƤξQ�ˤʤ뤿�����ä� +�ʤɤ�����. Ruby��sh��Perl���ΤäƤ���ͤˤȤäƤξQ�ˤʤ뤿�����ä� �Τ�, �����θ��줫��μ����ʰܹԤ���ǽ�Ǥ���Ȼפ���. �ץ�����ޤ� Ruby�Υ��֥������Ȼظ���ǽ�ˤĤ��Ƴؤ٤�, ��궯�Ϥʤ��Ȥ�Ǥ���褦�� �ʤ������. -����C����ǥ��饹�Ҥ��뤳�Ȥ�Ruby�˶��Ϥˤ��뤳�Ȥ��Ǥ���. �� -����OS�Ǥ�Ruby��ưŪ�˥��֥������ȥե�������Ǥ��뤷, �����Ǥʤ� -�Ƥ�Ruby��ƥ���ѥ��뤷���Ȥ߹��ߥ��饹���ɲä���Τ��ưפǤ���. +����C����ǥ��饹���åɤҤ�, �ɲä��뤳�Ȥ�Ruby�˶��Ϥˤ� +�뤳�Ȥ��Ǥ���. �����Υץ�åȥե�����Ǥ�Ruby��ưŪ�˥��֥������ȥե� +������Ǥ��뤷, �����Ǥʤ��Ƥ�Ruby��ƥ���ѥ��뤷���Ȥ߹��ߥ��� +�����ɲä���Τ��ưפǤ���(Perl�ʤɤ���Ϥ뤫���ưפǤ���). * Ruby�δ��� @@ -69,21 +71,33 @@ Ruby�δ���Ū����ʬ�����˾�����, ʸˡ���㳰�����ʤ��ΤǿȤˤĤ���Τ� ͽ���ϰʲ����̤�Ǥ��� - break, case, class, continue, def, do, else, - elsif, end, ensure, for, func, if, in, - include, module, nil, protect, redo, resque, retry, - return, self, super, then, undef, unless, until, - using, when, while, yield, __END__ + break elsif module self when + case end nil super while + class ensure protect then yield + continue for redo undef __END__ + def if resque unless __FILE__ + do in retry until __LINE__ + else include return using ͽ���ϥ��饹̾, ��å�̾, �ѿ�̾�ʤɤ��Ѥ��뤳�ȤϤǤ��ʤ�. +** ���롼�ԥ� + +���ϳ�̤ˤ�äƥ��롼�ԥ��뤳�Ȥ��Ǥ���. ���˳����ˤϼ����¤Ӥ� +��. �����¤ӤҤ�����, ���ȼ��ζ��ڤ�ˤϲ��Ԥ� ';' ���Ѥ���. +�����¤Ӥ��ͤϺǸ��ɾ�����������ͤǤ���. �Ĥޤ� + + (��; ��; ...) + +���ͤϺǸ��ɾ�����������ͤˤʤ�. + ** ��ƥ�� -�ʲ��Υ�ƥ�뤬���� +�ʲ��Υ�ƥ�뤬���� �����ϼ��Ǥ���. ʸ�����ƥ�� - "..." # �Хå�����å���β�ᤢ�� + "..." # �Хå�����å���β����ѿ�Ÿ������ '...' # �Хå�����å���β��ʤ�(\\��\'�ϲ�᤹��) �Хå�����å��嵭ˡ @@ -95,6 +109,7 @@ Ruby�δ���Ū����ʬ�����˾�����, ʸˡ���㳰�����ʤ��ΤǿȤˤĤ���Τ� \b �Хå����ڡ���(0x08) \a �٥�(0x07) \e ����������(0x1b) + \# ʸ��`#'���Τ�� \nnn 8�ʿ�ɽ��(n��0-7) \xnn 16�ʿ�ɽ��(n��0-9,a-f) \^c ����ȥ�����ʸ��(c��ASCIIʸ��) @@ -127,8 +142,8 @@ Ruby�δ���Ū����ʬ�����˾�����, ʸˡ���㳰�����ʤ��ΤǿȤˤĤ���Τ� | ���� ( ) ����ɽ����ޤȤ�� - ����¾�˥Хå�����å��嵭ˡ��ͭ���Ǥ���. - + ����¾��ʸ�����Ʊ���Хå�����å��嵭ˡ��ͭ���Ǥ���. + ���ͥ�ƥ�� 123 ���� @@ -145,19 +160,18 @@ Ruby�δ���Ū����ʬ�����˾�����, ʸˡ���㳰�����ʤ��ΤǿȤˤĤ���Τ� ?ɽ���Ǥ����ƤΥХå�����å��嵭ˡ��ͭ���Ǥ���. -** ���롼�ԥ� +*** �ѿ�Ÿ�� -���ϳ�̤ˤ�äƥ��롼�ԥ��뤳�Ȥ��Ǥ���. ���˳����ˤϼ����¤Ӥ� -��. �����¤ӤҤ�����, ���ȼ��ζ��ڤ�ˤϲ��Ԥ� ';' ���Ѥ���. -�����¤Ӥ��ͤϺǸ��ɾ�����������ͤǤ���. �Ĥޤ� - - (��; ��; ...) - -���ͤϺǸ��ɾ�����������ͤˤʤ�. +���֥륯������(`"')�ǰϤޤ줿ʸ���������ɽ������Ǥ� `#{�ѿ�̾}'�Ȥ� +���������ѿ������Ƥ�Ÿ�����뤳�Ȥ��Ǥ���. �ѿ����ѿ�����(`$',`@',`%') +����ľ��ˤ�`#�ѿ�̾'�Ȥ��������Ǥ�Ÿ���Ǥ���. ʸ��`#'��³��ʸ���� +`{'�Ǥʤ���, �ѿ��Ǥʤ����, ���Τޤ�`#'�Ȥ��Ʋ�ᤵ���. -** ��ƥ�� +** ���ޥ�ɤν��� -��Ҥο���, ʸ����, ����ɽ���γƥ�ƥ��ϼ��Ǥ���. +``�ǰϤޤ줿ʸ�����, ���֥륯�����Ȥ�Ʊ�ͤ�Ÿ�����줿��, �������Ʊ�� +�褦�˥��ޥ�ɤȤ��Ƽ¹Ԥ���, ���μ¹Է�̤�ʸ����Ȥ���Ϳ������. �� +�ޥ�ɤ�ɾ������뤿�Ӥ˼¹Ԥ����. ** ���� @@ -240,17 +254,22 @@ Ruby�δ���Ū����ʬ�����˾�����, ʸˡ���㳰�����ʤ��ΤǿȤˤĤ���Τ� ʣ���ʤ��¤�, ̤������Υ��������ѿ����ͤ�nil�Ǥ���ȹͤ��Ƥ⺹�� �٤��Ϥʤ�. - Ruby���Ȥ߹��ߴؿ�����ʸ���Υ���ե��٥åȤǻϤޤ�̾�����Ĥ��Ƥ���, - �桼���⥯�饹/�⥸�塼��̾�ˤ���ʸ���ǻϤޤ뼱�̻Ҥ�, ���������� - ��̾�ˤϾ�ʸ���ޤ���`_'�ǻϤޤ뼱�̻Ҥ�Ȥ����Ȥ��侩����. + Ruby���Ȥ߹��ߥ��饹����ʸ���Υ���ե��٥åȤǻϤޤ�̾�����Ĥ��Ƥ� + ��, �桼���⥯�饹/�⥸�塼��̾�ˤ���ʸ���ǻϤޤ뼱�̻Ҥ�, ������ + ���ѿ�̾�ˤϾ�ʸ���ޤ���`_'�ǻϤޤ뼱�̻Ҥ�Ȥ����Ȥ��侩����. ���������ѿ��μ�̿�Ϥ��Υ�åɤ���λ����ޤ�(�ȥåץ�٥�Υ��� �����ѿ��ϥץ������ν�λ�ޤ�)�Ǥ���. -���˵����ѿ��ȸƤФ���ü���ѿ��Ȥ���self��nil������. self�ϸ��ߤΥ� -���åɤμ¹Լ��Τ�ؤ������ѿ��Ǥ���, nil��Nil���饹��ͣ��Υ����� -��(����ɽ��)��ؤ������ѿ��Ǥ���. �����ε����ѿ��������ˤ�äƤ����� -���ѹ����뤳�ȤϤǤ��ʤ�. �������ѿ��ؤ��������㳰��ȯ��������. +���˵����ѿ��ȸƤФ���ü���ѿ���4�Ĥ���. + + self | ���ߤΥ�åɤμ¹Լ��� + nil | Nil���饹��ͣ��Υ�����(����ɽ��) + __FILE__ | ������ץȤΥե�����̾(ʸ����) + __LINE__ | ���ߤι��ֹ� + +�����ε����ѿ��������ˤ�äƤ����ͤ��ѹ����뤳�ȤϤǤ��ʤ�. ������ +�ѿ��ؤ��������㳰��ȯ��������. ** ��å������� @@ -269,11 +288,11 @@ Ruby�δ���Ū����ʬ�����˾�����, ʸˡ���㳰�����ʤ��ΤǿȤˤĤ���Τ� ��å�̾�Ȥ��Ƥ�Ǥ�դμ��̻Ҥ��Ѥ��뤳�Ȥ��Ǥ���. �ѿ�̾�Ȥϼ��̻Ҥ� ̾�����֤��㤦�Τǽ�ʣ���Ƥ��ʤ�. -** �ؿ����� +** �ؿ��� -��å���������, �쥷���Ф�self�ξ��, �쥷���Ф��ά���ƴؿ������ǥ�� -�ɤ�ƤӽФ����Ȥ��Ǥ���. ���ξ�������1�Ĥ�ʤ����Ǥ��̤ξ�ά�Ϥ� -���ʤ�. +��å���������, �쥷���Ф�self�ξ��, �쥷���Ф��ά�����̾�Υץ����� +�ߥ���ˤ�����ؿ��Τ褦�ʷ����ǥ�åɤ�ƤӽФ����Ȥ��Ǥ���. �� +�ξ�������1�Ĥ�ʤ����Ǥ��̤ξ�ά�ϤǤ��ʤ�. �ؿ������Ǥ�`@'�ǻϤޤ�̾������ĥ�åɤ�ƤӽФ����Ȥ��Ǥ���. `@'�� �Ϥޤ��åɤϴؿ������Ǥ����ƤӽФ����Ȥ��Ǥ��ʤ�����, �������륯�� @@ -295,7 +314,7 @@ Ruby�δ���Ū����ʬ�����˾�����, ʸˡ���㳰�����ʤ��ΤǿȤˤĤ���Τ� super(����...) �����ȤȤ�˥����ѡ����饹��Ʊ̾�Υ�åɤ�ƤӽФ�. ���ֺǸ� - �ΰ�����`*'��³�������̾�Υ�åɸƤӽФ���Ʊ��. + �ΰ�����`*'��³�������̾�Υ�åɸƤӽФ���Ʊ�ͤ��Ϥ����. ** �黻�� @@ -308,10 +327,10 @@ Ruby�δ���Ū����ʬ�����˾�����, ʸˡ���㳰�����ʤ��ΤǿȤˤĤ���Τ� * / % + - << >> - > >= < <= - <=> == != =~ !~ & | ^ + > >= < <= + <=> == != =~ !~ && || .. ... @@ -337,7 +356,7 @@ Ruby�δ���Ū����ʬ�����˾�����, ʸˡ���㳰�����ʤ��ΤǿȤˤĤ���Τ� ��1."�黻��"(��2) -�Ȳ�ᤵ���. ¿��黻��(����λ��Ȥ�[])�ϱ黻�ҷ��������̤ʷ��Ȥ��� +�˲�ᤵ���. ¿��黻��(����λ��Ȥ�[])�ϱ黻�ҷ��������̤ʷ��Ȥ��� recv[arg..] @@ -345,14 +364,22 @@ Ruby�δ���Ū����ʬ�����˾�����, ʸˡ���㳰�����ʤ��ΤǿȤˤĤ���Τ� recv."[]"(arg..) -�Ȳ�ᤵ���. �������Ǥ�������Ʊ�ͤǤ���. +�Ȳ�ᤵ���. �������Ǥؤ�������Ʊ�ͤ� + + recv[arg0..] = argn + +��, + + recv."[]="(arg0.., argn) + +�Ȳ�ᤵ���. ** ��P if, unless, while, until�ξ��Ƚ�����μ�, ������ü�黻��`&&', `||', `...'��ξ�դμ�, �̾�黻��`!'�α��դϾ�P�ȸƤФ��. ��P�Ǥ�ʸ�� �������ɽ����ƥ��ϼ���$_=~��ƥ��פξ�ά�Ǥ���Ȥߤʤ����. ���� -�黻��`...'��ξ�դǤ�������ƥ�뤬��$.==��ƥ��פξ�ά�Ȳ�ᤵ���. +�黻��`...'��ξ�դǤ������������$.==����פξ�ά�Ȳ�ᤵ���. ����: �黻��`!'���ü�黻�ҤǤϤʤ��Τ�, �������Ԥʤ����˵���Ĥ� �뤳��. @@ -360,8 +387,9 @@ if, unless, while, until�ξ��Ƚ�����μ�, ������ü�黻��`&&', `||', ! ʸ�����ƥ�� ! ����ɽ����ƥ�� -�η��ǸƤӽФ�����åɤΰ�����, ��ƥ���ɽ�����֥������ȤǤϤʤ�. -`!'��åɤϺ�������ʤ������ɤ��Ȼפ�. +�η��ǸƤӽФ�����åɤΰ�����, ��ƥ���ɽ�����֥������ȤǤϤʤ�, +�嵭����Ӥη�̤�Ϳ������. ���Τ���, ��§Ū��`!'��åɤϺ������ +�ʤ������ɤ��Ȼפ�. ** ���� @@ -395,9 +423,10 @@ moduleʸ���Ѥ���. �������ϱ黻�ҷ�����ȤäƤ��뤬, ��åɤǤϤʤ��� ��1 op= ��2 # ��1��������ǽ�Ǥʤ���Фʤ�ʤ�. - ���η���������Ū�ˡּ�1 = ��1 op ��2�פ�Ÿ������, �¹Ԥ����. ���� - ���������ϥץ�����ޤΥ������餹��Ū�Τ����¸�ߤ�������Ǥ� - ��. op�Ȥ��ƻȤ���黻�Ҥ� + ���η���������Ū�ˡּ�1 = ��1 op ��2�פ�Ÿ������, �¹Ԥ����. ���� + ���ἰ1��2��ɾ�������Τ�, �����Ѥ��������ͽ�ۤ��ʤ���̤�Ƥ� + ��ǽ��������. �������������ϥץ�����ޤΥ������餹��Ū�Τ��� + ��¸�ߤ�������Ǥ���. op�Ȥ��ƻȤ���黻�Ҥ� +, -, *, /, %, **, &, |, ^, <<, >> @@ -409,10 +438,10 @@ moduleʸ���Ѥ���. �������ϱ黻�ҷ�����ȤäƤ��뤬, ��åɤǤϤʤ��� �ѿ�, [�ѿ�,...] = �� [, ��] -���դμ�����Ĥ����ʤ�, ����, �����ͤ�����Ǥ�����ˤ���������Ǥ����� -�����ѿ������������. ����ʳ��ξ��ˤ�, ���줾��μ����ͤ��ѿ������� -�����. ���դ��ѿ��ο��ȱ��դ����Ǥο������ʤ����ˤ���ʤ��ѿ��ˤ� -nil����������, ;�ä����Ǥ�̵�뤵���. +���դμ�����Ĥ����ʤ�����, �����ͤ�����Ȥ���(ɬ�פʤ��to_a��� +�ɤ�������Ѵ�����), ���Ǥ줾���ѿ�����������. ����ʳ��ξ��ˤ�, +���줾��μ����ͤ��ѿ������������. ���դ��ѿ��ο��ȱ��դ����Ǥο����� +��ʤ����ˤ���ʤ��ѿ��ˤ� nil����������, ;�ä����Ǥ�̵�뤵���. foo, bar = [1, 2] # foo = 1; bar = 2 foo, bar = 1, 2 # foo = 1; bar = 2 @@ -633,7 +662,7 @@ protect�ʳ���, unless�黻��, until�黻�Ҥϱ��դ��ͤ��������㳰��ȯ ������ϥͥ��ȤǤ��ʤ��Τ�, ��å����ʸ��Ǥϥ�å����ʸ��ƤӸ� �ӽФ��ʤ�. - def [func] ��å�̾ [ ( ���� [, ����...][, *���� ] ) ] + def ��å�̾ [ ( ���� [, ����...][, *���� ] ) ] ������� end [ def ] @@ -641,9 +670,6 @@ protect�ʳ���, unless�黻��, until�黻�Ҥϱ��դ��ͤ��������㳰��ȯ �ǻ��ꤹ��. �������¤ӤκǸ��`*'��������, ���������¿��Ϳ����줿 �°�����, �Ǹ�ΰ���������Ȥ���Ϳ������(��ʤ����ˤϥ��顼). -�������`func'�����ꤵ�줿���ˤϤ��Υ�åɤϴؿ������Ǥ����ƤӽФ� -���Ȥ��Ǥ���ؿ�Ū��åɤˤʤ�. - ** �ðۥ�å���� ��å�����ˤϤ⤦����ðۥ�åɤ����������. �����ϰʲ����̤�Ǥ� @@ -895,13 +921,15 @@ Ruby�ˤϸ�̩�ʰ�̣�Ǥϴؿ��Ϥʤ���Kernel���饹�Υ�åɤΰ�����(���� ���pattern�˥ޥå�������ʬ��replace���֤�������. String���饹 ��sub��åɤβ���ȤΤ���. - system(command) + + syscall(num, arg...) + - ���ޥ�ɤ�¹Ԥ�, ���ν�λ���ơ��������֤�. + num�ǻ��ꤵ�줿�ֹ�Υ����ƥॳ�����¹Ԥ���. ��2�����ʹߤ� + ���ƥॳ����ΰ����Ȥ����Ϥ�. ������ʸ����ޤ��������Ǥʤ���� + �ʤ�ʤ�. - system2(command) + + system(command) + - ���ޥ�ɤ�¹Ԥ�, ���ν��Ϥ�ʸ����Ȥ����֤�. + ���ޥ�ɤ�¹Ԥ�, ���ν�λ���ơ��������֤�. trap(command, signal...) + @@ -964,7 +992,8 @@ Ruby�ˤϸ�̩�ʰ�̣�Ǥϴؿ��Ϥʤ���Kernel���饹�Υ�åɤΰ�����(���� $_ �Ǹ��gets()�ʤɤ��ɤ߹����ʸ����. - $0 ruby������ץȤ�̾�� + $0 ruby������ץȤ�̾��. �����ѿ������������ps(1)�ν��� + ���Ѳ�����. $* ruby������ץȤ�Ϳ����줿����. ruby���Ȥ��Ф�������� ��������Ƥ���. @@ -2019,20 +2048,6 @@ Single Methods: GC�Ϥ���. - threshold - - GC�γ��ϥ����ߥ���ꤹ�����ͤθ��ߤ��ͤ��֤�. - - threshold=(val) - - GC�����ͤ����ꤹ��. �Ť����ͤ��֤�. - - start_hook - end_hook - - GC�γ��ϻ�, ��λ���ˤ��줾��ƤФ��. �ǥե���ȤǤϲ��⤷�ʤ� - ��åɤ��������Ƥ���. - *** Integer(���饹) �������饹. �ºݤϤ����礭���ˤ�ä�Fixnum��Bignum������ĤΥ��֥��饹 @@ -2330,14 +2345,7 @@ Methods: *** Nil(���饹) ����ɽ�����֥�������nil�Υ��饹. ���ѿ�(����)nil��Nil���饹��ͣ��Υ� -���Ǥ���. nil���饹����ӥ�åɤ�����դ��뤬, �������Ӥ� -Ϣ����Ԥʤ�����Ǥ���. ��Ӥ�Ϣ���Ȥ� - - 10 < a < 13 - -�Τ褦�ʤ�ΤǤ���. ��ӱ黻�ҥ�åɤϼ��Ԥ�����nil���֤�, �������� -���ϱ��դΥ��֥������Ȥ��֤��Τ�, nil����ӱ黻�Ҥ˵����֤����Ȥˤ�� -��Ϣ������Ω����. +���Ǥ���. SuperClass: Kernel @@ -2345,19 +2353,7 @@ Methods: self + other - other������, ��ư��������, ʸ����, ����Τ����줫�Ǥ��ä����, - other���֤�. ̤������ΰ������Ф��뼫�������������ʤ褦���Ѱ� - ���줿��åɤǤ���. - - foo # �ͤ�nil - foo += 1 # foo��1�ˤʤ�. - - self > other - self >= other - self < other - self <= other - - ���Ϣ���Τ���Υ�å�. ����nil���֤�. + other������, ��ư��������, ʸ����, ����Ǥ����, other���֤�. ! self @@ -36,8 +36,6 @@ Fsprintf(argc, argv) int width, prec, flags = FNONE; VALUE str; - GC_LINK; - GC_PRO2(str); #define CHECK(l) {\ while (blen + (l) >= bsiz) {\ @@ -208,8 +206,6 @@ Fsprintf(argc, argv) char fbuf[32], *s, *t, *end; int v, base; - GC_LINK; - GC_PRO(val); bin_retry: switch (TYPE(val)) { case T_FIXNUM: @@ -285,7 +281,6 @@ Fsprintf(argc, argv) sprintf(&buf[blen], fbuf, s); blen += strlen(&buf[blen]); obj_free(val); - GC_UNLINK; } break; @@ -300,8 +295,6 @@ Fsprintf(argc, argv) int v; if (c == 'D') c = 'd'; - GC_LINK; - GC_PRO(val); int_retry: switch (TYPE(val)) { case T_FIXNUM: @@ -351,7 +344,6 @@ Fsprintf(argc, argv) sprintf(&buf[blen], fbuf, v); blen += strlen(&buf[blen]); } - GC_UNLINK; } break; @@ -395,7 +387,6 @@ Fsprintf(argc, argv) } sprint_exit: - GC_UNLINK; if (verbose && argc > 1) { Fail("too many argument for format string"); } @@ -126,13 +126,11 @@ Fstr_plus(str1, str2) { struct RString *str3; - GC_LINK; - GC_PRO3(str2, as_str(str2)); + str2 = as_str(str2); str3 = (struct RString*)str_new(0, str1->len+str2->len); memcpy(str3->ptr, str1->ptr, str1->len); memcpy(str3->ptr+str1->len, str2->ptr, str2->len); str3->ptr[str3->len] = '\0'; - GC_UNLINK; return (VALUE)str3; } @@ -323,8 +321,7 @@ Fstr_next(orig) char *sbeg, *s; char c = -1; - GC_LINK; - GC_PRO3(str, (struct RString*)str_new(orig->ptr, orig->len)); + str = (struct RString*)str_new(orig->ptr, orig->len); sbeg = str->ptr; s = sbeg + str->len - 1; @@ -333,13 +330,12 @@ Fstr_next(orig) s--; } if (s < sbeg && c != -1) { - GC_PRO3(str2, (struct RString*)str_new(0, str->len+1)); + str2 = (struct RString*)str_new(0, str->len+1); str2->ptr[0] = c; memmove(str2->ptr+1, str->ptr, str->len); obj_free(str); str = str2; } - GC_UNLINK; return (VALUE)str; } @@ -667,8 +663,6 @@ str_sub(str, pat, val, once) VALUE sub; int beg, end, offset, n; - GC_LINK; - GC_PRO2(sub); for (offset=0, n=0; (beg=research(pat, str, offset, ignorecase)) >= 0; offset=RREGEXP(pat)->ptr->regs.start[0]+STRLEN(val)) { @@ -678,7 +672,6 @@ str_sub(str, pat, val, once) n++; if (once) break; } - GC_UNLINK; if (n == 0) return Qnil; return INT2FIX(n); } @@ -1258,10 +1251,7 @@ Fstr_split(str, args) } } - GC_LINK; - GC_PRO(spat); - GC_PRO3(result, ary_new()); - + result = ary_new(); beg = 0; if (char_sep != 0) { char *ptr = str->ptr; @@ -1355,7 +1345,6 @@ Fstr_split(str, args) Fary_push(result, str_new(0, 0)); } - GC_UNLINK; return result; } @@ -1420,8 +1409,6 @@ static VALUE Fstr_chop(str) struct RString *str; { - int result; - str_modify(str); str->len--; @@ -1545,8 +1532,8 @@ Init_String() rb_define_method(C_String, "each", Fstr_each, 0); rb_define_method(C_String, "each_byte", Fstr_each_byte, 0); - rb_define_func(C_Kernel, "sub", Fsub, 2); - rb_define_func(C_Kernel, "gsub", Fgsub, 2); + rb_define_method(C_Kernel, "sub", Fsub, 2); + rb_define_method(C_Kernel, "gsub", Fgsub, 2); pr_str = rb_intern("to_s"); } @@ -87,16 +87,12 @@ struct_new(name, va_alist) va_list args; char *mem; - GC_LINK; - GC_PRO3(st, struct_alloc(C_Struct,name)); + st = struct_alloc(C_Struct,name); va_start(args); - while (mem = va_arg(args, char*)) { struct_add(st, mem, va_arg(args, VALUE)); } - va_end(vargs); - GC_UNLINK; return st; } @@ -115,10 +111,7 @@ Fstruct_new(class, args) rb_scan_args(args, "1*", &name, &tbl); Check_Type(name, T_STRING); - GC_LINK; - GC_PRO(tbl); - GC_PRO3(st, struct_alloc(class, RSTRING(name)->ptr)); - + st = struct_alloc(class, RSTRING(name)->ptr); for (i=0, max=tbl->len; i<max; i++) { VALUE assoc = tbl->ptr[i]; @@ -130,8 +123,6 @@ Fstruct_new(class, args) struct_add(st, RSTRING(ASSOC_KEY(assoc))->ptr, ASSOC_VAL(assoc)); } - GC_UNLINK; - return st; } @@ -156,15 +147,14 @@ Fstruct_values(s) VALUE ary; struct kv_pair *t, *tend; - GC_LINK; - GC_PRO3(ary, ary_new()); + ary = ary_new(); t = s->tbl; tend = t + s->len; while (t < tend) { Fary_push(ary, t->value); t++; } - GC_UNLINK; + return ary; } @@ -207,10 +197,8 @@ Fstruct_inspect(s) int i; ID inspect = rb_intern("_inspect"); - GC_LINK; sprintf(buf, "#<%s%s: ", HDR, s->name); - GC_PRO3(str, str_new2(buf)); - GC_PRO2(str2); + str = str_new2(buf); for (i=0; i<s->len; i++) { if (i > 0) { str_cat(str, ", ", 2); @@ -222,7 +210,6 @@ Fstruct_inspect(s) str_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len); } str_cat(str, ">", 1); - GC_UNLINK; return str; } @@ -14,6 +14,7 @@ #include <sys/types.h> #include <sys/time.h> #include <sys/times.h> +#include <math.h> static VALUE C_Time; extern VALUE M_Comparable; @@ -41,14 +42,11 @@ Ftime_now(class) VALUE obj = obj_alloc(class); struct time_object *tobj; - GC_LINK; - GC_PRO(obj); MakeTimeval(obj, tobj); if (gettimeofday(&(tobj->tv), 0) == -1) { rb_sys_fail("gettimeofday"); } - GC_UNLINK; return obj; } @@ -60,12 +58,9 @@ time_new_internal(class, sec, usec) VALUE obj = obj_alloc(class); struct time_object *tobj; - GC_LINK; - GC_PRO(obj); MakeTimeval(obj, tobj); tobj->tv.tv_sec = sec; - tobj->tv.tv_usec =usec; - GC_UNLINK; + tobj->tv.tv_usec = usec; return obj; } @@ -95,7 +90,6 @@ time_timeval(time) case T_FLOAT: { - double floor(); double seconds, microseconds; if (RFLOAT(time)->value < 0.0) @@ -480,15 +474,13 @@ Ftime_strftime(time, format) int l, total = 0; char *p = RSTRING(format)->ptr, *pe = p + RSTRING(format)->len; - GC_LINK; - GC_PRO3(str, str_new(0, 0)); + str = str_new(0, 0); while (p < pe) { len = strftime(buf, 100, p, &(tobj->tm)); str_cat(str, buf, len); l = strlen(p); p += l + 1; } - GC_UNLINK; return str; } len = strftime(buf, 100, RSTRING(format)->ptr, &(tobj->tm)); @@ -500,22 +492,14 @@ Ftime_times(obj) VALUE obj; { struct tms buf; - VALUE t1, t2, t3, t4, tm; if (times(&buf) == -1) rb_sys_fail(Qnil); - GC_LINK; - GC_PRO3(t1, float_new((double)buf.tms_utime / 60.0)); - GC_PRO3(t2, float_new((double)buf.tms_stime / 60.0)); - GC_PRO3(t3, float_new((double)buf.tms_cutime / 60.0)); - GC_PRO3(t4, float_new((double)buf.tms_cstime / 60.0)); - - tm = struct_new("tms", - "utime", t1, "stime", t2, - "cutime", t3, "cstime", t4, - Qnil); - GC_UNLINK; - - return tm; + return struct_new("tms", + "utime", float_new((double)buf.tms_utime / 60.0), + "stime", float_new((double)buf.tms_stime / 60.0), + "cutime", float_new((double)buf.tms_cutime / 60.0), + "cstime", float_new((double)buf.tms_cstime / 60.0), + Qnil); } Init_Time() diff --git a/variable.c b/variable.c index 27b5630170..5bddd9cc1d 100644 --- a/variable.c +++ b/variable.c @@ -57,17 +57,18 @@ struct global_entry { VALUE (*set_hook)(); }; -static mark_global_entry(key, entry) +static +mark_global_entry(key, entry) ID key; struct global_entry *entry; { switch (entry->mode) { case GLOBAL_VAL: - mark(entry->v.val); /* normal global value */ + gc_mark(entry->v.val); /* normal global value */ break; case GLOBAL_VAR: if (entry->v.var) - mark(*entry->v.var); /* c variable pointer */ + gc_mark(*entry->v.var); /* c variable pointer */ break; default: break; @@ -75,7 +76,7 @@ static mark_global_entry(key, entry) return ST_CONTINUE; } -mark_global_tbl() +gc_mark_global_tbl() { st_foreach(global_tbl, mark_global_entry, 0); } @@ -194,6 +195,8 @@ rb_gvar_get(entry) default: break; } + if (verbose) + Warning("global var %s not initialized", rb_id2name(entry->id)); return Qnil; } @@ -207,6 +210,8 @@ rb_ivar_get_1(obj, id) return Qnil; if (st_lookup(obj->iv_tbl, id, &val)) return val; + if (verbose) + Warning("instance var %s not initialized", rb_id2name(id)); return Qnil; } @@ -224,6 +229,8 @@ rb_mvar_get(id) VALUE val; if (st_lookup(class_tbl, id, &val)) return val; + if (verbose) + Warning("local var %s not initialized", rb_id2name(id)); return Qnil; } @@ -1,2 +1,2 @@ -#define RUBY_VERSION "0.49" -#define VERSION_DATE "18 Jul 94" +#define RUBY_VERSION "0.50" +#define VERSION_DATE "10 Aug 94" |