This is the mail archive of the guile@sourceware.cygnus.com mailing list for the Guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: librep's indirect threaded bytecode interpretter


"Jorgen 'forcer' Schaefer" <forcer@mindless.com> writes:

> I strongly recommend *not* to use java bytecode for guile.  The JVM
> is too a restricted language as that it would be worthwhile.
> It's almost impossible to optimize JVM bytecode well for the
> local requirements.

What specifically are you referring to?  What are "local
requirements"?  There are some implementation tricks that are
not available using JVM, but it does give you plenty of
possibilities for clever implementation.

> Also, it lacks useful stuff which don't make
> sense for Java, but make alot of sense for Scheme (check with
> Kawa and their problems implementing the whole Scheme standard
> ontop of the JVM).

As the author of Kawa, I know something about this.  Implementing
full tail-calls and call/cc is difficult, but it is quite clear how
if can be done in portable Java.  Full tail-calls are already
implemented; full call/cc will be implemented at some point
but at least Kawa's current user's seem to be more interested
in other features, and time is finite.

Of course there is no reason why you can't implement full call/cc by
using a native subroutine, just like Guile already does.  So I don't
see full call/cc as being relevant to the choice of using Java bytecodes
vs designing Guile-specific bytecodes.  You always have the option of
writing a bytecode interpreter for JVM that *does* support full
tail-recursion and call/cc.  Then people have a choice:
(a) If you don't need full tail-calls and call/cc (95% of applications),
generate efficient and portable bytecodes, and run everywhere.
(b) If you need full tail-calls or call/cc and portability,
use a compilation option to generate explicit call frame objects,
and run everywhere, but somewhat slower.
(c) Generate an efficient stack-based calling convention, but use
a JVM that supports tail-calls and call/cc.

Designing a Guile-specific bytecode should be compared to option (c).
Guile-specific bytecode is more compact, can in theory be faster,
but you don't have the option of Java interoperability and using
any JVM you choose.  Most importantly, using Java bytecodes
lets you re-use the Kawa compiler to generate the bytecodes.
Writing a compiler is not a trivial task, and I have spent years
improving Kawa.

One possibility to consider if you're not happy with Java bytecodes:
JVM has about 50 unassigned single-byte opcodes.  These can be used
for common Scheme operations, on a Scheme-extended Java bytecode
interpreter.  It should be easy to modify Kawa so that it can
*optionally* generate these Scheme-specific bytecodes.  Then you have
the best of both worlds: The user can choose whether to compile
Scheme-optimized bytecodes for the Guile-JVM or can compile portable
bytecodes to "run everywhere".  Almost all of the compiler and runtime
code will be common to the two modes.

Also keep in mind that Guile needs to run not only Scheme, but also
other languages, including Emacs Lisp.  Translating to Scheme source
code is possible, but clumsy.  It is near-impossible to generate
Scheme that is both readable and correct, and if you also want
efficient code forget it.  Generating to bytecode makes more
sense:  You can do it faster (faster eval/load response) and you
can generate better code.  Kawa already has a framework to compile
multiple languages, and currently supports Emacs Lisp (and a
never-finished JavaScript front-end).
-- 
	--Per Bothner
per@bothner.com   http://www.bothner.com/~per/

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]