Skip to content

RFC #0001 Compiler and Virtual Machine

heuripedes edited this page Jan 6, 2012 · 9 revisions

RFC #0001 - Compiler and Virtual Machine

Execution model

The opcodes are executed and their results (if any) are stored in a stack. Temporary jumps (call, for example) will have the return address stored on the stack.

Opcodes and Operands

The opcode must carry information about itself (type), it's handler and it's operands. Opcodes are allowed to have at most two operands, of which the use will be documented soon, and will also carry some data - either a Value pointer or a signed integer. There must also be a field to indicate the operand type.

Simplified implementation proposal:

typedef void (*OpcodeHandler)(Opcode&, size_t*);

enum OperandType {
        OPERAND_NONE   = 0x00
        OPERAND_VALUE  = 0x01,
        OPERAND_NUMBER = 0x02,
        OPERAND_STACK  = 0x03
};

struct Operand {
        OperandType type;
        union {
                Value*  value;
                ssize_t number;
        } data;
};

enum OpcodeType {
        OP_NOP = 0x00,
        /* ... */
};

struct Opcode {
        OpcodeType    type;
        OpcodeHandler handler;
        Operand       operands[2];
};

Arithmetic

Opcode Operands Description
add a b a + b
sub a b a - b
mul a b a * b
div a b a / b
mod a b a % b
shr a b a << b
shl a b a >> b

Bitwise

Opcode Operands Description
bwor a b a | b
bwand a b a & b
bwxor a b a ^ b
bwnot a ~a

Logical

Most of these are not used for conditionals but for inline code like a = b == c.

Opcode Operands Description
or a b a || b
and a b a && b
not a !a
eq a b a == b
neq a b a != b
lt a b a < b
gt a b a > b
le a b a <= b
ge a b a >= b

Variable handling

Opcode Operands Description
varset a b a = b
load a pushes a's value into the stack
store a pops the stack into a

Control flow

Opcode Operands Description
jmp off jumps to off
jmpnz off pops the stack and jumps to off if the pop'd value is not 0
jmpz off pops the stack and jumps to off if the pop'd value is 0
fcall a args pushes the current address and calls a and passes args
mcall a args same as fcall, but for methods.
ret a pushes a into the stack and returns to the caller
break ? ?
continue ? ?

Misc

Opcode Operands Description
discard n discards the top n values from the stack

Calling convention (Internal)

Sample compilation

Listing #1:

if (a || b) {
        d = c(a);
}
e = f;

Compiles to:

0: or a, b     # a || b
1: jmpz 4      # leave the if
2: call c, [a] # c(a)
3: store d     # d = (return from c(a))
4: varset e, f # e = f

Or:

0: load a
1: jmpz
2: load b
3: jmpz
4: call c, [a]
5: store d
6: assign e, f

Listing #2:

Int a = 30;

Compiles to:

0: assign a 30  # see questions

Listing #4:

a = f() + 10;

Compiles to:

0: call f, []      # return value on the stack
1: add (stack), a  # stack.pop() + a
2: store a         # a = stack.pop()

Listing #5:

f(); /* returns something */

Compiles to:

0: call f, []  # calls f
1: discard 1   # discards return value

Questions

  • How should the compiler/virtual machine handle variable declaration?
  • What about constructors?
Clone this wiki locally