aboutsummaryrefslogtreecommitdiff
path: root/src/lundump.js
blob: 69445d434861934cdc8c62f5cedeed9da5ac1994 (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
/*jshint esversion: 6 */
"use strict";

const DataView  = require('buffer-dataview');
const fs        = require('fs');
const lua_State = require('./lstate.js').lua_State;
const LClosure  = require('./lobject.js').LClosure;

/**
 * Parse Lua 5.3 bytecode
 * @see {@link http://www.lua.org/source/5.3/lundump.c.html|lundump.c}
 */
class BytecodeParser {

    /**
     * Initilialize bytecode parser
     * @constructor
     * @param {DataView} dataView Contains the binary data
     */
    constructor(dataView) {
        this.dataView = dataView;
        this.offset = 0;
    }

    peekByte() {
        return this.dataView.getUint8(this.offset, true);
    }

    readByte() {
        let byte = this.peekByte();
        this.offset++;
        return byte;
    }

    peekWord() {
        return this.dataView.getUint32(this.offset, true);
    }

    readWord() {
        let word = this.peekWord();
        this.offset += 4;

        return word;
    }

    checkHeader() {
        if (this.readByte() !== 0x1b
            || this.readByte() !== 0x4c
            || this.readByte() !== 0x75
            || this.readByte() !== 0x61)
            throw new Error("Bad LUA_SIGNATURE, expected [1b 4c 75 61]");

        if (this.readByte() !== 0x53)
            throw new Error("Bad Lua version, expected 5.3");

        if (this.readByte() !== 0)
            throw new Error("Supports only official PUC-Rio implementation")
    }

    luaU_undump() {
        checkHeader();
        let cl = new LClosure(L, this.readByte());

        return cl;
    }

}