-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvm.c
101 lines (84 loc) · 1.8 KB
/
vm.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
//
// vm.c
//
// Copyright (c) 2013 TJ Holowaychuk <tj@vision-media.ca>
//
#include "vm.h"
#include "disasm.h"
#include "object.h"
#include "opcodes.h"
#include "internal.h"
luna_object_t *
luna_eval(luna_vm_t *vm) {
luna_dump(vm);
printf("\n");
luna_instruction_t *ip = vm->main->ip;
luna_instruction_t i;
int registers[32] = {0};
for (;;) {
switch (OP(i = *ip++)) {
// LOADK
case LUNA_OP_LOADK:
printf("loadk %d\n", K(B(i)));
R((A(i))) = K(B(i));
break;
// LOADB
case LUNA_OP_LOADB:
printf("loadb %d %d %d\n", A(i), K(B(i)), C(i));
R(A(i)) = K(B(i));
if (C(i)) ip++;
break;
// ADD
case LUNA_OP_ADD:
R(A(i)) = RK(B(i)) + RK(C(i));
break;
// SUB
case LUNA_OP_SUB:
R(A(i)) = RK(B(i)) - RK(C(i));
break;
// DIV
case LUNA_OP_DIV:
R(A(i)) = RK(B(i)) / RK(C(i));
break;
// MUL
case LUNA_OP_MUL:
R(A(i)) = RK(B(i)) * RK(C(i));
break;
// MOD
case LUNA_OP_MOD:
R(A(i)) = RK(B(i)) % RK(C(i));
break;
// NEGATE
case LUNA_OP_NEGATE:
R(A(i)) = -R(B(i));
break;
// LT
case LUNA_OP_LT:
printf("lt %d %d\n", RK(B(i)), RK(C(i)));
if (RK(B(i)) < RK(C(i))) ip++;
break;
// LTE
case LUNA_OP_LTE:
printf("lte %d %d\n", RK(B(i)), RK(C(i)));
if (RK(B(i)) <= RK(C(i))) ip++;
break;
// JMP
case LUNA_OP_JMP:
printf("jmp %d\n", B(i));
ip += B(i);
break;
// HALT
case LUNA_OP_HALT:
goto end;
}
}
end:
return luna_int_new(R(0));
}
void
luna_vm_free(luna_vm_t *vm) {
free(vm->main->constants);
free(vm->main->code);
free(vm->main);
free(vm);
}