@@ -632,9 +632,21 @@ local function getReturnOfSetMetaTable(args)
632632 local mt = args [2 ]
633633 local node = vm .createNode ()
634634 if tbl then
635- node :merge (vm .compileNode (tbl ))
635+ local tblNode = vm .compileNode (tbl )
636+ node :merge (tblNode )
637+
638+ -- 存储元表信息,将mt节点作为源节点的元表
639+ if mt then
640+ local mtNode = vm .compileNode (mt )
641+ -- 为节点添加metatable属性
642+ for n in tblNode :eachObject () do
643+ n .metatable = mtNode
644+ end
645+ end
636646 end
647+
637648 if mt then
649+ -- 合并__index属性到返回节点
638650 vm .compileByParentNodeAll (mt , ' __index' , function (src )
639651 for n in vm .compileNode (src ):eachObject () do
640652 if n .type == ' global'
@@ -647,7 +659,85 @@ local function getReturnOfSetMetaTable(args)
647659 end )
648660 end
649661 -- 过滤nil
650- node :remove ' nil'
662+ node :remove ' nil'
663+ return node
664+ end
665+
666+ --- @param args parser.object[]
667+ --- @return vm.node
668+ local function getReturnOfGetMetaTable (args )
669+ local obj = args [1 ]
670+ local node = vm .createNode ()
671+ if not obj then
672+ return node
673+ end
674+
675+ local objNode = vm .compileNode (obj )
676+ local foundMetatable = false
677+
678+ -- 尝试遍历对象的所有可能类型
679+ for n in objNode :eachObject () do
680+ -- 检查是否有metatable属性
681+ if n .metatable then
682+ -- 先检查元表中是否有__metatable字段
683+ local hasMetaField = false
684+ for mt in n .metatable :eachObject () do
685+ if mt .type == ' table' then
686+ -- 尝试从元表中查找__metatable字段
687+ vm .compileByParentNodeAll (mt , ' __metatable' , function (src )
688+ hasMetaField = true
689+ -- 使用__metatable字段的值作为返回值
690+ for metaObj in vm .compileNode (src ):eachObject () do
691+ node :merge (metaObj )
692+ end
693+ end )
694+ end
695+ end
696+
697+ -- 如果没有__metatable字段,则返回元表本身
698+ if not hasMetaField then
699+ node :merge (n .metatable )
700+ end
701+
702+ foundMetatable = true
703+ end
704+
705+ -- 检查是否有setmetatable调用
706+ if not foundMetatable and 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
707+ local mtArg = n .value .args [2 ]
708+ local mtNode = vm .compileNode (mtArg )
709+
710+ -- 检查元表参数中是否有__metatable字段
711+ local hasMetaField = false
712+ -- 尝试从元表参数中查找__metatable字段
713+ vm .compileByParentNodeAll (mtArg , ' __metatable' , function (src )
714+ hasMetaField = true
715+ -- 使用__metatable字段的值作为返回值
716+ for metaObj in vm .compileNode (src ):eachObject () do
717+ node :merge (metaObj )
718+ end
719+ end )
720+
721+ -- 如果没有__metatable字段,则返回元表本身
722+ if not hasMetaField then
723+ node :merge (mtNode )
724+ end
725+
726+ foundMetatable = true
727+ end
728+ end
729+
730+ -- 如果没有找到任何元表信息,创建一个空表类型
731+ if not foundMetatable then
732+ local tableObj = {
733+ type = ' table' ,
734+ start = obj .start or 0 ,
735+ finish = obj .finish or 0 ,
736+ }
737+ node :merge (tableObj )
738+ end
739+
740+ node :remove ' nil'
651741 return node
652742end
653743
@@ -1865,6 +1955,13 @@ local compilerSwitch = util.switch()
18651955 vm .setNode (source , getReturnOfSetMetaTable (args ))
18661956 return
18671957 end
1958+ if func .special == ' getmetatable' then
1959+ if not args then
1960+ return
1961+ end
1962+ vm .setNode (source , getReturnOfGetMetaTable (args ))
1963+ return
1964+ end
18681965 if func .special == ' pcall' and index > 1 then
18691966 if not args then
18701967 return
0 commit comments