guile-devel
[Top][All Lists]
Advanced

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

Re: guile-vm 0.3


From: Marius Vollmer
Subject: Re: guile-vm 0.3
Date: 09 Apr 2001 15:57:11 +0200
User-agent: Gnus/5.0803 (Gnus v5.8.3) Emacs/20.7

Rob Browning <address@hidden> writes:

> For the past couple of days, I've had a half-formulated idea running
> around in my head.  I've been thinking about g-wrap, lightning,
> libfcall, and libffi, and trying to figure out whether or not it might
> be possible (and both reasonbly efficient and sufficiently portable)
> to add some instructions to lightning that would allow on-the-fly
> wrapping of C interfaces.

Hmm, might be worth a try.  For what it's worth, you should be able to
use Lightning already to construct calls to C code:

     :
    (prepare 2)
    (mov r0 "foo!")
    (push r0)
    (finish (subr "gtk_button_new_with_label"))
    (retval r0)
    (prepare 1)
    (push r0)
    (finish (subr "sgtk_wrap_gtkobj"))
    (retval r0)
    ;; now a smob representing the new button is in R0
     :

What is missing is a good way to do type checking and conversion.

Anyway, I'm not sure if run-time generation of wrappers is an
advantage.  We are wrapping libraries that are batch-compiled, so why
not wrap them with another batch-compiled library?

> Further, with every call of a C-side function, the g-wrap wrappers
> carefully check their arguments, but in cases where you have something
> like this at the scheme level (presume all the functions called here
> are g-wrapped C functions):
> 
>    (let ((foo-obj (make-some-C-obj-ptr-of-type-foo x y z)))
>      (foo-frob! foo)
>      (foo-bar! foo)
>      (foo-baz! foo)
>      (foo-whatever foo)
>      foo)
> 
> there is *no* need to check the arguments to any of the function calls
> since you know from the g-wrap prototype that the "make" function can
> only return a foo ptr.

I think you want to have a real compiler for this, that does real type
inference.  In the midst of fixnum arithmetic and pair walking
optimizations it could also do some subr optimizations.  In fact, the
compiler could maybe do the complete wrapping...

> The downside is that having g-wrap generate C wrapper code is
> extremely portable, and one of these fancier solutions might be less
> portable, unless we were willing to commit to keeping the
> infrastructure working everywhere.

Yes, I would really like to have a real compiler that compiles to
machine language, and have it work everywhere.  But for the time
being, we should not make us dependent on clever hacks that do not
work everywhere.

I am quite confident that once we can demonstrate a compiler for, say,
the i386 platform, it will not be long before it gets ported to other
popular architectures and maybe at one time we can say that while we
need to keep Guile running on systems where we don't have a native
compiler, we don't need to care for performance on these systems.

However, this is all wild fantasy on my part.  We should not make a
native code compiler another `Godot'.  Do not wait for it.

[ Still, it _is_ great fun to work on a native compiler and, given GNU
  Lightning, it is not really difficult, either.  I now have a
  prototype that efficiently compiles tail-calls and inner-function,
  argument passing gotos.  It does no register allocation yet, tho,
  but that will come soon.

  Here is an example that computes the sum of all integers upto N.
  Note that there is no support for inlining of primitive operations
  yet, so this isn't particularily fast.

    (lambda-template (n)
                     (labels ((loop (i sum)
                                    (if (invoke (global <=)
                                                (local i) (local n))
                                        (goto loop
                                              (invoke (global +)
                                                      (local i) (quote 1))
                                              (invoke (global +)
                                                      (local i) (local sum)))
                                        (local sum))))
                             (goto loop (quote 1) (quote 0))))

    =>

      (beq l26 r1 4)
      (prepare 1)
      (mov r0 "some procedure")
      (pusharg r0)
      (finish (subr "scm_error_num_args_subr"))
    l26
      (mov r0 (scm 0))
      (push r0)
      (mov r0 (scm 1))
      (push r0)
      (b l27)
      (b l28)
    l27
      (ldx r0 sp 12)
      (push r0)
      (ldx r0 sp 4)
      (push r0)
      (ld r0 (var #<variable 402fd570 name: <= 
                                      binding: #<primitive-procedure <=>>))
      (mov r1 8)
      (call (code #<codevector 80baa68>))
      (mov r0 r0)
      (beq l29 r0 (scm #f))
      (ldx r0 sp 4)
      (push r0)
      (ldx r0 sp 4)
      (push r0)
      (ld r0 (var #<variable 40252878 name: + 
                                      binding: #<primitive-procedure +>>))
      (mov r1 8)
      (call (code #<codevector 80baa68>))
      (mov r0 r0)
      (stx 4 sp r0)
      (mov r0 (scm 1))
      (push r0)
      (ldx r0 sp 4)
      (push r0)
      (ld r0 (var #<variable 40252878 name: + 
                                      binding: #<primitive-procedure +>>))
      (mov r1 8)
      (call (code #<codevector 80baa68>))
      (mov r0 r0)
      (stx 0 sp r0)
      (b l27)
      (b l30)
    l29
      (ldx r0 sp 4)
      (ldx r2 sp 8)
      (add sp sp 16)
      (mov r1 4)
      (jmp r2)
    l30
      (add sp sp 8)
      (b l28)
    l28
  
  As you can see, a peephole pass is badly needed.
]



reply via email to

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