@@ -632,9 +632,21 @@ local function getReturnOfSetMetaTable(args)
632
632
local mt = args [2 ]
633
633
local node = vm .createNode ()
634
634
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
636
646
end
647
+
637
648
if mt then
649
+ -- 合并__index属性到返回节点
638
650
vm .compileByParentNodeAll (mt , ' __index' , function (src )
639
651
for n in vm .compileNode (src ):eachObject () do
640
652
if n .type == ' global'
@@ -647,7 +659,85 @@ local function getReturnOfSetMetaTable(args)
647
659
end )
648
660
end
649
661
-- 过滤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'
651
741
return node
652
742
end
653
743
@@ -1865,6 +1955,13 @@ local compilerSwitch = util.switch()
1865
1955
vm .setNode (source , getReturnOfSetMetaTable (args ))
1866
1956
return
1867
1957
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
1868
1965
if func .special == ' pcall' and index > 1 then
1869
1966
if not args then
1870
1967
return
0 commit comments