fix match intern mt and stackvalues

This commit is contained in:
zixun
2019-10-21 11:38:08 +08:00
committed by 云风
parent 8a1d7006eb
commit f17c17b8c7
2 changed files with 37 additions and 18 deletions

View File

@@ -92,17 +92,15 @@ lco_stackvalues(lua_State* L) {
luaL_checktype(L, 2, LUA_TTABLE); luaL_checktype(L, 2, LUA_TTABLE);
n = lua_gettop(cL); n = lua_gettop(cL);
if(n > 0) { if(n > 0) {
lua_checkstack(L, n+1); luaL_checkstack(L, n+1, NULL);
int top = lua_gettop(L); int top = lua_gettop(L);
lua_xmove(cL, L, n); lua_xmove(cL, L, n);
int i=0; int i=0;
for(i=0; i<n; i++) { for(i=1; i<=n; i++) {
lua_pushvalue(L, top+1+i); lua_pushvalue(L, top+i);
lua_seti(L, 2, i+1); lua_seti(L, 2, i);
} }
lua_xmove(L, cL, n); lua_xmove(L, cL, n);
} else {
n = 0;
} }
} }

View File

@@ -275,23 +275,40 @@ local function resolve_replace(replace_map)
end end
local function match_mt(v) local function match_mt(v)
local mt = getmetatable(v) local mt = debug.getmetatable(v)
if mt then if mt then
local nv = replace_map[mt] local nv = replace_map[mt]
if nv then if nv then
nv = getnv(mt) nv = getnv(mt)
setmetatable(v, nv) debug.setmetatable(v, nv)
else else
match_value(mt) match_value(mt)
end end
end end
end end
local function match_internmt()
local internal_types = {
pointer = debug.upvalueid(getnv, 1),
boolean = false,
str = "",
number = 42,
thread = coroutine.running(),
func = getnv,
}
for _,v in pairs(internal_types) do
match_mt(v)
end
match_mt(nil)
end
local function match_table(t) local function match_table(t)
local keys = {} local keys = false
for k,v in next, t do for k,v in next, t do
local tk = type(k) local tk = type(k)
if match[tk] then if match[tk] then
keys = keys or {}
keys[#keys+1] = k keys[#keys+1] = k
end end
@@ -304,17 +321,19 @@ local function resolve_replace(replace_map)
end end
end end
for _, old_k in ipairs(keys) do if keys then
local new_k = replace_map[old_k] for _, old_k in ipairs(keys) do
if new_k then local new_k = replace_map[old_k]
local value = rawget(t, old_k)
new_k = getnv(old_k)
rawset(t, old_k, nil)
if new_k then if new_k then
rawset(t, new_k, value) local value = rawget(t, old_k)
new_k = getnv(old_k)
rawset(t, old_k, nil)
if new_k then
rawset(t, new_k, value)
end
else
match_value(old_k)
end end
else
match_value(old_k)
end end
end end
match_mt(t) match_mt(t)
@@ -414,6 +433,8 @@ local function resolve_replace(replace_map)
match["userdata"] = match_userdata match["userdata"] = match_userdata
match["thread"] = match_thread match["thread"] = match_thread
match_internmt()
local root = debug.getregistry() local root = debug.getregistry()
assert(replace_map[root] == nil) assert(replace_map[root] == nil)
match_table(root) match_table(root)