summaryrefslogtreecommitdiff
path: root/script
diff options
context:
space:
mode:
Diffstat (limited to 'script')
-rw-r--r--script/vm/compiler.lua94
-rw-r--r--script/vm/def.lua2
-rw-r--r--script/vm/local-id.lua38
-rw-r--r--script/vm/node.lua1
-rw-r--r--script/vm/ref.lua4
-rw-r--r--script/vm/visible.lua2
6 files changed, 89 insertions, 52 deletions
diff --git a/script/vm/compiler.lua b/script/vm/compiler.lua
index c8323a49..2cb2d93c 100644
--- a/script/vm/compiler.lua
+++ b/script/vm/compiler.lua
@@ -66,7 +66,7 @@ end
local function searchFieldByLocalID(source, key, pushResult)
local fields
if key then
- fields = vm.getLocalSourcesSets(source, key)
+ fields = vm.getLocalSets(source, key)
else
fields = vm.getLocalFields(source, false)
end
@@ -1234,42 +1234,72 @@ local compilerSwitch = util.switch()
if key == nil then
return
end
- if type(key) == 'table' then
- ---@cast key vm.node
- local uri = guide.getUri(source)
- local value = vm.getTableValue(uri, vm.compileNode(source.node), key)
- if value then
- vm.setNode(source, value)
- end
- for k in key:eachObject() do
- if k.type == 'global' and k.cate == 'type' then
- ---@cast k vm.global
- vm.compileByParentNode(source.node, k, function (src)
- vm.setNode(source, vm.compileNode(src))
- if src.value then
- vm.setNode(source, vm.compileNode(src.value))
- end
- end)
+
+ ---@type vm.node, boolean
+ local cacheNode, needCompile
+
+ do
+ local localInfo = vm.getLocalInfo(source)
+ if localInfo then
+ cacheNode = localInfo.node
+ if not cacheNode then
+ needCompile = true
+ cacheNode = vm.createNode()
+ localInfo.node = cacheNode
+ end
+ else
+ local parentNode = vm.compileNode(source.node)
+ if not parentNode.fields then
+ parentNode.fields = {}
+ end
+ cacheNode = parentNode.fields[key]
+ if not cacheNode then
+ needCompile = true
+ cacheNode = vm.createNode()
+ parentNode.fields[key] = cacheNode
end
end
- else
- ---@cast key string
- vm.compileByParentNode(source.node, key, function (src)
- if src.value then
- if bindDocs(src) then
- vm.setNode(source, vm.compileNode(src))
- elseif src.value.type ~= 'nil' then
- vm.setNode(source, vm.compileNode(src.value))
- local node = vm.getNode(src)
- if node then
- vm.setNode(source, node)
- end
+ end
+
+ if needCompile then
+ if type(key) == 'table' then
+ ---@cast key vm.node
+ local uri = guide.getUri(source)
+ local value = vm.getTableValue(uri, vm.compileNode(source.node), key)
+ if value then
+ cacheNode:merge(value)
+ end
+ for k in key:eachObject() do
+ if k.type == 'global' and k.cate == 'type' then
+ ---@cast k vm.global
+ vm.compileByParentNode(source.node, k, function (src)
+ cacheNode:merge(vm.compileNode(src))
+ if src.value then
+ cacheNode:merge(vm.compileNode(src.value))
+ end
+ end)
end
- else
- vm.setNode(source, vm.compileNode(src))
end
- end)
+ else
+ ---@cast key string
+ vm.compileByParentNode(source.node, key, function (src)
+ if src.value then
+ if bindDocs(src) then
+ cacheNode:merge(vm.compileNode(src))
+ elseif src.value.type ~= 'nil' then
+ cacheNode:merge(vm.compileNode(src.value))
+ local node = vm.getNode(src)
+ if node then
+ cacheNode:merge(node)
+ end
+ end
+ else
+ cacheNode:merge(vm.compileNode(src))
+ end
+ end)
+ end
end
+ vm.setNode(source, cacheNode)
end)
: case 'setglobal'
: call(function (source)
diff --git a/script/vm/def.lua b/script/vm/def.lua
index 9bc6159b..09b7193f 100644
--- a/script/vm/def.lua
+++ b/script/vm/def.lua
@@ -33,7 +33,7 @@ end
---@param source parser.object
---@param pushResult fun(src: parser.object)
local function searchByLocalID(source, pushResult)
- local idSources = vm.getLocalSourcesSets(source)
+ local idSources = vm.getLocalSets(source)
if not idSources then
return
end
diff --git a/script/vm/local-id.lua b/script/vm/local-id.lua
index 1c3fd356..89466c47 100644
--- a/script/vm/local-id.lua
+++ b/script/vm/local-id.lua
@@ -3,9 +3,14 @@ local guide = require 'parser.guide'
---@class vm
local vm = require 'vm.vm'
+---@class vm.local
+---@field sets parser.object[]
+---@field gets parser.object[]
+---@field node? vm.node
+
---@class parser.object
---@field package _localID string|false
----@field package _localIDs table<string, { sets: parser.object[], gets: parser.object[] }>
+---@field package _localIDs table<string, vm.local>
local compileLocalID, getLocal
@@ -163,8 +168,8 @@ end
---@param source parser.object
---@param key? string
----@return parser.object[]?
-function vm.getLocalSourcesSets(source, key)
+---@return vm.local?
+function vm.getLocalInfo(source, key)
local id = vm.getLocalID(source)
if not id then
return nil
@@ -179,28 +184,29 @@ function vm.getLocalSourcesSets(source, key)
end
id = id .. vm.ID_SPLITE .. key
end
- return root._localIDs[id].sets
+ return root._localIDs[id]
end
---@param source parser.object
---@param key? string
---@return parser.object[]?
-function vm.getLocalSourcesGets(source, key)
- local id = vm.getLocalID(source)
- if not id then
+function vm.getLocalSets(source, key)
+ local localInfo = vm.getLocalInfo(source, key)
+ if not localInfo then
return nil
end
- local root = guide.getRoot(source)
- if not root._localIDs then
+ return localInfo.sets
+end
+
+---@param source parser.object
+---@param key? string
+---@return parser.object[]?
+function vm.getLocalGets(source, key)
+ local localInfo = vm.getLocalInfo(source, key)
+ if not localInfo then
return nil
end
- if key then
- if type(key) ~= 'string' then
- return nil
- end
- id = id .. vm.ID_SPLITE .. key
- end
- return root._localIDs[id].gets
+ return localInfo.gets
end
---@param source parser.object
diff --git a/script/vm/node.lua b/script/vm/node.lua
index 65d752df..ec1b9ef2 100644
--- a/script/vm/node.lua
+++ b/script/vm/node.lua
@@ -14,6 +14,7 @@ vm.nodeCache = setmetatable({}, util.MODE_K)
---@class vm.node
---@field [integer] vm.node.object
---@field [vm.node.object] true
+---@field fields? table<vm.node|string, vm.node>
local mt = {}
mt.__index = mt
mt.id = 0
diff --git a/script/vm/ref.lua b/script/vm/ref.lua
index 012cfd28..45c01c78 100644
--- a/script/vm/ref.lua
+++ b/script/vm/ref.lua
@@ -228,13 +228,13 @@ end
---@param source parser.object
---@param pushResult fun(src: parser.object)
local function searchByLocalID(source, pushResult)
- local sourceSets = vm.getLocalSourcesSets(source)
+ local sourceSets = vm.getLocalSets(source)
if sourceSets then
for _, src in ipairs(sourceSets) do
pushResult(src)
end
end
- local sourceGets = vm.getLocalSourcesGets(source)
+ local sourceGets = vm.getLocalGets(source)
if sourceGets then
for _, src in ipairs(sourceGets) do
pushResult(src)
diff --git a/script/vm/visible.lua b/script/vm/visible.lua
index 0a0144b7..485063f8 100644
--- a/script/vm/visible.lua
+++ b/script/vm/visible.lua
@@ -76,7 +76,7 @@ end
---@return vm.global?
function vm.getDefinedClass(suri, source)
source = guide.getSelfNode(source) or source
- local sets = vm.getLocalSourcesSets(source)
+ local sets = vm.getLocalSets(source)
if sets then
for _, set in ipairs(sets) do
if set.bindDocs then