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 three 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,
        /* ... */
};

const size_t OpcodeMaxOperands = 3;

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

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, a jumps to off if a is not 0
jmpz off, a jumps to off if a 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
nop   do nothing
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: assign e, f # e = f

Or:

0: jmpz 4, a
1: jmpz 4, b
2: call c, [a]
3: store d
4: 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