Skip to content

Commit b4524f0

Browse files
committed
improve performance
1 parent 54e6260 commit b4524f0

File tree

6 files changed

+83
-53
lines changed

6 files changed

+83
-53
lines changed

script/vm/compiler.lua

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ local vm = require 'vm.vm'
1818

1919
local searchFieldSwitch = util.switch()
2020
: case 'table'
21-
: call(function (suri, source, key, pushResult)
21+
: call(function (suri, source, key, ref, pushResult)
2222
local hasFiled = false
2323
for _, field in ipairs(source) do
2424
if field.type == 'tablefield'
@@ -52,16 +52,16 @@ local searchFieldSwitch = util.switch()
5252
end
5353
end)
5454
: case 'string'
55-
: call(function (suri, source, key, pushResult)
55+
: call(function (suri, source, key, ref, pushResult)
5656
-- change to `string: stringlib` ?
5757
local stringlib = globalMgr.getGlobal('type', 'stringlib')
5858
if stringlib then
59-
vm.getClassFields(suri, stringlib, key, pushResult)
59+
vm.getClassFields(suri, stringlib, key, ref, pushResult)
6060
end
6161
end)
6262
: case 'local'
6363
: case 'self'
64-
: call(function (suri, node, key, pushResult)
64+
: call(function (suri, node, key, ref, pushResult)
6565
local fields
6666
if key then
6767
fields = localID.getSources(node, key)
@@ -70,12 +70,14 @@ local searchFieldSwitch = util.switch()
7070
end
7171
if fields then
7272
for _, src in ipairs(fields) do
73-
pushResult(src)
73+
if ref or guide.isSet(src) then
74+
pushResult(src)
75+
end
7476
end
7577
end
7678
end)
7779
: case 'doc.type.array'
78-
: call(function (suri, source, key, pushResult)
80+
: call(function (suri, source, key, ref, pushResult)
7981
if type(key) == 'number' then
8082
if key < 1
8183
or not math.tointeger(key) then
@@ -85,7 +87,7 @@ local searchFieldSwitch = util.switch()
8587
pushResult(source.node)
8688
end)
8789
: case 'doc.type.table'
88-
: call(function (suri, source, key, pushResult)
90+
: call(function (suri, source, key, ref, pushResult)
8991
for _, field in ipairs(source.fields) do
9092
local fieldKey = field.name
9193
if fieldKey.type == 'doc.type' then
@@ -111,7 +113,7 @@ local searchFieldSwitch = util.switch()
111113
end
112114
end)
113115
: case 'global'
114-
: call(function (suri, node, key, pushResult)
116+
: call(function (suri, node, key, ref, pushResult)
115117
if node.cate == 'variable' then
116118
if key then
117119
if type(key) ~= 'string' then
@@ -122,8 +124,10 @@ local searchFieldSwitch = util.switch()
122124
for _, set in ipairs(global:getSets(suri)) do
123125
pushResult(set)
124126
end
125-
for _, get in ipairs(global:getGets(suri)) do
126-
pushResult(get)
127+
if ref then
128+
for _, get in ipairs(global:getGets(suri)) do
129+
pushResult(get)
130+
end
127131
end
128132
end
129133
else
@@ -132,17 +136,19 @@ local searchFieldSwitch = util.switch()
132136
for _, set in ipairs(global:getSets(suri)) do
133137
pushResult(set)
134138
end
135-
for _, get in ipairs(global:getGets(suri)) do
136-
pushResult(get)
139+
if ref then
140+
for _, get in ipairs(global:getGets(suri)) do
141+
pushResult(get)
142+
end
137143
end
138144
end
139145
end
140146
end
141147
if node.cate == 'type' then
142-
vm.getClassFields(suri, node, key, pushResult)
148+
vm.getClassFields(suri, node, key, ref, pushResult)
143149
end
144150
end)
145-
: default(function (suri, source, key, pushResult)
151+
: default(function (suri, source, key, ref, pushResult)
146152
local node = source._globalNode
147153
if not node then
148154
return
@@ -174,12 +180,12 @@ local searchFieldSwitch = util.switch()
174180
end
175181
end
176182
if node.cate == 'type' then
177-
vm.getClassFields(suri, node, key, pushResult)
183+
vm.getClassFields(suri, node, key, ref, pushResult)
178184
end
179185
end)
180186

181187

182-
function vm.getClassFields(suri, node, key, pushResult)
188+
function vm.getClassFields(suri, node, key, ref, pushResult)
183189
local mark = {}
184190

185191
local function searchClass(class, searchedFields)
@@ -206,7 +212,7 @@ function vm.getClassFields(suri, node, key, pushResult)
206212
-- check local field and global field
207213
if set.bindSources then
208214
for _, src in ipairs(set.bindSources) do
209-
searchFieldSwitch(src.type, suri, src, key, function (field)
215+
searchFieldSwitch(src.type, suri, src, key, ref, function (field)
210216
local fieldKey = guide.getKeyName(field)
211217
if not searchedFields[fieldKey]
212218
and guide.isSet(field) then
@@ -215,7 +221,7 @@ function vm.getClassFields(suri, node, key, pushResult)
215221
end
216222
end)
217223
if src.value and src.value.type == 'table' then
218-
searchFieldSwitch('table', suri, src.value, key, function (field)
224+
searchFieldSwitch('table', suri, src.value, key, ref, function (field)
219225
local fieldKey = guide.getKeyName(field)
220226
if not searchedFields[fieldKey]
221227
and guide.isSet(field) then
@@ -361,7 +367,7 @@ local function getReturnOfSetMetaTable(args)
361367
node:merge(vm.compileNode(tbl))
362368
end
363369
if mt then
364-
vm.compileByParentNode(mt, '__index', function (src)
370+
vm.compileByParentNode(mt, '__index', false, function (src)
365371
for n in vm.compileNode(src):eachObject() do
366372
if n.type == 'global'
367373
or n.type == 'local'
@@ -529,11 +535,11 @@ end
529535
---@param source vm.node
530536
---@param key? any
531537
---@param pushResult fun(source: parser.object)
532-
function vm.compileByParentNode(source, key, pushResult)
538+
function vm.compileByParentNode(source, key, ref, pushResult)
533539
local parentNode = vm.compileNode(source)
534540
local suri = guide.getUri(source)
535541
for node in parentNode:eachObject() do
536-
searchFieldSwitch(node.type, suri, node, key, pushResult)
542+
searchFieldSwitch(node.type, suri, node, key, ref, pushResult)
537543
end
538544
end
539545

@@ -903,7 +909,7 @@ local compilerSwitch = util.switch()
903909
if key == nil then
904910
return
905911
end
906-
vm.compileByParentNode(source.node, key, function (src)
912+
vm.compileByParentNode(source.node, key, false, function (src)
907913
if src.type == 'doc.type.field'
908914
or src.type == 'doc.field' then
909915
vm.setNode(source, vm.compileNode(src))
@@ -929,7 +935,7 @@ local compilerSwitch = util.switch()
929935
vm.setNode(source, value)
930936
end
931937
else
932-
vm.compileByParentNode(source.node, key, function (src)
938+
vm.compileByParentNode(source.node, key, false, function (src)
933939
vm.setNode(source, vm.compileNode(src))
934940
end)
935941
end
@@ -940,7 +946,7 @@ local compilerSwitch = util.switch()
940946
return
941947
end
942948
local key = guide.getKeyName(source)
943-
vm.compileByParentNode(source.node, key, function (src)
949+
vm.compileByParentNode(source.node, key, false, function (src)
944950
if src.type == 'doc.type.field'
945951
or src.type == 'doc.field' then
946952
vm.setNode(source, vm.compileNode(src))
@@ -953,7 +959,7 @@ local compilerSwitch = util.switch()
953959
return
954960
end
955961
local key = guide.getKeyName(source)
956-
vm.compileByParentNode(source.node, key, function (src)
962+
vm.compileByParentNode(source.node, key, false, function (src)
957963
vm.setNode(source, vm.compileNode(src))
958964
end)
959965
end)
@@ -976,7 +982,7 @@ local compilerSwitch = util.switch()
976982
end
977983

978984
if not hasMarkDoc then
979-
vm.compileByParentNode(source.parent, guide.getKeyName(source), function (src)
985+
vm.compileByParentNode(source.parent, guide.getKeyName(source), false, function (src)
980986
vm.setNode(source, vm.compileNode(src))
981987
end)
982988
end

script/vm/def.lua

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ local searchFieldSwitch = util.switch()
105105
end
106106
end
107107
if obj.cate == 'type' then
108-
vm.getClassFields(suri, obj, key, pushResult)
108+
vm.getClassFields(suri, obj, key, false, pushResult)
109109
end
110110
end)
111111
: case 'local'
@@ -131,36 +131,48 @@ local searchFieldSwitch = util.switch()
131131
end
132132
end)
133133

134-
local searchByParentNode
135-
local nodeSwitch = util.switch()
134+
local nodeSwitch;nodeSwitch = util.switch()
136135
: case 'field'
137136
: case 'method'
138-
: call(function (source, pushResult)
139-
searchByParentNode(source.parent, pushResult)
137+
: call(function (source, lastKey, pushResult)
138+
return nodeSwitch(source.parent.type, source.parent, lastKey, pushResult)
140139
end)
141140
: case 'getfield'
142141
: case 'setfield'
143142
: case 'getmethod'
144143
: case 'setmethod'
145144
: case 'getindex'
146145
: case 'setindex'
147-
: call(function (source, pushResult)
146+
: call(function (source, lastKey, pushResult)
148147
local parentNode = vm.compileNode(source.node)
149148
local uri = guide.getUri(source)
150149
local key = guide.getKeyName(source)
150+
if not key then
151+
return
152+
end
153+
if lastKey then
154+
key = key .. vm.ID_SPLITE .. lastKey
155+
end
151156
for pn in parentNode:eachObject() do
152157
searchFieldSwitch(pn.type, uri, pn, key, pushResult)
153158
end
159+
return key, source.node
154160
end)
155161
: case 'tableindex'
156162
: case 'tablefield'
157-
: call(function (source, pushResult)
163+
: call(function (source, lastKey, pushResult)
164+
if lastKey then
165+
return
166+
end
158167
local tbl = source.parent
159168
local uri = guide.getUri(source)
160169
searchFieldSwitch(tbl.type, uri, tbl, guide.getKeyName(source), pushResult)
161170
end)
162171
: case 'doc.see.field'
163-
: call(function (source, pushResult)
172+
: call(function (source, lastKey, pushResult)
173+
if lastKey then
174+
return
175+
end
164176
local parentNode = vm.compileNode(source.parent.name)
165177
local uri = guide.getUri(source)
166178
for pn in parentNode:eachObject() do
@@ -190,8 +202,21 @@ end
190202

191203
---@param source parser.object
192204
---@param pushResult fun(src: parser.object)
193-
function searchByParentNode(source, pushResult)
194-
nodeSwitch(source.type, source, pushResult)
205+
local function searchByParentNode(source, pushResult)
206+
local lastKey
207+
local src = source
208+
while true do
209+
local key, node = nodeSwitch(src.type, src, lastKey, pushResult)
210+
if not key then
211+
break
212+
end
213+
src = node
214+
if lastKey then
215+
lastKey = key .. vm.ID_SPLITE .. lastKey
216+
else
217+
lastKey = key
218+
end
219+
end
195220
end
196221

197222
local function searchByNode(source, pushResult)

script/vm/field.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ local searchByNodeSwitch = util.switch()
1717

1818
local function searchByNode(source, pushResult)
1919
local uri = guide.getUri(source)
20-
vm.compileByParentNode(source, nil, function (field)
20+
vm.compileByParentNode(source, nil, true, function (field)
2121
searchByNodeSwitch(field.type, uri, field, pushResult)
2222
end)
2323
end

script/vm/global-manager.lua

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ m.globals = {}
1616
---@type table<uri, table<string, boolean>>
1717
m.globalSubs = util.multiTable(2)
1818

19-
m.ID_SPLITE = '\x1F'
20-
2119
local compilerGlobalSwitch = util.switch()
2220
: case 'local'
2321
: call(function (source)
@@ -76,7 +74,7 @@ local compilerGlobalSwitch = util.switch()
7674
if parentName == '_G' then
7775
name = keyName
7876
else
79-
name = ('%s%s%s'):format(parentName, m.ID_SPLITE, keyName)
77+
name = ('%s%s%s'):format(parentName, vm.ID_SPLITE, keyName)
8078
end
8179
elseif source.node.special == '_G' then
8280
name = keyName
@@ -104,7 +102,7 @@ local compilerGlobalSwitch = util.switch()
104102
if parentName == '_G' then
105103
name = keyName
106104
else
107-
name = ('%s%s%s'):format(parentName, m.ID_SPLITE, keyName)
105+
name = ('%s%s%s'):format(parentName, vm.ID_SPLITE, keyName)
108106
end
109107
elseif source.node.special == '_G' then
110108
name = keyName
@@ -227,7 +225,7 @@ end
227225
function m.getGlobal(cate, name, field)
228226
local key = cate .. '|' .. name
229227
if field then
230-
key = key .. m.ID_SPLITE .. field
228+
key = key .. vm.ID_SPLITE .. field
231229
end
232230
return m.globals[key]
233231
end
@@ -244,8 +242,8 @@ function m.getFields(cate, name)
244242
for gid, global in pairs(m.globals) do
245243
if gid ~= key
246244
and util.stringStartWith(gid, key)
247-
and gid:sub(#key + 1, #key + 1) == m.ID_SPLITE
248-
and not gid:find(m.ID_SPLITE, #key + 2) then
245+
and gid:sub(#key + 1, #key + 1) == vm.ID_SPLITE
246+
and not gid:find(vm.ID_SPLITE, #key + 2) then
249247
globals[#globals+1] = global
250248
end
251249
end
@@ -266,7 +264,7 @@ function m.getGlobals(cate)
266264
local clock = os.clock()
267265
for gid, global in pairs(m.globals) do
268266
if util.stringStartWith(gid, cate)
269-
and not gid:find(m.ID_SPLITE) then
267+
and not gid:find(vm.ID_SPLITE) then
270268
globals[#globals+1] = global
271269
end
272270
end

0 commit comments

Comments
 (0)