summaryrefslogtreecommitdiff
path: root/src/lvm.js
blob: 7a65d740a4b578d90a6e7d097a2ef7fdfc5bf09b (plain)
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/*jshint esversion: 6 */
"use strict";

const BytecodeParser = require("./lundump.js");
const OC             = require('./lopcodes.js');

class LuaVM {

    constructor(L) {
        this.L = L;
    }

    RA(base, a) {
       return base + a;
    }

    RB(base, opcode, b) {
       return base + b;
    }

    RC(base, c) {
       return base + c;
    }

    RKB(base, k, b) {
        return OC.ISK(b) ? k[OC.INDEXK(b)] : base + b;
    }

    RKC(base, k, c) {
        return OC.ISK(c) ? k[OC.INDEXK(c)] : base + c;
    }

    execute() {
        let L = this.L;
        let ci = L.ci[this.L.ciOff];

        newframe:
        for (;;) {
            var cl = L.stack[ci.func];
            let k = cl.p.k;
            let base = ci.base;

            let i = ci.savedpc[ci.pcOff++];
            let ra = this.RA(base, i.A);

            console.log(OC.OpCodes[i.opcode]);
            switch (OC.OpCodes[i.opcode]) {
                case "OP_MOVE":
                    L.stack[ra] = RB(base, i.opcode, i.B);
                    break;
                case "OP_LOADK":
                    L.stack[ra] = k[i.Bx];
                    break;
                case "OP_LOADKX":
                    break;
                case "OP_LOADBOOL":
                    break;
                case "OP_LOADNIL":
                    break;
                case "OP_GETUPVAL":
                    break;
                case "OP_GETTABUP":
                    break;
                case "OP_GETTABLE":
                    break;
                case "OP_SETTABUP":
                    break;
                case "OP_SETUPVAL":
                    break;
                case "OP_SETTABLE":
                    break;
                case "OP_NEWTABLE":
                    break;
                case "OP_SELF":
                    break;
                case "OP_ADD":
                    break;
                case "OP_SUB":
                    break;
                case "OP_MUL":
                    break;
                case "OP_MOD":
                    break;
                case "OP_POW":
                    break;
                case "OP_DIV":
                    break;
                case "OP_IDIV":
                    break;
                case "OP_BAND":
                    break;
                case "OP_BOR":
                    break;
                case "OP_BXOR":
                    break;
                case "OP_SHL":
                    break;
                case "OP_SHR":
                    break;
                case "OP_UNM":
                    break;
                case "OP_BNOT":
                    break;
                case "OP_NOT":
                    break;
                case "OP_LEN":
                    break;
                case "OP_CONCAT":
                    break;
                case "OP_JMP":
                    break;
                case "OP_EQ":
                    break;
                case "OP_LT":
                    break;
                case "OP_LE":
                    break;
                case "OP_TEST":
                    break;
                case "OP_TESTSET":
                    break;
                case "OP_CALL":
                    break;
                case "OP_TAILCALL":
                    break;
                case "OP_RETURN":
                    if (i.B >= 2) {
                        for (let j = 0; j <= i.B-2; j++) {
                            L.stack[L.ciOff + j] = L.stack[ra + j];
                        }
                    }
                    L.ci = ci.previous;

                    if (L.ci === null) return;

                    if (i.B !== 0) L.top = ci.top;

                    continue newframe;
                    break;
                case "OP_FORLOOP":
                    break;
                case "OP_FORPREP":
                    break;
                case "OP_TFORCALL":
                    break;
                case "OP_TFORLOOP":
                    break;
                case "OP_SETLIST":
                    break;
                case "OP_CLOSURE":
                    break;
                case "OP_VARARG":
                    break;
                case "OP_EXTRAARG":
                    break;
            }
        }
    }

}

module.exports = {
    LuaVM: LuaVM
};