[#26975] [proposal] ANSI style function — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp>

山本です。

56 messages 2005/09/07
[#26976] Re: [proposal] ANSI style function — Yukihiro Matsumoto <matz@...> 2005/09/07

まつもと ゆきひろです

[#26977] Re: [proposal] ANSI style function — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/09/07

山本です。

[#26978] Re: [proposal] ANSI style function — nobu@... 2005/09/07

なかだです。

[#26979] Re: [proposal] ANSI style function — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/09/07

山本です。

[#26980] Re: [proposal] ANSI style function — Yukihiro Matsumoto <matz@...> 2005/09/07

まつもと ゆきひろです

[#26983] Re: [proposal] ANSI style function — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/09/08

山本です。

[#26988] Re: [proposal] ANSI style function — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/09/08

山本です。

[#26989] Re: [proposal] ANSI style function — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/09/08

山本です。

[#26990] Re: [proposal] ANSI style function — Yukihiro Matsumoto <matz@...> 2005/09/08

まつもと ゆきひろです

[#26991] Re: [proposal] ANSI style function — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/09/08

山本です。

[#26995] Re: [proposal] ANSI style function — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/09/09

山本です。

[#26996] Re: [proposal] ANSI style function — Yukihiro Matsumoto <matz@...> 2005/09/09

まつもと ゆきひろです

[#26998] Re: [proposal] ANSI style function — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/09/09

山本です。

[#27000] Re: [proposal] ANSI style function — Takahiro Kambe <taca@...> 2005/09/09

In message <20050909220539.E1B26BB8.ocean@m2.ccsnet.ne.jp>

[#27001] Re: [proposal] ANSI style function — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/09/10

山本です。

[#27002] Re: [proposal] ANSI style function — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/09/10

山本です。

[#27003] Re: [proposal] ANSI style function — Yukihiro Matsumoto <matz@...> 2005/09/10

まつもと ゆきひろです

[#27004] Re: [proposal] ANSI style function — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/09/10

山本です。

[#27005] Re: [proposal] ANSI style function — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/09/10

山本です。

[#27006] Re: [proposal] ANSI style function — Yukihiro Matsumoto <matz@...> 2005/09/10

まつもと ゆきひろです

[#27007] Re: [proposal] ANSI style function — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/09/10

山本です。

[#27008] Re: [proposal] ANSI style function — Yukihiro Matsumoto <matz@...> 2005/09/10

まつもと ゆきひろです

[#27009] Re: [proposal] ANSI style function — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/09/10

山本です。

[#27011] Re: [proposal] ANSI style function — Yukihiro Matsumoto <matz@...> 2005/09/10

まつもと ゆきひろです

[#27013] Re: [proposal] ANSI style function — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/09/10

山本です。

[#27016] Re: [proposal] ANSI style function — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/09/11

山本です。

[#27015] Re: [proposal] ANSI style function — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/09/11

山本です。

[#26984] elimination of "extern int errno;" — Takahiro Kambe <taca@...>

こんにちは。

48 messages 2005/09/08
[#27023] sizeof(FILE) problem on DragonFly BSD — Takahiro Kambe <taca@...> 2005/09/12

In message <20050908.120716.71112483.taca@back-street.net>

[#27024] Re: sizeof(FILE) problem on DragonFly BSD — Yukihiro Matsumoto <matz@...> 2005/09/12

まつもと ゆきひろです

[#27025] Re: sizeof(FILE) problem on DragonFly BSD — Takahiro Kambe <taca@...> 2005/09/12

In message <1126489480.743964.31599.nullmailer@x31.priv.netlab.jp>

[#27027] Re: sizeof(FILE) problem on DragonFly BSD — Takahiro Kambe <taca@...> 2005/09/12

In message <20050912.104954.92585084.taca@back-street.net>

[#27029] Re: sizeof(FILE) problem on DragonFly BSD — Yukihiro Matsumoto <matz@...> 2005/09/12

まつもと ゆきひろです

[#27035] Re: sizeof(FILE) problem on DragonFly BSD — "U.Nakamura" <usa@...> 2005/09/12

こんにちは、なかむら(う)です。

[#27036] Re: sizeof(FILE) problem on DragonFly BSD — Yukihiro Matsumoto <matz@...> 2005/09/12

まつもと ゆきひろです

[#27079] ruby-1.8.3 status for release (Re: Re: sizeof(FILE) problem on DragonFly BSD) — Masayoshi Takahashi <maki@...> 2005/09/15

高橋征義です。

[#27081] Re: ruby-1.8.3 status for release (Re: Re: sizeof(FILE) problem on DragonFly BSD) — Yukihiro Matsumoto <matz@...> 2005/09/15

まつもと ゆきひろです

[#27082] Re: ruby-1.8.3 status for release — Masayoshi Takahashi <maki@...> 2005/09/15

高橋征義です。

[#27083] Re: ruby-1.8.3 status for release — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/09/15

山本です。

[#27099] Re: ruby-1.8.3 status for release — Hidetoshi NAGAI <nagai@...> 2005/09/15

永井@知能.九工大です.

[#27531] ruby/tk installation without tcl/tk (for 1.8.4) — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/10/26

山本です。

[#27619] Re: ruby/tk installation without tcl/tk (for 1.8.4) — Hidetoshi NAGAI <nagai@...> 2005/11/02

永井@知能.九工大です.

[#27139] ruby-1.8.3 status for release — Masayoshi Takahashi <maki@...>

高橋征義です。

66 messages 2005/09/18
[#27193] Re: ruby-1.8.3 status for release — TAKAHASHI Masayoshi <maki@...> 2005/09/20

高橋征義です。

[#27251] 脆弱性レポート翻訳者募集 — Yukihiro Matsumoto <matz@...>

まつもと ゆきひろです

13 messages 2005/09/21

[#27321] RubyGemsとOS platformとの関係 — Daigo Moriwaki <techml@...>

こんにちは、森脇です。

42 messages 2005/09/26
[#27327] Re: RubyGemsとOS platformとの関係 — nobuyoshi nakada <nobuyoshi.nakada@...> 2005/09/27

なかだです。

[#27330] Re: RubyGemsとOS platformとの関係 — Yukihiro Matsumoto <matz@...> 2005/09/27

まつもと ゆきひろです

[#27337] Re: RubyGems と OS platform との関係 — NISHIO Mizuho <jurader@...> 2005/09/27

西尾瑞穂 と言います。

[#27343] Re: RubyGems と OS platform との関係 — Yukihiro Matsumoto <matz@...> 2005/09/28

まつもと ゆきひろです

[#27347] Re: RubyGems と OS platform との関係 — Tanaka Akira <akr@...17n.org> 2005/09/28

In article <1127872084.608903.6359.nullmailer@x31.priv.netlab.jp>,

[#27348] Re: RubyGems と OS platform との関係 — Yukihiro Matsumoto <matz@...> 2005/09/28

まつもと ゆきひろです

[#27359] Re: RubyGems と OS platform との関係 — Daigo Moriwaki <techml@...> 2005/09/28

森脇です。

[#27364] Re: RubyGems と OS platform との関係 — akira yamada / やまだあきら <akira@...> 2005/09/30

Daigo Moriwaki wrote:

[#27365] Re: RubyGems と OS platform との関係 — Tanaka Akira <akr@...17n.org> 2005/09/30

In article <433CC31E.20802@ruby-lang.org>,

[#27367] Re: RubyGems と OS platform との関係 — akira yamada / やまだあきら <akira@...> 2005/09/30

Tanaka Akira wrote:

[#27369] Re: RubyGems と OS platform との関係 — Tanaka Akira <akr@...17n.org> 2005/10/01

In article <433D4CED.9030005@ruby-lang.org>,

[ruby-dev:27001] Re: [proposal] ANSI style function

From: "H.Yamamoto" <ocean@...2.ccsnet.ne.jp>
Date: 2005-09-10 01:56:42 UTC
List: ruby-dev #27001
山本です。

>> 数が違っても安全かというのとは少し違うのですが、
>> 
>> #include <stdio.h>
>> 
>> static void hoge(int d)
>> {
>>     printf("%d\n", d);
>> }
>> 
>> int main()
>> {
>>     void (*p)();
>ANSI C的には、ここで宣言している関数のポインタの変数の定義は正しくない
>というか、void (*p)(int); といった具合いに引数を取るなら取るで、その型
>も含めて宣言すべきです。

やっぱりそうなりますよね。C++ では削除された機能ですし、
http://david.tribble.com/text/cdiffs.htm によれば C99 でも deprecated
となったようですし・・・void * と同じく、保証された動作ならそれはそれで
便利なのかもしれないと思ったのですけど(ruby.h でのコールバック関数の型は
プロトタイプ化しておいて、variable.c 内部では引数なし関数ポインタで持つとか)

>> プロトタイプがないときの仕様を調べればいいのか・・・
>挙動不定とかかもしれません。

とりあえず variable.c から引数のない関数ポインタを追放してみたのですが、
骨がおれました。今までのように機械的に変換するわけにはいかず、関数内部の
挙動も把握する必要があったので。

http://www.ccsnet.ne.jp/~ocean/ansi/ に追加した HAVE_STRONG_PROTOTYPES を削除する
パッチ 003.diff に加えて、下のパッチでとりあえず動いているように見えます。

# 結局 union を使って K&R との差を補ったのと、コールバック関数を switch
# に切り分けた部分がオブジェクト指向的に後退してるようで気に入りませんが、
# 型安全性の面では向上した・・・のかな?もっといい方法があるかもしれません。

# なお、io.c などコールバック関数側はそのままなので、まだ警告は出ます。

$ あと、どこかで関数ポインタの比較は遅延ロードなどの関係でできないという話を
$ 聞いたので、その点はこのパッチにメリットがあるかもしれません。

Index: ruby.h
===================================================================
--- ruby.h	(revision 1)
+++ ruby.h	(working copy)
@@ -493,8 +493,8 @@
 void rb_extend_object _((VALUE,VALUE));
 
 void rb_define_variable _((const char*,VALUE*));
-void rb_define_virtual_variable _((const char*,VALUE(*)(ANYARGS),void(*)(ANYARGS)));
-void rb_define_hooked_variable _((const char*,VALUE*,VALUE(*)(ANYARGS),void(*)(ANYARGS)));
+void rb_define_virtual_variable (const char*,VALUE(*)(ID),void(*)(VALUE,ID));
+void rb_define_hooked_variable (const char*,VALUE*,VALUE(*)(ID,VALUE*),void(*)(VALUE,ID,VALUE*));
 void rb_define_readonly_variable _((const char*,VALUE*));
 void rb_define_const _((VALUE,const char*,VALUE));
 void rb_define_global_const _((const char*,VALUE));
Index: variable.c
===================================================================
--- variable.c	(revision 3)
+++ variable.c	(working copy)
@@ -284,17 +284,28 @@
 
 struct trace_var {
     int removed;
-    void (*func)();
+    void (*func)(VALUE, VALUE);
     VALUE data;
     struct trace_var *next;
 };
 
+enum globval_variable_state { GVAR_UNDEF, GVAR_VALUE, GVAR_VIRTUAL, GVAR_HOOK };
+
 struct global_variable {
-    int   counter;
-    void *data;
-    VALUE (*getter)();
-    void  (*setter)();
-    void  (*marker)();
+    int counter;
+    enum global_variable_state state;
+    union {
+	VALUE val; /* GVER_VALUE */
+	struct { /* GVER_VIRTUAL */
+	    VALUE (*getter)(ID id);
+	    void  (*setter)(VALUE val, ID id);
+	} virt;
+	struct { /* GVER_HOOK */
+	    VALUE *var;
+	    VALUE (*getter)(ID id, VALUE *var);
+	    void  (*setter)(VALUE val, ID id, VALUE *var);
+	} hook;
+    } u;
     int block_trace;
     struct trace_var *trace;
 };
@@ -304,18 +315,6 @@
     ID id;
 };
 
-static VALUE undef_getter(ID id);
-static void  undef_setter(VALUE val, ID id, void *data, struct global_variable *var);
-static void  undef_marker(void);
-
-static VALUE val_getter(ID id, VALUE val);
-static void  val_setter(VALUE val, ID id, void *data, struct global_variable *var);
-static void  val_marker(VALUE data);
-
-static VALUE var_getter(ID id, VALUE *var);
-static void  var_setter(VALUE val, ID id, VALUE *var);
-static void  var_marker(VALUE *var);
-
 struct global_entry*
 rb_global_entry(ID id)
 {
@@ -328,11 +327,7 @@
 	entry->id = id;
 	entry->var = var;
 	var->counter = 1;
-	var->data = 0;
-	var->getter = undef_getter;
-	var->setter = undef_setter;
-	var->marker = undef_marker;
-
+	var->state = GVAR_UNDEF;
 	var->block_trace = 0;
 	var->trace = 0;
 	st_add_direct(rb_global_tbl, id, (st_data_t)entry);
@@ -341,68 +336,33 @@
 }
 
 static VALUE
-undef_getter(ID id)
+hook_default_getter(ID id, VALUE *var)
 {
-    rb_warning("global variable `%s' not initialized", rb_id2name(id));
-
-    return Qnil;
+    if (!var) return Qnil;
+    return *var;
 }
 
 static void
-undef_setter(VALUE val, ID id, void *data, struct global_variable *var)
+hook_default_setter(VALUE val, ID id, VALUE *var)
 {
-    var->getter = val_getter;
-    var->setter = val_setter;
-    var->marker = val_marker;
-
-    var->data = (void*)val;
+    *var = val;
 }
 
 static void
-undef_marker(void)
+hook_readonly_setter(VALUE val, ID id, VALUE *var)
 {
+    rb_name_error(id, "%s is a read-only variable", rb_id2name(id));
 }
 
 static VALUE
-val_getter(ID id, VALUE val)
+virt_default_getter(ID id)
 {
-    return val;
+    rb_name_error(id, "%s is a write-only variable", rb_id2name(id));
 }
 
 static void
-val_setter(VALUE val, ID id, void *data, struct global_variable *var)
+virt_default_setter(VALUE val, ID id)
 {
-    var->data = (void*)val;
-}
-
-static void
-val_marker(VALUE data)
-{
-    if (data) rb_gc_mark_maybe(data);
-}
-
-static VALUE
-var_getter(ID id, VALUE *var)
-{
-    if (!var) return Qnil;
-    return *var;
-}
-
-static void
-var_setter(VALUE val, ID id, VALUE *var)
-{
-    *var = val;
-}
-
-static void
-var_marker(VALUE *var)
-{
-    if (var) rb_gc_mark_maybe(*var);
-}
-
-static void
-readonly_setter(VALUE val, ID id, void *var)
-{
     rb_name_error(id, "%s is a read-only variable", rb_id2name(id));
 }
 
@@ -412,7 +372,15 @@
     struct trace_var *trace;
     struct global_variable *var = entry->var;
 
-    (*var->marker)(var->data);
+    switch (var->state) {
+      case GVAR_VALUE:
+	rb_gc_mark_maybe(var->u.val);
+	break;
+      case GVAR_HOOK:
+	if (var->u.hook.var) rb_gc_mark_maybe(*var->u.hook.var);
+	break;
+    }
+
     trace = var->trace;
     while (trace) {
 	if (trace->data) rb_gc_mark_maybe(trace->data);
@@ -446,17 +414,17 @@
 rb_define_hooked_variable(
     const char *name,
     VALUE *var,
-    VALUE (*getter) (/* ??? */),
-    void  (*setter) (/* ??? */))
+    VALUE (*getter) (ID,VALUE*),
+    void  (*setter) (VALUE,ID,VALUE*))
 {
     struct global_variable *gvar;
     ID id = global_id(name);
 
     gvar = rb_global_entry(id)->var;
-    gvar->data = (void*)var;
-    gvar->getter = getter?getter:var_getter;
-    gvar->setter = setter?setter:var_setter;
-    gvar->marker = var_marker;
+    gvar->state = GVAR_HOOK;
+    gvar->u.hook.var = var;
+    gvar->u.hook.getter = getter?getter:hook_default_getter;
+    gvar->u.hook.setter = setter?setter:hook_default_setter;
 }
 
 void
@@ -468,18 +436,22 @@
 void
 rb_define_readonly_variable(const char *name, VALUE *var)
 {
-    rb_define_hooked_variable(name, var, 0, readonly_setter);
+    rb_define_hooked_variable(name, var, 0, hook_readonly_setter);
 }
 
 void
 rb_define_virtual_variable(
     const char *name,
-    VALUE (*getter) (/* ??? */),
-    void  (*setter) (/* ??? */))
+    VALUE (*getter) (ID),
+    void  (*setter) (VALUE,ID))
 {
-    if (!getter) getter = val_getter;
-    if (!setter) setter = readonly_setter;
-    rb_define_hooked_variable(name, 0, getter, setter);
+    struct global_variable *gvar;
+    ID id = global_id(name);
+
+    gvar = rb_global_entry(id)->var;
+    gvar->state = GVAR_VIRTUAL;
+    gvar->u.virt.getter = getter?getter:virt_default_getter;
+    gvar->u.virt.setter = setter?setter:virt_default_setter;
 }
 
 static void
@@ -616,7 +588,21 @@
 rb_gvar_get(struct global_entry *entry)
 {
     struct global_variable *var = entry->var;
-    return (*var->getter)(entry->id, var->data, var);
+
+    switch (var->state) {
+      case GVAR_UNDEF:
+	rb_warning("global variable `%s' not initialized", rb_id2name(entry->id));
+	return Qnil;
+      case GVAR_VALUE:
+        return var->u.val;
+      case GVAR_VIRTUAL:
+	return (*var->u.virt.getter)(entry->id);
+      case GVAR_HOOK:
+	return (*var->u.hook.getter)(entry->id, var->u.hook.var);
+    }
+
+    rb_bug("should not reach here");
+    return Qnil; /* dummy */
 }
 
 struct trace_data {
@@ -652,8 +638,21 @@
 
     if (rb_safe_level() >= 4)
 	rb_raise(rb_eSecurityError, "Insecure: can't change global variable value");
-    (*var->setter)(val, entry->id, var->data, var);
 
+    switch (var->state) {
+      case GVAR_UNDEF:
+	var->state = GVAR_VALUE;
+      case GVAR_VALUE:
+        var->u.val = val;
+        break;
+      case GVAR_VIRTUAL:
+	(*var->u.virt.setter)(val, entry->id);
+	break;
+      case GVAR_HOOK:
+	(*var->u.hook.setter)(val, entry->id, var->u.hook.var);
+	break;
+    }
+
     if (var->trace && !var->block_trace) {
 	var->block_trace = 1;
 	trace.trace = var->trace;
@@ -684,7 +683,7 @@
 VALUE
 rb_gvar_defined(struct global_entry *entry)
 {
-    if (entry->var->getter == undef_getter) return Qfalse;
+    if (entry->var->state == GVAR_UNDEF) return Qfalse;
     return Qtrue;
 }
 



In This Thread