[uim-commit] r1883 - branches/r5rs/sigscheme

yamaken at freedesktop.org yamaken at freedesktop.org
Wed Oct 26 12:40:07 PDT 2005


Author: yamaken
Date: 2005-10-26 12:39:58 -0700 (Wed, 26 Oct 2005)
New Revision: 1883

Modified:
   branches/r5rs/sigscheme/Makefile.am
   branches/r5rs/sigscheme/datas.c
   branches/r5rs/sigscheme/io.c
   branches/r5rs/sigscheme/main.c
   branches/r5rs/sigscheme/sigscheme.c
   branches/r5rs/sigscheme/sigscheme.h
Log:
* This commit simplifies the GCC4-ready stack protection

* sigscheme/sigscheme.h
  - (SCM_GC_PROTECTED_CALL, SCM_GC_PROTECTED_CALL_VOID,
    SCM_GC_PROTECTED_CALL_INTERNAL): New macro
  - (SCM_GC_PROTECTED_FUNC_T, SCM_GC_PROTECTED_FUNC_DECL,
    SCM_GC_CALL_PROTECTED_FUNC, SCM_GC_CALL_PROTECTED_VOID_FUNC,
    SCM_GC_CALL_PROTECTED_FUNC_INTERNAL): Removed
  - (scm_gc_protect_stack): Make volatile
  - (scm_gc_ensure_uninlined_func): Removed
  - (SigScm_GC_EnsureUninlinedFunc,
    SigScm_GC_EnsureUninlinedFuncInternal): Removed
* sigscheme/datas.c
  - (scm_gc_protect_stack):
    * Moved from storage-protection.c
    * Make volatile
  - (SigScm_GC_ProtectStackInternal): Moved from storage-protection.c
  - (SigScm_GC_UnprotectStack): Unifiy SCM_GCC4_READY_GC and not
* sigscheme/sigscheme.c
  - (SigScm_Initialize_internal, Scm_eval_c_string_internal,
    SigScm_Initialize, Scm_eval_c_string): Follow the API change
* sigscheme/io.c
  - (SigScm_load_internal, SigScm_load): Follow the API change
* sigscheme/main.c
  - (repl, main): Follow the API change
* sigscheme/Makefile.am
  - (libsscm_la_SOURCES): Remove storage-protection.c


Modified: branches/r5rs/sigscheme/Makefile.am
===================================================================
--- branches/r5rs/sigscheme/Makefile.am	2005-10-26 18:45:13 UTC (rev 1882)
+++ branches/r5rs/sigscheme/Makefile.am	2005-10-26 19:39:58 UTC (rev 1883)
@@ -1,6 +1,6 @@
 noinst_LTLIBRARIES  = libsscm.la
 libsscm_la_SOURCES = \
-		datas.c storage-protection.c debug.c \
+		datas.c debug.c \
 		encoding.c error.c \
 		eval.c io.c \
 		operations.c \

Modified: branches/r5rs/sigscheme/datas.c
===================================================================
--- branches/r5rs/sigscheme/datas.c	2005-10-26 18:45:13 UTC (rev 1882)
+++ branches/r5rs/sigscheme/datas.c	2005-10-26 19:39:58 UTC (rev 1883)
@@ -167,6 +167,11 @@
 
 static jmp_buf save_regs_buf;
 ScmObj *scm_stack_start_pointer = NULL;
+#if UIM_SCM_GCC4_READY_GC
+/* See also the comment about these variables in sigscheme.h */
+ScmObj *(*volatile scm_gc_protect_stack)(ScmObj *)
+    = &SigScm_GC_ProtectStackInternal;
+#endif /* UIM_SCM_GCC4_READY_GC */
 
 /* multiple values */
 #if SCM_USE_VALUECONS
@@ -666,19 +671,39 @@
     scm_freelist = scm_new_freelist;
 }
 
-#if !SCM_GCC4_READY_GC
+#if SCM_GCC4_READY_GC
+ScmObj *SigScm_GC_ProtectStackInternal(ScmObj *designated_stack_start)
+{
+    /*
+     * &stack_start will be relocated to start of the frame of subsequent
+     * function call
+     */
+    ScmObj stack_start;
+
+    if (!designated_stack_start)
+        designated_stack_start = &stack_start;
+
+    if (!scm_stack_start_pointer)
+        scm_stack_start_pointer = designated_stack_start;
+
+    /* may intentionally be an invalidated local address */
+    return designated_stack_start;
+}
+
+#else /* SCM_GCC4_READY_GC */
+
 void SigScm_GC_ProtectStack(ScmObj *stack_start)
 {
     if (!scm_stack_start_pointer)
         scm_stack_start_pointer = stack_start;
 }
+#endif /* SCM_GCC4_READY_GC */
 
 void SigScm_GC_UnprotectStack(ScmObj *stack_start)
 {
     if (scm_stack_start_pointer == stack_start)
         scm_stack_start_pointer = NULL;
 }
-#endif /* !SCM_GCC4_READY_GC */
 
 /*===========================================================================
   Object Allocators

Modified: branches/r5rs/sigscheme/io.c
===================================================================
--- branches/r5rs/sigscheme/io.c	2005-10-26 18:45:13 UTC (rev 1882)
+++ branches/r5rs/sigscheme/io.c	2005-10-26 19:39:58 UTC (rev 1883)
@@ -90,11 +90,7 @@
 /*=======================================
   File Local Function Declarations
 =======================================*/
-#if SCM_GCC4_READY_GC
-static SCM_GC_PROTECTED_FUNC_DECL(ScmObj, SigScm_load_internal, (const char *c_filename));
-#else
 static ScmObj SigScm_load_internal(const char *c_filename);
-#endif /* SCM_GCC4_READY_GC */
 static char*  create_valid_path(const char *c_filename);
 #if SCM_USE_NONSTD_FEATURES
 static ScmObj create_loaded_str(ScmObj filename);
@@ -415,7 +411,7 @@
     ScmObj succeeded   = SCM_FALSE;
 
 #if SCM_GCC4_READY_GC
-    SCM_GC_CALL_PROTECTED_FUNC(succeeded, SigScm_load_internal, (c_filename));
+    SCM_GC_PROTECTED_CALL(succeeded, ScmObj, SigScm_load_internal, (c_filename));
 #else
     /* start protecting stack */
     SigScm_GC_ProtectStack(&stack_start);

Modified: branches/r5rs/sigscheme/main.c
===================================================================
--- branches/r5rs/sigscheme/main.c	2005-10-26 18:45:13 UTC (rev 1882)
+++ branches/r5rs/sigscheme/main.c	2005-10-26 19:39:58 UTC (rev 1883)
@@ -53,11 +53,7 @@
 /*=======================================
   File Local Function Declarations
 =======================================*/
-#if SCM_GCC4_READY_GC
-static SCM_GC_PROTECTED_FUNC_DECL(void , repl, (void));
-#else
 static void repl(void);
-#endif
 
 /*=======================================
   Function Implementations
@@ -123,7 +119,7 @@
 
     if (argc < 2) {
 #if SCM_GCC4_READY_GC
-        SCM_GC_CALL_PROTECTED_VOID_FUNC(repl, ());
+        SCM_GC_PROTECTED_CALL_VOID(repl, ());
 #else
         repl();
 #endif

Modified: branches/r5rs/sigscheme/sigscheme.c
===================================================================
--- branches/r5rs/sigscheme/sigscheme.c	2005-10-26 18:45:13 UTC (rev 1882)
+++ branches/r5rs/sigscheme/sigscheme.c	2005-10-26 19:39:58 UTC (rev 1883)
@@ -100,19 +100,9 @@
 /*=======================================
   File Local Function Declarations
 =======================================*/
-#if SCM_GCC4_READY_GC
-static SCM_GC_PROTECTED_FUNC_DECL(void, SigScm_Initialize_internal, (void));
-#else
 static void SigScm_Initialize_internal(void);
-#endif
-
 static int Scm_RegisterFunc(const char *name, ScmFuncType func, enum ScmFuncTypeCode type);
-
-#if SCM_GCC4_READY_GC
-static SCM_GC_PROTECTED_FUNC_DECL(ScmObj, Scm_eval_c_string_internal, (const char *exp));
-#else
 static ScmObj Scm_eval_c_string_internal(const char *exp);
-#endif
 
 /*=======================================
   Function Implementations
@@ -120,7 +110,7 @@
 void SigScm_Initialize(void)
 {
 #if SCM_GCC4_READY_GC
-    SCM_GC_CALL_PROTECTED_VOID_FUNC(SigScm_Initialize_internal, ());
+    SCM_GC_PROTECTED_CALL_VOID(SigScm_Initialize_internal, ());
 #else
     ScmObj stack_start = NULL;
 
@@ -416,7 +406,7 @@
     ScmObj ret         = SCM_NULL;
 
 #if SCM_GCC4_READY_GC
-    SCM_GC_CALL_PROTECTED_FUNC(ret, Scm_eval_c_string_internal, (exp));
+    SCM_GC_PROTECTED_CALL(ret, ScmObj, Scm_eval_c_string_internal, (exp));
 #else
     /* start protecting stack */
     SigScm_GC_ProtectStack(&stack_start);

Modified: branches/r5rs/sigscheme/sigscheme.h
===================================================================
--- branches/r5rs/sigscheme/sigscheme.h	2005-10-26 18:45:13 UTC (rev 1882)
+++ branches/r5rs/sigscheme/sigscheme.h	2005-10-26 19:39:58 UTC (rev 1883)
@@ -91,34 +91,31 @@
 
 #define SCM_EVAL(obj, env) (Scm_eval(obj, env))
 
+#if SCM_GCC4_READY_GC
 /*
- * Function Invocation With Stack Protection
+ * Function caller with protecting Scheme objects on stack from GC
  *
- * Users should only use SCM_GC_PROTECTED_FUNC_DECL(),
- * SCM_GC_CALL_PROTECTED_FUNC() and SCM_GC_CALL_PROTECTED_VOID_FUNC().
+ * The protection is safe against with variable reordering on a stack
+ * frame performed in some compilers as anti-stack smashing or
+ * optimization.
+ *
+ * Users should only use SCM_GC_PROTECTED_CALL() and
+ * SCM_GC_PROTECTED_CALL_VOID().
  */
-#if SCM_GCC4_READY_GC
+#define SCM_GC_PROTECTED_CALL(ret, ret_type, func, args)                     \
+    SCM_GC_PROTECTED_CALL_INTERNAL(ret = , ret_type, func, args)
 
-#define SCM_GC_PROTECTED_FUNC_T(func) SigScm_GC_ProtectedType__##func
+#define SCM_GC_PROTECTED_CALL_VOID(func, args)                               \
+    SCM_GC_PROTECTED_CALL_INTERNAL((void), void, func, args)
 
-#define SCM_GC_PROTECTED_FUNC_DECL(ret_type, func, args)                     \
-    ret_type func args SCM_NOINLINE;                                         \
-    typedef ret_type (*SCM_GC_PROTECTED_FUNC_T(func)) args
-
-#define SCM_GC_CALL_PROTECTED_FUNC(ret, func, args)                          \
-    SCM_GC_CALL_PROTECTED_FUNC_INTERNAL(ret = , func, args)
-
-#define SCM_GC_CALL_PROTECTED_VOID_FUNC(func, args)                          \
-    SCM_GC_CALL_PROTECTED_FUNC_INTERNAL((void), func, args)
-
-#define SCM_GC_CALL_PROTECTED_FUNC_INTERNAL(exp_ret, func, args)             \
+#define SCM_GC_PROTECTED_CALL_INTERNAL(exp_ret, ret_type, func, args)        \
     do {                                                                     \
-        SCM_GC_PROTECTED_FUNC_T(func) fp;                                    \
+        /* ensure that func is uninlined */                                  \
+        ret_type (*volatile fp)() = (ret_type (*)())&func;                   \
         ScmObj *stack_start;                                                 \
                                                                              \
+        if (0) exp_ret func args;  /* compile-time type check */             \
         stack_start = SigScm_GC_ProtectStack(NULL);                          \
-        fp = (SCM_GC_PROTECTED_FUNC_T(func))                                 \
-                  SigScm_GC_EnsureUninlinedFunc((ScmCFunc)&func);            \
         exp_ret (*fp)args;                                                   \
         SigScm_GC_UnprotectStack(stack_start);                               \
     } while (/* CONSTCOND */ 0)
@@ -172,14 +169,15 @@
 /*=======================================
    Variable Declarations
 =======================================*/
-/* storage-protection.c */
+/* datas.c */
 #if SCM_GCC4_READY_GC
 /*
- * For ensuring that these function calls be uninlined. Dont' access these
- * variables directly.
+ * The variable to ensure that a call of SigScm_GC_ProtectStack() is
+ * uninlined in portable way through (*f)().
+ *
+ * Don't access this variables directly. Use SCM_GC_PROTECTED_CALL*() instead.
  */
-extern ScmObj *(*scm_gc_protect_stack)(ScmObj *);
-extern ScmCFunc (*scm_gc_ensure_uninlined_func)(ScmCFunc);
+extern ScmObj *(*volatile scm_gc_protect_stack)(ScmObj *);
 #endif /* SCM_GCC4_READY_GC */
 
 /*=======================================
@@ -331,10 +329,22 @@
 
 /* datas.c */
 void   SigScm_GC_Protect(ScmObj *var);
-#if !SCM_GCC4_READY_GC
+#if SCM_GCC4_READY_GC
+/*
+ * Ordinary programs should not call these functions directly. Use
+ * SCM_GC_PROTECTED_CALL*() instead.
+ */
+#ifdef __GNUC__
+#define SigScm_GC_ProtectStack SigScm_GC_ProtectStackInternal
+#else /* __GNUC__ */
+#define SigScm_GC_ProtectStack (*scm_gc_protect_stack)
+#endif /* __GNUC__ */
+
+ScmObj *SigScm_GC_ProtectStackInternal(ScmObj *designated_stack_start) SCM_NOINLINE;
+#else /* SCM_GCC4_READY_GC */
 void   SigScm_GC_ProtectStack(ScmObj *stack_start);
+#endif /* SCM_GCC4_READY_GC */
 void   SigScm_GC_UnprotectStack(ScmObj *stack_start);
-#endif
 ScmObj Scm_NewCons(ScmObj a, ScmObj b);
 ScmObj Scm_NewInt(int val);
 ScmObj Scm_NewSymbol(char *name, ScmObj v_cell);
@@ -357,25 +367,6 @@
 #endif
 ScmObj Scm_Intern(const char *name);
 
-/* storage-protection.c */
-#if SCM_GCC4_READY_GC
-/*
- * Ordinary programs should not call these functions directly. Use
- * SCM_GC_CALL_PROTECTED_*FUNC() instead.
- */
-#ifdef __GNUC__
-#define SigScm_GC_ProtectStack SigScm_GC_ProtectStackInternal
-#define SigScm_GC_EnsureUninlinedFunc SigScm_GC_EnsureUninlinedFuncInternal
-#else /* __GNUC__ */
-#define SigScm_GC_ProtectStack (*scm_gc_protect_stack)
-#define SigScm_GC_EnsureUninlinedFunc (*scm_gc_ensure_uninlined_func)
-#endif /* __GNUC__ */
-void SigScm_GC_UnprotectStack(ScmObj *stack_start);
-
-ScmObj *SigScm_GC_ProtectStackInternal(ScmObj *designated_stack_start) SCM_NOINLINE;
-ScmCFunc SigScm_GC_EnsureUninlinedFuncInternal(ScmCFunc func) SCM_NOINLINE;
-#endif /* SCM_GCC4_READY_GC */
-
 /* eval.c */
 ScmObj ScmOp_eval(ScmObj obj, ScmObj env);
 ScmObj ScmOp_apply(ScmObj proc, ScmObj arg0, ScmObj rest, ScmEvalState *eval_state);



More information about the uim-commit mailing list