4 ms·
A bytecode interpreter has a much more basic execution environment than an uncompiled AST-driven interpreter. With a naive AST interpreter you create an object
by zwkrt 8y ago
A bytecode interpreter has a much more basic execution environment than an uncompiled AST-driven interpreter.
With a naive AST interpreter you create an object for each language construct, which has references to other AST objects in a big tree. Execution involves calling eval() on the root and recursively allowing sub-expressions to bubble up their evaluated results. So this approach is nice because execution and code look similar, but it is also bloated since you create an object for each construct which is thrown away after calling eval() and it is succeptible to stack overflow.
With a bytecode interpreter you simplify the execution environment to a list of instruction codes, an env, and a self-maintained call stack. Each op is a simple manipulation of the stack or env, with little wasted effort.
Overall, compiling to byte code is equivalent to memoizing the AST to remove recursion from evaluation. It is much more likely to be cache coherent as well.
- zwkrt 8y agoThis is what happens when you leave hitting reply until the morning. Sibling comment is much nicer than mine!