@@ -588,9 +588,21 @@ local function getReturnOfSetMetaTable(args)
588588 local mt = args [2 ]
589589 local node = vm .createNode ()
590590 if tbl then
591- node :merge (vm .compileNode (tbl ))
591+ local tblNode = vm .compileNode (tbl )
592+ node :merge (tblNode )
593+
594+ -- 存储元表信息,将mt节点作为源节点的元表
595+ if mt then
596+ local mtNode = vm .compileNode (mt )
597+ -- 为节点添加metatable属性
598+ for n in tblNode :eachObject () do
599+ n .metatable = mtNode
600+ end
601+ end
592602 end
603+
593604 if mt then
605+ -- 合并__index属性到返回节点
594606 vm .compileByParentNodeAll (mt , ' __index' , function (src )
595607 for n in vm .compileNode (src ):eachObject () do
596608 if n .type == ' global'
@@ -602,8 +614,49 @@ local function getReturnOfSetMetaTable(args)
602614 end
603615 end )
604616 end
617+
605618 -- 过滤nil
606- node :remove ' nil'
619+ node :remove ' nil'
620+ return node
621+ end
622+
623+ --- @param args parser.object[]
624+ --- @return vm.node
625+ local function getReturnOfGetMetaTable (args )
626+ local obj = args [1 ]
627+ local node = vm .createNode ()
628+ if not obj then
629+ return node
630+ end
631+
632+ local objNode = vm .compileNode (obj )
633+ -- 尝试遍历对象的所有可能类型
634+ for n in objNode :eachObject () do
635+ -- 检查是否有metatable属性
636+ if n .metatable then
637+ node :merge (n .metatable )
638+ end
639+
640+ -- 检查是否有setmetatable调用
641+ if n .value and n .value .type == ' call' and n .value .node and n .value .node .special == ' setmetatable' and n .value .args and n .value .args [2 ] then
642+ -- 直接返回setmetatable的第二个参数
643+ node :merge (vm .compileNode (n .value .args [2 ]))
644+ end
645+
646+ -- 如果是__metatable字段的处理,优先使用它
647+ vm .compileByParentNodeAll (obj , ' __metatable' , function (src )
648+ for metaObj in vm .compileNode (src ):eachObject () do
649+ node :merge (metaObj )
650+ end
651+ end )
652+ end
653+
654+ -- 如果没有找到任何元表信息,创建一个空表类型
655+ if node :isEmpty () then
656+ node :addTable ()
657+ end
658+
659+ node :remove ' nil'
607660 return node
608661end
609662
@@ -1821,6 +1874,13 @@ local compilerSwitch = util.switch()
18211874 vm .setNode (source , getReturnOfSetMetaTable (args ))
18221875 return
18231876 end
1877+ if func .special == ' getmetatable' then
1878+ if not args then
1879+ return
1880+ end
1881+ vm .setNode (source , getReturnOfGetMetaTable (args ))
1882+ return
1883+ end
18241884 if func .special == ' pcall' and index > 1 then
18251885 if not args then
18261886 return
0 commit comments