Bytecode-less pypy languages
So I've started work on my Clojure(lisp) in pypy interpreter again. This time I've decided to take a very materialistic approach to the design. As such my interpreter does not run off of bytecode, instead it directly interprets the Clojure structures, truely treating data as code. The idea is that every object in the system must have a evauate() method, and optionally a invoke(args) method. These methods are implemented as follows: most objects return themselves when evalute() is run def evaulates to itself, and when invoked, creates a named var that is bound to the 2nd form. E.g. (def foo 1) creates a var named foo that points to IntObj(1) user defined functions create local bindings, and then invoke their contents symbols search local bindings and global defs and then return the result through evaluate() lists evaluate all their contents, and then invoke the first item passing it the rest of the list as arguments With this simple approach, I've been able to implement many of the clojure concepts with just a few lines of code. It really works well. Here is my question. When I get a full program written, I'll have hundreds of objects each with evaluate() and invoke() all will be immutable, but there really isn't any sort of loop. We can implement loops via recur: (def (fn (x) (if (< x 100) (recur (inc x)) x))) But that's about the only loop in the interpreter. So I know in "normal" jits you would "greenlight" the instruction pointer of the byte code interpreter. Will PyPy not be happy with a lack of an instruction pointer? If I flag every single class as immutable, will it be able to still a decent jit? I guess, what I'm asking is when do green and red variables need to be defined, is it ever okay to not define them? Will the jit even work? Thank you for your time, Timothy -- “One of the main causes of the fall of the Roman Empire was that–lacking zero–they had no way to indicate successful termination of their C programs.” (Robert Firth)
On Wed, Nov 23, 2011 at 1:18 PM, Timothy Baldridge <tbaldridge@gmail.com> wrote:
So I've started work on my Clojure(lisp) in pypy interpreter again. This time I've decided to take a very materialistic approach to the design. As such my interpreter does not run off of bytecode, instead it directly interprets the Clojure structures, truely treating data as code. The idea is that every object in the system must have a evauate() method, and optionally a invoke(args) method. These methods are implemented as follows:
Nice.
most objects return themselves when evalute() is run def evaulates to itself, and when invoked, creates a named var that is bound to the 2nd form. E.g. (def foo 1) creates a var named foo that points to IntObj(1) user defined functions create local bindings, and then invoke their contents symbols search local bindings and global defs and then return the result through evaluate() lists evaluate all their contents, and then invoke the first item passing it the rest of the list as arguments
With this simple approach, I've been able to implement many of the clojure concepts with just a few lines of code. It really works well.
Here is my question. When I get a full program written, I'll have hundreds of objects each with evaluate() and invoke() all will be immutable, but there really isn't any sort of loop. We can implement loops via recur:
(def (fn (x) (if (< x 100) (recur (inc x)) x)))
But that's about the only loop in the interpreter.
So I know in "normal" jits you would "greenlight" the instruction pointer of the byte code interpreter. Will PyPy not be happy with a lack of an instruction pointer? If I flag every single class as immutable, will it be able to still a decent jit? I guess, what I'm asking is when do green and red variables need to be defined, is it ever okay to not define them? Will the jit even work?
IIRC armin wanted to try the jit with the javascript interpreter, that a long time ago interpreted the AST directly. But we never end up doing this, but I think it is a great idea for clojure and specially for simple languages were you don't want to waste time implementing a bytecode vm. -- Leonardo Santagada
On 11/23/2011 04:18 PM, Timothy Baldridge wrote:
So I've started work on my Clojure(lisp) in pypy interpreter again. This time I've decided to take a very materialistic approach to the design. As such my interpreter does not run off of bytecode, instead it directly interprets the Clojure structures, truely treating data as code. The idea is that every object in the system must have a evauate() method, and optionally a invoke(args) method. These methods are implemented as follows:
most objects return themselves when evalute() is run def evaulates to itself, and when invoked, creates a named var that is bound to the 2nd form. E.g. (def foo 1) creates a var named foo that points to IntObj(1) user defined functions create local bindings, and then invoke their contents symbols search local bindings and global defs and then return the result through evaluate() lists evaluate all their contents, and then invoke the first item passing it the rest of the list as arguments
With this simple approach, I've been able to implement many of the clojure concepts with just a few lines of code. It really works well.
Here is my question. When I get a full program written, I'll have hundreds of objects each with evaluate() and invoke() all will be immutable, but there really isn't any sort of loop. We can implement loops via recur:
(def (fn (x) (if (< x 100) (recur (inc x)) x)))
But that's about the only loop in the interpreter.
So I know in "normal" jits you would "greenlight" the instruction pointer of the byte code interpreter. Will PyPy not be happy with a lack of an instruction pointer? If I flag every single class as immutable, will it be able to still a decent jit? I guess, what I'm asking is when do green and red variables need to be defined, is it ever okay to not define them? Will the jit even work?
There is no deep reason why the JIT won't work. You might have to have one or two small hacks in the main interpreter loop for the JIT, but should not be too annoying. In fact, the Prolog interpreter in RPython works quite similarly. Cheers, Carl Friedrich
participants (3)
-
Carl Friedrich Bolz
-
Leonardo Santagada
-
Timothy Baldridge