summaryrefslogtreecommitdiff
path: root/script/vm
diff options
context:
space:
mode:
Diffstat (limited to 'script/vm')
-rw-r--r--script/vm/compiler.lua43
-rw-r--r--script/vm/node.lua9
2 files changed, 39 insertions, 13 deletions
diff --git a/script/vm/compiler.lua b/script/vm/compiler.lua
index 43c7be1e..a87f2eba 100644
--- a/script/vm/compiler.lua
+++ b/script/vm/compiler.lua
@@ -443,6 +443,9 @@ function m.compileByParentNode(source, key, pushResult)
end
local function selectNode(source, list, index)
+ if not list then
+ return nil
+ end
local exp
if list[index] then
exp = list[index]
@@ -644,17 +647,6 @@ local compilerSwitch = util.switch()
if source.bindDocs then
hasMarkDoc = bindDocs(source)
end
- if source.ref and not hasMarkDoc then
- for _, ref in ipairs(source.ref) do
- if ref.type == 'setlocal' then
- if ref.value and ref.value.type == 'table' then
- nodeMgr.setNode(source, ref.value)
- else
- nodeMgr.setNode(source, m.compileNode(ref.value))
- end
- end
- end
- end
local hasMarkParam
if source.dummy and not hasMarkDoc then
hasMarkParam = true
@@ -669,6 +661,19 @@ local compilerSwitch = util.switch()
end
end
end
+ if not source.value
+ and source.ref
+ and not hasMarkDoc then
+ for _, ref in ipairs(source.ref) do
+ if ref.type == 'setlocal' then
+ if ref.value and ref.value.type == 'table' then
+ nodeMgr.setNode(source, ref.value)
+ else
+ nodeMgr.setNode(source, m.compileNode(ref.value))
+ end
+ end
+ end
+ end
-- function x.y(self, ...) --> function x:y(...)
if source[1] == 'self'
and not hasMarkDoc
@@ -707,11 +712,25 @@ local compilerSwitch = util.switch()
if source.parent.type == 'loop' then
nodeMgr.setNode(source, globalMgr.getGlobal('type', 'integer'))
end
+
+ -- avoid self reference
+ -- `local x; x = x`
+ -- the third `x` is unknown here
+ -- x[1] -> value of x[2] -> x[3] -> x[1](locked!)
+ if source.ref then
+ local myNode = nodeMgr.getNode(source)
+ for _, ref in ipairs(source.ref) do
+ if ref.type == 'setlocal'
+ or ref.type == 'getlocal' then
+ nodeMgr.setNode(ref, myNode, true)
+ end
+ end
+ end
end)
: case 'setlocal'
: case 'getlocal'
: call(function (source)
- nodeMgr.setNode(source, m.compileNode(source.node))
+ nodeMgr.setNode(source, m.compileNode(source.node), true)
end)
: case 'setfield'
: case 'setmethod'
diff --git a/script/vm/node.lua b/script/vm/node.lua
index d51c2318..409841fc 100644
--- a/script/vm/node.lua
+++ b/script/vm/node.lua
@@ -23,7 +23,14 @@ function m.mergeNode(a, b)
return union(a, b)
end
-function m.setNode(source, node)
+---@param source parser.object
+---@param node vm.node
+---@param cover? boolean
+function m.setNode(source, node, cover)
+ if cover then
+ m.nodeCache[source] = node
+ return
+ end
if not node then
return
end