Skip to content

Commit 72741f6

Browse files
committed
Bugfix when nil object return by getmetatable
1 parent 2b6151a commit 72741f6

File tree

1 file changed

+49
-8
lines changed

1 file changed

+49
-8
lines changed

script/vm/compiler.lua

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,8 @@ local function getReturnOfGetMetaTable(args)
669669
local obj = args[1]
670670
local node = vm.createNode()
671671
if not obj then
672+
-- 如果没有对象,返回nil类型
673+
node:merge(vm.declareGlobal('type', 'nil'))
672674
return node
673675
end
674676

@@ -727,14 +729,9 @@ local function getReturnOfGetMetaTable(args)
727729
end
728730
end
729731

730-
-- 如果没有找到任何元表信息,创建一个空表类型
732+
-- 如果没有找到任何元表信息,返回nil类型
731733
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)
734+
node:merge(vm.declareGlobal('type', 'nil'))
738735
end
739736

740737
node:remove 'nil'
@@ -1795,7 +1792,7 @@ local compilerSwitch = util.switch()
17951792
end)
17961793
: case 'tablefield'
17971794
: case 'tableindex'
1798-
: call(function (source)
1795+
: call(function (source, lastKey, pushResult)
17991796
local hasMarkDoc
18001797
if source.bindDocs then
18011798
hasMarkDoc = vm.bindDocs(source)
@@ -2083,6 +2080,50 @@ local compilerSwitch = util.switch()
20832080
end)
20842081
: case 'call'
20852082
: call(function (source)
2083+
-- 检查是否是getmetatable函数引用的方法调用
2084+
if source.node and source.node.type == 'getmethod' and source.args then
2085+
local method = source.node
2086+
local node = method.node
2087+
2088+
-- 检查是否是通过引用调用getmetatable
2089+
if node then
2090+
local methodName = method.method and method.method[1]
2091+
if methodName then
2092+
-- 使用compileByParentNode直接查找属性
2093+
vm.compileByParentNode(node, methodName, function (field)
2094+
if field.value and field.value.special == 'getmetatable' then
2095+
-- 是getmetatable的引用,安全处理
2096+
-- 创建一个新节点避免guide.getRoot错误
2097+
vm.setNode(source, getReturnOfGetMetaTable({node}))
2098+
return
2099+
end
2100+
end)
2101+
end
2102+
end
2103+
end
2104+
2105+
-- 检查常规函数调用中直接调用getmetatable的情况
2106+
if source.node and source.node.special == 'getmetatable' then
2107+
-- 直接使用getReturnOfGetMetaTable处理
2108+
if source.args and source.args[1] then
2109+
vm.setNode(source, getReturnOfGetMetaTable(source.args))
2110+
return
2111+
end
2112+
end
2113+
2114+
-- 检查方法内部直接调用getmetatable(self)的情况
2115+
if source.node and source.node.type == 'getlocal' and source.node[1] == 'getmetatable' then
2116+
if source.args and source.args[1] and source.args[1].type == 'getlocal' and source.args[1][1] == 'self' then
2117+
-- 获取self对象引用
2118+
local selfNode = guide.getSelfNode(source.args[1])
2119+
if selfNode then
2120+
-- 处理元表,但不直接传递可能导致guide.getRoot错误的对象
2121+
vm.setNode(source, getReturnOfGetMetaTable({selfNode}))
2122+
return
2123+
end
2124+
end
2125+
end
2126+
20862127
-- ignore rawset
20872128
if source.node.special == 'rawset' then
20882129
return

0 commit comments

Comments
 (0)