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 ? ?

Calling convention (Internal)

Sample compilation

The code:

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

The code:

Int a = 30;

Compiles to:

0: assign a 30  # see questions

Questions

  • How should the compiler/virtual machine handle variable declaration?
  • What about constructors?

Clone this wiki locally