From cad34b796b14c1e9d9ae062339d7e9d4cd18cc22 Mon Sep 17 00:00:00 2001 From: Tom Lau Date: Mon, 1 Jul 2024 09:40:16 +0800 Subject: perf: Optimize undefined-field check early break logic The current early break only wants to check if there are any definition. There is no need to fetch the full definitions list. We can early break as soon as we found the 1st one. --- script/vm/def.lua | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'script/vm') diff --git a/script/vm/def.lua b/script/vm/def.lua index 5388a384..669d39c2 100644 --- a/script/vm/def.lua +++ b/script/vm/def.lua @@ -92,3 +92,42 @@ function vm.getDefs(source) return results end + +local HAS_DEF_ERR = {} -- the error object for comparing +local function checkHasDef(checkFunc, source, pushResult) + local _, err = pcall(checkFunc, source, pushResult) + return err == HAS_DEF_ERR +end + +---@param source parser.object +function vm.hasDef(source) + local mark = {} + local hasLocal + local function pushResult(src) + if src.type == 'local' then + if hasLocal then + return + end + hasLocal = true + if source.type ~= 'local' + and source.type ~= 'getlocal' + and source.type ~= 'setlocal' + and source.type ~= 'doc.cast.name' then + return + end + end + if not mark[src] then + mark[src] = true + if guide.isAssign(src) + or guide.isLiteral(src) then + -- break out on 1st result using error() with a unique error object + error(HAS_DEF_ERR) + end + end + end + + return checkHasDef(searchBySimple, source, pushResult) + or checkHasDef(searchByLocalID, source, pushResult) + or checkHasDef(vm.compileByNodeChain, source, pushResult) + or checkHasDef(searchByNode, source, pushResult) +end -- cgit v1.2.3