guile-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

guile/guile-lightning lightning.c


From: Marius Vollmer
Subject: guile/guile-lightning lightning.c
Date: Thu, 05 Apr 2001 17:35:02 -0700

CVSROOT:        /cvs
Module name:    guile
Changes by:     Marius Vollmer <address@hidden> 01/04/05 17:35:02

Modified files:
        guile-lightning: lightning.c 

Log message:
        * lightning.c: Lotsa intricate stuff for efficiently invoking
        arbitrary procedure objects from compiled code.

CVSWeb URLs:
http://subversions.gnu.org/cgi-bin/cvsweb/guile/guile-lightning/lightning.c.diff?r1=1.5&r2=1.6

Patches:
Index: guile/guile-lightning/lightning.c
diff -u guile/guile-lightning/lightning.c:1.5 
guile/guile-lightning/lightning.c:1.6
--- guile/guile-lightning/lightning.c:1.5       Sun Apr  1 09:11:19 2001
+++ guile/guile-lightning/lightning.c   Thu Apr  5 17:35:02 2001
@@ -43,6 +43,7 @@
 #include <libguile/values.h>
 #include <lightning.h>
 #include <dlfcn.h>
+#include <stdarg.h>
 
 #include "disassemble.h"
 
@@ -100,8 +101,9 @@
 static SCM scm_tc16_code;
 
 #define CODE_P(x)    (SCM_NIMP(x) && SCM_CELL_WORD_0(x) == scm_tc16_code)
-#define CODE_VEC(x)  (SCM_CELL_OBJECT_1(x))
+#define CODE_INSN(x) ((jit_insn *)SCM_CELL_WORD_1(x))
 #define CODE_ENV(x)  (SCM_CELL_OBJECT_2(x))
+#define CODE_VEC(x)  (SCM_CELL_OBJECT_3(x))
 
 static SCM
 code_mark (SCM obj)
@@ -133,9 +135,9 @@
   SCM_DEFER_INTS;
   SCM_NEWCELL2 (z);
   SCM_SET_CELL_WORD_0 (z, scm_tc16_code);
-  SCM_SET_CELL_OBJECT_1 (z, codevector);
+  SCM_SET_CELL_WORD_1 (z, CODEVECTOR_DATA(codevector)->start);
   SCM_SET_CELL_OBJECT_2 (z, env);
-  SCM_SET_CELL_OBJECT_3 (z, SCM_BOOL_F);
+  SCM_SET_CELL_OBJECT_3 (z, codevector);
   SCM_ALLOW_INTS;
 
   return z;
@@ -210,13 +212,256 @@
 code_apply (SCM smob, SCM args)
 {
 #define FUNC_NAME "code_apply"
-  struct codevector *c;
   SCM_VALIDATE_LIST (SCM_ARG1, args);
-  c = CODEVECTOR_DATA (CODE_VEC (smob));
-  return call_tc (c->start, scm_reverse_x (args, SCM_EOL), CODE_ENV (smob));
+  return call_tc (CODE_INSN(smob),
+                 scm_reverse_x (args, SCM_EOL),
+                 CODE_ENV (smob));
 #undef FUNC_NAME
 }
 
+static SCM
+nlistify (int n, va_list ap)
+{
+  SCM l = SCM_EOL;
+  SCM *t = &l;
+  while (--n >= 0)
+    {
+      *t = scm_cons (va_arg (ap, SCM), SCM_EOL);
+      t = SCM_CDRLOC (*t);
+    }
+  return l;
+}
+
+static SCM
+nlistify2 (int n, SCM e1, SCM e2, va_list ap)
+{
+  SCM l = nlistify (n-2, ap);
+  if (n >= 2)
+    l = scm_cons (e2, l);
+  if (n >= 1)
+    l = scm_cons (e1, l);
+  return l;
+}
+
+SCM 
+scm_invoke (SCM proc, int _n, void *retaddress,
+           SCM arg1, SCM arg2, ...)
+{
+  // We MUST not change `n' and `retaddress', they are used by the
+  // caller.
+
+  int n;
+
+  SCM_ASRTGO (SCM_NIMP (proc), badproc);
+
+  n = _n / sizeof(SCM);
+
+ tail:
+  switch (SCM_TYP7 (proc))
+    {
+    case scm_tc7_subr_2o:
+      return (SCM_SUBRF (proc) (arg1, (n > 1)? arg2 : SCM_UNDEFINED));
+    case scm_tc7_subr_2:
+      SCM_ASRTGO (n == 2, wrongnumargs);
+      return (SCM_SUBRF (proc) (arg1, arg2));
+    case scm_tc7_subr_0:
+      SCM_ASRTGO (n == 0, wrongnumargs);
+      return (SCM_SUBRF (proc) ());
+    case scm_tc7_subr_1:
+      SCM_ASRTGO (n == 1, wrongnumargs);
+      return (SCM_SUBRF (proc) (arg1));
+    case scm_tc7_subr_1o:
+      SCM_ASRTGO (n <= 1, wrongnumargs);
+      return (SCM_SUBRF (proc) ((n < 1)? SCM_UNDEFINED : arg1));
+    case scm_tc7_cxr:
+      SCM_ASRTGO (n == 1, wrongnumargs);
+      if (SCM_SUBRF (proc))
+       {
+         if (SCM_INUMP (arg1))
+           {
+             return 
+               (scm_make_real (SCM_DSUBRF (proc) ((double) SCM_INUM (arg1))));
+           }
+         SCM_ASRTGO (SCM_NIMP (arg1), floerr);
+         if (SCM_REALP (arg1))
+           {
+             return 
+               (scm_make_real (SCM_DSUBRF (proc) (SCM_REAL_VALUE (arg1))));
+           }
+#ifdef SCM_BIGDIG
+         if (SCM_BIGP (arg1))
+           return (scm_make_real (SCM_DSUBRF (proc) (scm_big2dbl (arg1))));
+#endif
+       floerr:
+         SCM_WTA_DISPATCH_1 (*SCM_SUBR_GENERIC (proc), arg1,
+                             SCM_ARG1, SCM_SYMBOL_CHARS (SCM_SNAME (proc)));
+       }
+      proc = SCM_SNAME (proc);
+      {
+       char *chrs = SCM_SYMBOL_CHARS (proc) + SCM_SYMBOL_LENGTH (proc) - 1;
+       while ('c' != *--chrs)
+         {
+           SCM_ASSERT (SCM_CONSP (arg1),
+                   arg1, SCM_ARG1, SCM_SYMBOL_CHARS (proc));
+           arg1 = ('a' == *chrs) ? SCM_CAR (arg1) : SCM_CDR (arg1);
+         }
+       return (arg1);
+      }
+    case scm_tc7_subr_3:
+      {
+       va_list ap;
+       SCM arg3;
+       SCM_ASRTGO (n == 3, wrongnumargs);
+       va_start (ap, arg2);
+       arg3 = va_arg (ap, SCM);
+       va_end (ap);
+       return (SCM_SUBRF (proc) (arg1, arg2, arg3));
+      }
+    case scm_tc7_lsubr:
+      {
+       va_list ap;
+       SCM x;
+       va_start (ap, arg2);
+       x = nlistify2 (n, arg1, arg2, ap);
+       va_end (ap);
+       return (SCM_SUBRF (proc) (x));
+      }
+    case scm_tc7_lsubr_2:
+      {
+       va_list ap;
+       SCM x;
+       SCM_ASRTGO (n >= 2, wrongnumargs);
+       va_start (ap, arg2);
+       x = nlistify (n-2, ap);
+       va_end (ap);
+       return (SCM_SUBRF (proc) (arg1, arg2, x));
+      }
+    case scm_tc7_asubr:
+      {
+       va_list ap;
+       SCM x;
+       if (n == 0)
+         return (SCM_SUBRF (proc) (SCM_UNDEFINED, SCM_UNDEFINED));
+       if (n == 1)
+         return (SCM_SUBRF (proc) (arg1, SCM_UNDEFINED));
+       x = SCM_SUBRF (proc) (arg1, arg2);
+       va_start (ap, arg2);
+       while (n > 2)
+         {
+           x = SCM_SUBRF (proc) (x, va_arg (ap, SCM));
+           n--;
+         }
+       va_end (ap);
+       return x;
+      }
+    case scm_tc7_rpsubr:
+      {
+       va_list ap;
+       SCM x;
+       if (n <= 1)
+         return (SCM_BOOL_T);
+       if (SCM_FALSEP (SCM_SUBRF (proc) (arg1, arg2)))
+         return SCM_BOOL_F;
+       if (n == 2)
+         return SCM_BOOL_T;
+       va_start (ap, arg2);
+       x = arg2;
+       while (n > 2)
+         {
+           SCM y = va_arg (ap, SCM);
+           if (SCM_FALSEP (SCM_SUBRF (proc) (x, y)))
+             {
+               va_end (ap);
+               return (SCM_BOOL_F);
+             }
+           x = y;
+           n--;
+         }
+       va_end (ap);
+       return (SCM_BOOL_T);
+      }
+    case scm_tcs_closures:
+      {
+       scm_misc_error ("invoke", 
+                       "can't invoke interpreted code"
+                       " from compiled code yet.", SCM_EOL);
+      }
+    case scm_tc7_smob:
+      {
+       if (!SCM_SMOB_APPLICABLE_P (proc))
+         goto badproc;
+       if (n == 0)
+         return (SCM_SMOB_APPLY_0 (proc));
+       else if (n == 1)
+         return (SCM_SMOB_APPLY_1 (proc, arg1));
+       else if (n == 2)
+         return (SCM_SMOB_APPLY_2 (proc, arg1, arg2));
+       else
+         {
+           va_list ap;
+           SCM x;
+           va_start (ap, arg2);
+           x = nlistify (n-2, ap);
+           va_end (ap);
+           return (SCM_SMOB_APPLY_3 (proc, arg1, arg2, x));
+         }
+      }
+    case scm_tc7_cclo:
+      {
+       /* XXX - this chickens out to scm_apply */
+       va_list ap;
+       SCM args;
+       va_start (ap, arg2);
+       args = nlistify2 (n, arg1, arg2, ap);
+       va_end (ap);
+       args = scm_cons (proc, args);
+       return scm_apply (SCM_CCLO_SUBR (proc), args, SCM_EOL);
+      }
+    case scm_tc7_pws:
+      {
+       proc = SCM_PROCEDURE (proc);
+       goto tail;
+      }
+    case scm_tcs_cons_gloc:
+      {
+       if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
+         {
+           va_list ap;
+           SCM x;
+           va_start (ap, arg2);
+           x = nlistify2 (n, arg1, arg2, ap);
+           va_end (ap);
+           return (scm_apply_generic (proc, x));
+         }
+       else if (!SCM_I_OPERATORP (proc))
+         goto badproc;
+       else
+         {
+           /* XXX - this chickens out to scm_apply */
+           va_list ap;
+           SCM args;
+           va_start (ap, arg2);
+           args = nlistify2 (n, arg1, arg2, ap);
+           va_end (ap);
+           args = scm_cons (proc, args);
+           proc = (SCM_I_ENTITYP (proc)
+                   ? SCM_ENTITY_PROCEDURE (proc)
+                   : SCM_OPERATOR_PROCEDURE (proc));
+           if (SCM_NIMP (proc))
+             return scm_apply (proc, args, SCM_EOL);
+           else
+             goto badproc;
+         }
+      }
+    wrongnumargs:
+      scm_wrong_num_args (proc);
+    default:
+    badproc:
+      scm_wrong_type_arg ("invoke", SCM_ARG1, proc);
+      return (arg1);
+    }
+}
+
 static void
 do_label_def (SCM label_hash, SCM label)
 {
@@ -314,7 +559,9 @@
 SCM_SYMBOL (sym_scm, "scm");
 SCM_SYMBOL (sym_subr, "subr");
 SCM_SYMBOL (sym_label, "label");
-SCM_SYMBOL (sym_proc, "proc");
+SCM_SYMBOL (sym_code, "code");
+SCM_SYMBOL (sym_var, "var");
+SCM_SYMBOL (sym_codetag, "codetag");
 
 static unsigned long
 imm2int (SCM imm, SCM label_hash, struct codevector *c)
@@ -344,15 +591,34 @@
                            SCM_LIST1 (imm));
          return (unsigned long)lab;
        }
-      else if (SCM_CAR (imm) == sym_proc)
+      else if (SCM_CAR (imm) == sym_code)
        {
          #define FUNC_NAME "assemble"
          SCM x = SCM_CADR (imm);
-         SCM_VALIDATE_SMOB (SCM_ARG1, x, code);
+         SCM_VALIDATE_SMOB (SCM_ARG1, x, codevector);
          c->protects = scm_cons (x, c->protects);
          return (unsigned long)CODEVECTOR_DATA(x)->start;
          #undef FUNC_NAME
        }
+      else if (SCM_CAR (imm) == sym_var)
+       {
+         #define FUNC_NAME "assemble"
+         SCM x = SCM_CADR (imm);
+         SCM_VALIDATE_VARIABLE (SCM_ARG1, x);
+         x = SCM_VARVCELL (x);
+         c->protects = scm_cons (x, c->protects);
+         return (unsigned long)SCM_CDRLOC(x);
+          #undef FUNC_NAME
+       }
+    }
+  else if (SCM_CONSP (imm) && SCM_CAR (imm) == sym_codetag)
+    {
+      return scm_tc16_code;
+    }
+  else if (SCM_STRINGP (imm))
+    {
+      c->protects = scm_cons (imm, c->protects);
+      return (unsigned long)SCM_STRING_CHARS (imm);
     }
   else if (SCM_NUMBERP (imm))
     return scm_num2ulong (imm, (char *)SCM_ARG1, "assemble");



reply via email to

[Prev in Thread] Current Thread [Next in Thread]