summaryrefslogtreecommitdiff
path: root/server/src/vm/vm.lua
diff options
context:
space:
mode:
authorsumneko <sumneko@hotmail.com>2019-04-17 12:29:12 +0800
committersumneko <sumneko@hotmail.com>2019-04-17 12:29:12 +0800
commitf2a68c5f7dda67483599dc7c983a2ad3098da097 (patch)
tree4770c53981e71555aa60f7e30c4a4f6f8db0e456 /server/src/vm/vm.lua
parent4ddf788965b6f43d75d119600ed490e47825dff1 (diff)
downloadlua-language-server-f2a68c5f7dda67483599dc7c983a2ad3098da097.zip
修正函数递归时,局部变量堆栈共享状态的bug
Diffstat (limited to 'server/src/vm/vm.lua')
-rw-r--r--server/src/vm/vm.lua28
1 files changed, 25 insertions, 3 deletions
diff --git a/server/src/vm/vm.lua b/server/src/vm/vm.lua
index ef3ce27b..c9bc396c 100644
--- a/server/src/vm/vm.lua
+++ b/server/src/vm/vm.lua
@@ -103,6 +103,7 @@ function mt:runFunction(func)
local originFunction = self:getCurrentFunction()
self:setCurrentFunction(func)
func:push(func:getSource())
+ func:markChunk()
self:doActions(func:getSource())
@@ -125,7 +126,7 @@ function mt:buildFunction(exp)
local func = value:getFunction()
self:eachLocal(function (name, loc)
- func:saveLocal(name, loc)
+ func:saveUpvalue(name, loc)
end)
return value
@@ -1078,6 +1079,10 @@ function mt:saveLocal(name, loc)
self.currentFunction:saveLocal(name, loc)
end
+function mt:saveUpvalue(name, loc)
+ self.currentFunction:saveUpvalue(name, loc)
+end
+
function mt:loadLocal(name)
return self.currentFunction:loadLocal(name)
end
@@ -1153,6 +1158,23 @@ function mt:createLocal(key, source, value)
return loc
end
+function mt:createUpvalue(key, source, value)
+ local loc = self:bindLocal(source)
+ if loc then
+ return loc
+ end
+
+ if not value then
+ value = self:createValue('nil', source)
+ end
+
+ loc = localMgr.create(key, source, value)
+ self:saveUpvalue(key, loc)
+ self:bindLocal(source, loc, 'local')
+ value:addInfo('local', source)
+ return loc
+end
+
function mt:createEnvironment(ast)
-- 整个文件是一个函数
self.main = self:createFunction(ast)
@@ -1165,11 +1187,11 @@ function mt:createEnvironment(ast)
local env
if self.envType == '_ENV' then
-- 隐藏的上值`_ENV`
- env = self:createLocal('_ENV', self:getDefaultSource(), global)
+ env = self:createUpvalue('_ENV', self:getDefaultSource(), global)
else
-- 为了实现方便,fenv也使用隐藏上值来实现
-- 使用了非法标识符保证用户无法访问
- env = self:createLocal('@ENV', self:getDefaultSource(), global)
+ env = self:createUpvalue('@ENV', self:getDefaultSource(), global)
end
env:set('hide', true)
self.env = env