summaryrefslogtreecommitdiff
path: root/script/vm/getMeta.lua
diff options
context:
space:
mode:
Diffstat (limited to 'script/vm/getMeta.lua')
-rw-r--r--script/vm/getMeta.lua52
1 files changed, 52 insertions, 0 deletions
diff --git a/script/vm/getMeta.lua b/script/vm/getMeta.lua
new file mode 100644
index 00000000..aebef1a7
--- /dev/null
+++ b/script/vm/getMeta.lua
@@ -0,0 +1,52 @@
+local vm = require 'vm.vm'
+
+local function eachMetaOfArg1(source, callback)
+ local node, index = vm.getArgInfo(source)
+ local special = vm.getSpecial(node)
+ if special == 'setmetatable' and index == 1 then
+ local mt = node.next.args[2]
+ if mt then
+ callback(mt)
+ end
+ end
+end
+
+local function eachMetaOfRecv(source, callback)
+ if not source or source.type ~= 'select' then
+ return
+ end
+ if source.index ~= 1 then
+ return
+ end
+ local call = source.vararg
+ if not call or call.type ~= 'call' then
+ return
+ end
+ local special = vm.getSpecial(call.node)
+ if special ~= 'setmetatable' then
+ return
+ end
+ local mt = call.args[2]
+ if mt then
+ callback(mt)
+ end
+end
+
+function vm.eachMetaValue(source, callback)
+ vm.eachMeta(source, function (mt)
+ for _, src in ipairs(vm.getFields(mt)) do
+ if vm.getKeyName(src) == 's|__index' then
+ if src.value then
+ for _, valueSrc in ipairs(vm.getFields(src.value)) do
+ callback(valueSrc)
+ end
+ end
+ end
+ end
+ end)
+end
+
+function vm.eachMeta(source, callback)
+ eachMetaOfArg1(source, callback)
+ eachMetaOfRecv(source.value, callback)
+end