rbartlensky / Lua-interpreter

A Lua interpreter in Rust
5 stars 2 forks source link

Global variables are now loaded from _ENV. #11

Closed rbartlensky closed 5 years ago

rbartlensky commented 5 years ago

In the Lua specification, the global variables are loaded from a global table called _ENV. Programs can overwrite this variable as well, and can read and write from/to it. There are a few changes:

ltratt commented 5 years ago

Can you benchmark a couple of programs that do simple global read/writes before/after this PR?

rbartlensky commented 5 years ago

Can you benchmark a couple of programs that do simple global read/writes before/after this PR?

I have a hunch that programs before this PR are slightly faster, but only because I implemented globals without considering _ENV. But yes, I can try to create a few programs, and benchmark the interpreter on them!

rbartlensky commented 5 years ago

I would like to merge this PR before writing any benchmarks. I am going to implement functions and loops first, and then come back to optimizing the _ENV lookups.

rbartlensky commented 5 years ago

As an extra example, _ENV is handled in the following way:

Example program:

x = 2 -- equivalent to _ENV["x"] = 2

The compiler generates the following bytecode:

LDI     1 0   # load into register 1 integer 0
LDS     2 0   # load into register 2 string 0
SetAttr 0 2 1 # _ENV is always in register 0, _ENV["x"] = 2

and the tables:

Strings: { 0 -> "x" }
Integers: { 0 -> 2 }
Floats: {}

Every LuaString has an extra field which is the index of the string in the constant table. This field will be None if the user generates strings through concatenation.

The VM only executes set/get_attr if the loaded LuaString doesn't have an index. If it does, then the attribute is looked up via the env_attrs vector.

ltratt commented 5 years ago

I guess I was expecting something more like "GLOBAL_ASSIGN 0 2" where "0" == "print" and "1" is register 1 (which, presumably, holds the value 1). However, this is something we can optimise / change later.

rbartlensky commented 5 years ago

I guess I was expecting something more like "GLOBAL_ASSIGN 0 2" where "0" == "print" and "1" is register 1 (which, presumably, holds the value 1). However, this is something we can optimise / change later.

I see what you mean. That might speed things up, and the changes should be easy to make even later on.

rbartlensky commented 5 years ago

Ready for another review!

ltratt commented 5 years ago

Please squash.

rbartlensky commented 5 years ago

Squashed!