For your first experiments, I suggest implementing your stack as a linked list. Each list entry ("frame") represents a function invocation, so it needs;
- a reference to the callers frame,
- a reference to the function itself,
- a program counter inside that function, and
- the table of variables of the function.
If you know all variables for each function before you invoke it, then each variable can be assigned one slot each, so every invocation for that function allocates a frame of the same size, but the frame sizes of different functions will be different.
This plan is known as a "spaghetti stack". If you want to support continuations, you need to garbage-collect the frames, instead of de-allocating them when the function invocation returns. Although a spaghetti stack is not the path to super high-performance, it's very flexible and might suit you just fine.
For your objects, "super" is a pointer to a klass object, and the method table goes in the klass object. There's no need for methods on non-klass objects; to handle what Ruby calls "singleton" methods, you allocate a separate klass object just for that one instance, whose super is the original declared class. Ruby uses flags on the klass objects to indicate which ones are singleton classes, which are modules added via "extend", and which are the original declared class.