1 Star 0 Fork 0

letsgogo / golua

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
decode.go 4.38 KB
一键复制 编辑 原始数据 按行查看 历史
Adam Reese 提交于 2018-11-14 23:45 . fix(*): run gofmt
package binary
import (
"bytes"
"encoding/binary"
"fmt"
)
func decode(r *bytes.Buffer, c *Chunk) {
var h Header
must(binary.Read(r, order, &h))
assert(h.Signature == head, "not a precompiled chunk")
assert(h.Version == LUAC_VERSION, "version mismatch")
assert(h.Format == LUAC_FORMAT, "format mismatch")
assert(h.LuacData == tail, "corrupted")
assert(h.GoIntSize == CINT_SIZE, "int size mismatch")
assert(h.SizetSize == CSIZET_SIZE, "size_t size mismatch")
assert(h.InstrSize == INSTRUCTION_SIZE, "instruction size mismatch")
assert(h.LuaIntSize == LUA_INTEGER_SIZE, "lua integer size mismatch")
assert(h.LuaNumSize == LUA_NUMBER_SIZE, "lua number size mismatch")
assert(h.LuacIntEnc == LUAC_INT, "endianess mismatch")
assert(h.LuacNumEnc == LUAC_NUM, "float format mismatch")
c.Header = h
// decode size_upvalues (?)
_, err := r.ReadByte()
must(err)
// decode container closure prototype
decodePrototype(r, &c.Entry)
}
func decodePrototype(r *bytes.Buffer, proto *Prototype) {
// decode source name string (b[0] == length)
// b[0] == 0xFF ? uint64 : size
proto.Source = decodeString(r)
// decode line start
must(binary.Read(r, order, &proto.SrcPos))
// decode line end
must(binary.Read(r, order, &proto.EndPos))
// decode number of parameters
must(binary.Read(r, order, &proto.Params))
// decode is varadic
must(binary.Read(r, order, &proto.Vararg))
// decode maximum stack size
must(binary.Read(r, order, &proto.Stack))
// decode instruction bytecode
//
// leading 4-bytes is number of instructions
{
var num uint32
must(binary.Read(r, order, &num))
proto.Code = make([]uint32, num)
for i := range proto.Code {
must(binary.Read(r, order, &proto.Code[i]))
}
}
// decode constants
//
// leading 4-bytes is number of constants
{
var num uint32
must(binary.Read(r, order, &num))
proto.Consts = make([]interface{}, num)
for i := range proto.Consts {
proto.Consts[i] = decodeConst(r)
}
}
// decode upvalues
//
// leading 4-bytes is number of upvalues
{
var num uint32
must(binary.Read(r, order, &num))
proto.UpValues = make([]UpValue, num, num)
for i := range proto.UpValues {
var (
upv UpValue
err error
)
upv.InStack, err = r.ReadByte()
must(err)
upv.Index, err = r.ReadByte()
must(err)
proto.UpValues[i] = upv
}
}
// decode nested closure prototypes
//
// leading 4-bytes is number of prototypes
{
var num uint32
must(binary.Read(r, order, &num))
proto.Protos = make([]Prototype, num)
for i := range proto.Protos {
var fn Prototype
decodePrototype(r, &fn)
proto.Protos[i] = fn
}
}
// decode line info (pc -> line)
//
// leading 4-bytes is number of pcln entries
{
var num uint32
must(binary.Read(r, order, &num))
proto.PcLnTab = make([]uint32, num)
for i := range proto.PcLnTab {
must(binary.Read(r, order, &proto.PcLnTab[i]))
}
}
// decode local variables
//
// leading 4-bytes is number of pcln entries
{
var num uint32
must(binary.Read(r, order, &num))
proto.Locals = make([]LocalVar, num)
for i := range proto.Locals {
local := LocalVar{Name: decodeString(r)}
must(binary.Read(r, order, &local.Live))
must(binary.Read(r, order, &local.Dead))
proto.Locals[i] = local
}
}
// decode upvalue names
//
// leading 4-bytes is number of pcln entries
{
var num uint32
must(binary.Read(r, order, &num))
proto.UpNames = make([]string, num)
for i := range proto.UpNames {
proto.UpNames[i] = decodeString(r)
}
}
}
func decodeString(r *bytes.Buffer) string {
b, err := r.ReadByte()
must(err)
switch {
case b == 0x00:
return ""
case b == 0xFF:
var u64 uint64
must(binary.Read(r, order, &u64))
return string(r.Next(int(u64) - 1))
default:
return string(r.Next(int(b) - 1))
}
}
func decodeConst(r *bytes.Buffer) interface{} {
t, err := r.ReadByte()
must(err)
switch t {
case LUA_TYPE_NIL: // NIL
return nil
case LUA_TYPE_BOOL: // BOOL
b, err := r.ReadByte()
must(err)
var v bool
if b == 0 {
v = false
} else if b == 1 {
v = true
} else {
panic(fmt.Errorf("invalid bool constant: %d", b))
}
return v
case LUA_NUM_INT: // INT
var i64 int64
must(binary.Read(r, order, &i64))
return i64
case LUA_NUM_FLOAT: // FLOAT
var f64 float64
must(binary.Read(r, order, &f64))
return f64
case LUA_STR_SHORT, LUA_STR_LONG: // STRING
return decodeString(r)
default:
panic(fmt.Errorf("unexpected constant type: %d", t))
}
}
Go
1
https://gitee.com/letsgogo/golua.git
git@gitee.com:letsgogo/golua.git
letsgogo
golua
golua
4ee7f28eeb95

搜索帮助