luapy (6) luatable

小编 2026-06-18 阅读:968 评论:0
1)lua table from lua_value import LuaValue class LuaTable: def __init__(self, narr, nrec):...

1)lua table

from lua_value import LuaValue


class LuaTable:
    def __init__(self, narr, nrec):
        self.arr = None
        self.map = None

        if narr > 0:
            self.arr = []
        if nrec > 0:
            self.map = {}

    def __len__(self):
        return len(self.arr) if self.arr is not None else 0

    def get(self, key):
        key = LuaValue.float2integer(key)

        if self.arr and isinstance(key, int):
            if 1 <= key <= len(self.arr):
                return self.arr[key-1]

        return self.map[key] if key in self.map else None

    def map_to_arr(self):
        if self.map:
            i = len(self.arr)
            while i in self.map:
                v = self.map[i]
                self.map.pop(i)
                self.arr.append(v)
                i += 1

    def put(self, key, val):
        assert(key is not None)
        assert(key is not float(\'NAN\'))

        key = LuaValue.float2integer(key)
        if isinstance(key, int) and key >= 1:
            if not self.arr:
                self.arr = []
            arr_len = len(self.arr)
            if key <= arr_len:
                self.arr[key-1] = val
                if key == arr_len and val is None:
                    self.arr.pop(key)
                return
            if key == arr_len + 1:
                if self.map:
                    self.map.pop(key)
                if val is not None:
                    self.arr.append(val)
                    self.map_to_arr()
                return

        if val is not None:
            if not self.map:
                self.map = {key: val}
        else:
            self.map.pop(key)

2)lua state

from lua_stack import LuaStack
from lua_type import LuaType
from lua_value import LuaValue
from arith_op import ArithOp
from arithmetic import Arithmetic
from cmp_op import CmpOp
from compare import Compare
from lua_table import LuaTable


class LuaState:
    def __init__(self, proto):
        self.stack = LuaStack()
        self.proto = proto
        self.pc = 0

    # ...
    
    # table
    def create_table(self, narr, nrec):
        table = LuaTable(narr, nrec)
        self.stack.push(table)

    @staticmethod
    def get_table_val(t, k):
        if isinstance(t, LuaTable):
            return t.get(k)
        raise Exception(\'not a table\')

    def get_table(self, idx):
        t = self.stack.get(idx)
        k = self.stack.pop()
        v = LuaState.get_table_val(t, k)
        self.stack.push(v)
        return LuaValue.type_of(v)

    def get_i(self, idx, i):
        t = self.stack.get(idx)
        v = LuaState.get_table_val(t, i)
        self.stack.push(v)
        return LuaValue.type_of(v)

    def set_table(self, idx):
        t = self.stack.get(idx)
        v = self.stack.pop()
        k = self.stack.pop()
        LuaState.set_table_kv(t, k, v)

    @staticmethod
    def set_table_kv(t, k, v):
        if isinstance(t, LuaTable):
            t.put(k, v)
            return
        raise Exception(\'not a table\')

    def set_field(self, idx, k):
        t = self.stack.get(idx)
        v = self.stack.pop()
        LuaState.set_table_kv(t, k, v)

    def set_i(self, idx, i):
        t = self.stack.get(idx)
        v = self.stack.pop()
        LuaState.set_table_kv(t, i, v)

3)instruction

# R(A) := {}
def newtable(inst, vm):
    a, b, c = inst.a_b_c()
    a += 1
    vm.create_table(LuaValue.fb2int(b), LuaValue.fb2int(c))
    vm.replace(a)


# R(A) := R(B)[RK(C)]
def gettable(inst, vm):
    a, b, c = inst.a_b_c()
    a += 1
    b += 1
    vm.get_rk(c)
    vm.get_table(b)
    vm.replace(a)


# R(A)[R(B)] := RK(C)
def settable(inst, vm):
    a, b, c = inst.a_b_c()
    a += 1
    vm.get_rk(b)
    vm.get_rk(c)
    vm.set_table(a)


# R(A)[(C-1)*LFIELDS_PER_FLUSH+i] := R(A+i), 1 <= i <= B
def setlist(inst, vm):
    a, b, c = inst.a_b_c()
    a += 1
    c = c - 1 if c > 0 else inst.ax(vm.fetch())

    vm.check_stack(1)
    idx = c * LFIELDS_PER_FLUSH
    for i in range(1, b+1):
        idx += 1
        vm.push_value(a+i)
        vm.set_i(a, idx)


op_codes = [
    #      T  A  B       C       mode   name        action
    OpCode(0, 1, OpArgR, OpArgN, IABC,  \"MOVE    \", move),      # R(A) := R(B)
    OpCode(0, 1, OpArgK, OpArgN, IABx,  \"LOADK   \", loadk),     # R(A) := Kst(Bx)
    OpCode(0, 1, OpArgN, OpArgN, IABx,  \"LOADKX  \", loadkx),    # R(A) := Kst(extra arg)
    OpCode(0, 1, OpArgU, OpArgU, IABC,  \"LOADBOOL\", loadbool),  # R(A) := (bool)B; if (C) pc++
    OpCode(0, 1, OpArgU, OpArgN, IABC,  \"LOADNIL \", loadnil),   # R(A), R(A+1), ..., R(A+B) := nil
    OpCode(0, 1, OpArgU, OpArgN, IABC,  \"GETUPVAL\", None),      # R(A) := UpValue[B]
    OpCode(0, 1, OpArgU, OpArgK, IABC,  \"GETTABUP\", None),      # R(A) := UpValue[B][RK(C)]
    OpCode(0, 1, OpArgR, OpArgK, IABC,  \"GETTABLE\", gettable),  # R(A) := R(B)[RK(C)]
    OpCode(0, 0, OpArgK, OpArgK, IABC,  \"SETTABUP\", None),      # UpValue[A][RK(B)] := RK(C)
    OpCode(0, 0, OpArgU, OpArgN, IABC,  \"SETUPVAL\", None),      # UpValue[B] := R(A)
    OpCode(0, 0, OpArgK, OpArgK, IABC,  \"SETTABLE\", settable),  # R(A)[RK(B)] := RK(C)
    OpCode(0, 1, OpArgU, OpArgU, IABC,  \"NEWTABLE\", newtable),  # R(A) := {} (size = B,C)
    OpCode(0, 1, OpArgR, OpArgK, IABC,  \"SELF    \", None),      # R(A+1) := R(B); R(A) := R(B)[RK(C)]
    OpCode(0, 1, OpArgK, OpArgK, IABC,  \"ADD     \", add),       # R(A) := RK(B) + RK(C)
    OpCode(0, 1, OpArgK, OpArgK, IABC,  \"SUB     \", sub),       # R(A) := RK(B) - RK(C)
    OpCode(0, 1, OpArgK, OpArgK, IABC,  \"MUL     \", mul),       # R(A) := RK(B) * RK(C)
    OpCode(0, 1, OpArgK, OpArgK, IABC,  \"MOD     \", mod),       # R(A) := RK(B) % RK(C)
    OpCode(0, 1, OpArgK, OpArgK, IABC,  \"POW     \", luapow),    # R(A) := RK(B) ^ RK(C)
    OpCode(0, 1, OpArgK, OpArgK, IABC,  \"DIV     \", div),       # R(A) := RK(B) / RK(C)
    OpCode(0, 1, OpArgK, OpArgK, IABC,  \"IDIV    \", idiv),      # R(A) := RK(B) // RK(C)
    OpCode(0, 1, OpArgK, OpArgK, IABC,  \"BAND    \", band),      # R(A) := RK(B) & RK(C)
    OpCode(0, 1, OpArgK, OpArgK, IABC,  \"BOR     \", bor),       # R(A) := RK(B) | RK(C)
    OpCode(0, 1, OpArgK, OpArgK, IABC,  \"BXOR    \", bxor),      # R(A) := RK(B) ~ RK(C)
    OpCode(0, 1, OpArgK, OpArgK, IABC,  \"SHL     \", shl),       # R(A) := RK(B) << RK(C)
    OpCode(0, 1, OpArgK, OpArgK, IABC,  \"SHR     \", shr),       # R(A) := RK(B) >> RK(C)
    OpCode(0, 1, OpArgR, OpArgN, IABC,  \"UNM     \", unm),       # R(A) := -R(B)
    OpCode(0, 1, OpArgR, OpArgN, IABC,  \"BNOT    \", bnot),      # R(A) := ~R(B)
    OpCode(0, 1, OpArgR, OpArgN, IABC,  \"NOT     \", luanot),    # R(A) := not R(B)
    OpCode(0, 1, OpArgR, OpArgN, IABC,  \"LEN     \", length),    # R(A) := length of R(B)
    OpCode(0, 1, OpArgR, OpArgR, IABC,  \"CONCAT  \", concat),    # R(A) := R(B).. ... ..R(C)
    OpCode(0, 0, OpArgR, OpArgN, IAsBx, \"JMP     \", jmp),       # pc+=sBx; if (A) close all upvalues >= R(A - 1)
    OpCode(1, 0, OpArgK, OpArgK, IABC,  \"EQ      \", eq),        # if ((RK(B) == RK(C)) ~= A) then pc++
    OpCode(1, 0, OpArgK, OpArgK, IABC,  \"LT      \", lt),        # if ((RK(B) <  RK(C)) ~= A) then pc++
    OpCode(1, 0, OpArgK, OpArgK, IABC,  \"LE      \", le),        # if ((RK(B) <= RK(C)) ~= A) then pc++
    OpCode(1, 0, OpArgN, OpArgU, IABC,  \"TEST    \", test),      # if not (R(A) <=> C) then pc++
    OpCode(1, 1, OpArgR, OpArgU, IABC,  \"TESTSET \", testset),   # if (R(B) <=> C) then R(A) := R(B) else pc++
    OpCode(0, 1, OpArgU, OpArgU, IABC,  \"CALL    \", None),      # R(A), ...,R(A+C-2) := R(A)(R(A+1), ...,R(A+B-1))
    OpCode(0, 1, OpArgU, OpArgU, IABC,  \"TAILCALL\", None),      # return R(A)(R(A+1), ... ,R(A+B-1))
    OpCode(0, 0, OpArgU, OpArgN, IABC,  \"RETURN  \", None),      # return R(A), ... ,R(A+B-2)
    OpCode(0, 1, OpArgR, OpArgN, IAsBx, \"FORLOOP \", forloop),   # R(A)+=R(A+2); if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }
    OpCode(0, 1, OpArgR, OpArgN, IAsBx, \"FORPREP \", forprep),   # R(A)-=R(A+2); pc+=sBx
    OpCode(0, 0, OpArgN, OpArgU, IABC,  \"TFORCALL\", None),      # R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
    OpCode(0, 1, OpArgR, OpArgN, IAsBx, \"TFORLOOP\", None),      # if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx }
    OpCode(0, 0, OpArgU, OpArgU, IABC,  \"SETLIST \", setlist),   # R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B
    OpCode(0, 1, OpArgU, OpArgN, IABx,  \"CLOSURE \", None),      # R(A) := closure(KPROTO[Bx])
    OpCode(0, 1, OpArgU, OpArgN, IABC,  \"VARARG  \", None),      # R(A), R(A+1), ..., R(A+B-2) = vararg
    OpCode(0, 0, OpArgU, OpArgU, IAx,   \"EXTRAARG\", None),      # extra (larger) argument for previous opcode
]

4)test

local t = {\"a\", \"b\", \"c\"}
t[2] = \"B\"
t[\"foo\"] = \"Bar\"
local s = t[3] .. t[2] .. t[1] .. t[\"foo\"] .. #t
from binary_chunk import BinaryChunk
from lua_state import LuaState
from opcode import Instruction
from opcode import OpCode


def lua_main(proto):
    vm = LuaState(proto)
    vm.set_top(proto.get_max_stack_size())
    while True:
        pc = vm.get_pc()
        i = vm.fetch()
        inst = Instruction(i)
        if inst.op_code() != OpCode.RETURN:
            inst.execute(vm)
            print(\'[%02d] %-8s \' % (pc+1, inst.op_name()), end=\'\')
            vm.print_stack()
        else:
            break


def main():
    bc = BinaryChunk(\'./test/table.luac\')
    bc.print_header()
    bc.check_header()
    bc.print_main_func()

    proto = bc.get_main_func()
    lua_main(proto)


if __name__ == \'__main__\':
    main()

5)result

signature:        b\'\\x1bLua\'
version:          83
format:           0
luac_data:        b\'\\x19\\x93\\r\\n\\x1a\\n\'
cint_size:        4
csizet_size:      8
inst_size:        4
lua_int_size:     8
lua_number_size:  8
luac_int:         0x5678
luac_num:         370.5

main <@table.lua:0,0> (14 instructions)
0+ params, 6 slots, 1 upvalues, 2 locals, 9 constants, 0 functions
	1	[1]	NEWTABLE        0        3        0
	2	[1]	LOADK           1       -1
	3	[1]	LOADK           2       -2
	4	[1]	LOADK           3       -3
	5	[1]	SETLIST         0        3        1
	6	[2]	SETTABLE        0       -4       -5
	7	[3]	SETTABLE        0       -6       -7
	8	[4]	GETTABLE        1        0       -8
	9	[4]	GETTABLE        2        0       -4
	10	[4]	GETTABLE        3        0       -9
	11	[4]	GETTABLE        4        0       -6
	12	[4]	LEN             5        0
	13	[4]	CONCAT          1        1        5
	14	[4]	RETURN          0        1
constants (9):
	1	\"a\"
	2	\"b\"
	3	\"c\"
	4	2
	5	\"B\"
	6	\"foo\"
	7	\"Bar\"
	8	3
	9	1
locals (2):
	1	t	6	15
	2	s	14	15
upvalues (1):
	1	_ENV	1	0
[01] NEWTABLE @font-face {
				font-family: "autolinktags";
				src: url("https://www.seowoai.com/zb_users/plugin/AutoLinkTags/style/fonts/iconfont.woff2") format("woff2"),
				url("https://www.seowoai.com/zb_users/plugin/AutoLinkTags/style/fonts/iconfont.woff") format("woff"),
				url("https://www.seowoai.com/zb_users/plugin/AutoLinkTags/style/fonts/iconfont.ttf") format("truetype");
				font-weight:normal;
				font-style:normal;
			}.tagslink::after { content:"\e613"; margin:2px 0 0 0px; font-size:12px; font-family:"autolinktags"; display:inline-block; vertical-align:top; }															
版权声明

本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。

热门文章
  • 机房智能化温湿度解决方式之POE供电以太网温湿度传感器

    机房智能化温湿度解决方式之POE供电以太网温湿度传感器
    机房智能化温湿度解决方式之POE供电以太网温湿度传感器 北京盈创力和电子科技有限公司 智能型TCP网口温湿度记录仪 北京IP网络温湿度记录仪厂家,北京盈创力和 北京智能型TCP网口温湿度记录仪IP网络温湿度记录仪是一种新型的基于TCP/IP协议双绞线以太网标准温湿度采集模块,利用它可以实现现场温度值、相对湿度值的采集,同时利用其自身的RJ45通信接口可以方便地和机房监控主机或交换机集线器进行联网。 工作于-40℃~85℃工业级带...
  • Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering

    Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering
    Problem Statement 我们考虑一个具有马尔可夫性质、非线性、非高斯的状态空间模型(State Space Model):对于一个时间序列上的观测结果{yt,t∈N}\\{ y_t , t \\in N \\}{yt​,t∈N},我们认为每个观测结果yty_tyt​的生成依赖于一个无法直接观察的隐变量xt∈{xt,t∈N}x_t \\in \\{x_t , t \\in N \\}xt​∈{xt​,t∈N},即:p(...
  • HTTP状态保持的原理

    HTTP状态保持的原理
    a)在用户登录之后,浏览器返回响应的时候会在响应中添加上cookieb)浏览器接收到cookie之后会自动保存c)当用户再次请求同一服务器中的其他网页的时候,浏览器会自动带上之前保存的cookied)服务接收到请求之后可以请 request 对象中取到cookie 判断当前用户是否登录  Http是无状态的,就是连接时数据互通,关闭后...
  • Hive 系统函数及示例

    Hive 系统函数及示例
    查看所有系统函数 show functions; 函数分类 内置函数【系统函数】 数学函数: floor、round、ceil、cos、log2等 字符串函数: length、reverse、trim、lower、get_json_object、repeat等 收集函数: size 转换函数: cast 日期函数: year、month、datediff、date、date_add等 条件函数: coalesce、case…w...
  • CSRF的原理和防范措施

    CSRF的原理和防范措施
    a)攻击原理:i.用户C访问正常网站A时进行登录,浏览器保存A的cookieii.用户C再访问攻击网站B,网站B上有某个隐藏的链接或者图片标签会自动请求网站A的URL地址,例如表单提交,传指定的参数iii.而攻击网站B在访问网站A的时候,浏览器会自动带上网站A的cookieiv.所以网站A在接收到请求之后可判断当前用户是登录状态,所以...
标签列表