fix(lua): обходим wasmoon null.then bug — __rbxl_drain_handler возвращает 1

Корень: wasmoon Promise-detection (строка 1026 в index.js):
  if (Promise.resolve(target) === target || typeof target.then === 'function')
typeof null === 'object' → проходит проверку → target.then на null → crash.

Когда __rbxl_drain_handler возвращался nil → wasmoon видел null → крашился.

Фикс: возвращаем число 1 явно из coroutine.create body и из самой
drain_handler. Это не-объект — проверка Promise-detection не сработает.
This commit is contained in:
min 2026-06-09 10:12:36 +03:00
parent eae2ad7cc5
commit eddf0b5a23

View File

@ -1748,22 +1748,19 @@ export function registerRobloxShim(lua, opts) {
debug.sethook(function() debug.sethook(function()
coroutine.yield(0.016) coroutine.yield(0.016)
end, "", 20000) end, "", 20000)
local ok, err = pcall(fn, a1, a2, a3, a4) -- ВНУТРЕННИЙ pcall: игнорирует runtime errors handler'а
if not ok then -- ВНЕШНИЙ pcall: ловит yield-across-C-boundary
__log("error", "[handler-fn-error] " .. tostring(err)) -- Все возвращаемые значения отбрасываем (не возвращаем из coroutine
end -- что-либо, чтобы wasmoon Promise-detection не сработал на null).
pcall(function() pcall(fn, a1, a2, a3, a4) end)
return 1 -- возвращаем НЕ-nil чтобы wasmoon не падал на null.then
end) end)
__rbxl_register_coroutine(handlerId, co) __rbxl_register_coroutine(handlerId, co)
local ok, ret = coroutine.resume(co) pcall(coroutine.resume, co)
if not ok then if coroutine.status(co) == 'dead' then
__log("error", "[handler-resume-error] " .. tostring(ret))
__rbxl_send_error(handlerId, tostring(ret))
__rbxl_unregister_coroutine(handlerId)
elseif type(ret) == 'number' then
__rbxl_schedule_resume(handlerId, ret)
elseif coroutine.status(co) == 'dead' then
__rbxl_unregister_coroutine(handlerId) __rbxl_unregister_coroutine(handlerId)
end end
return 1 -- возвращаем НЕ-nil
end end
`); `);
// Кешируем ссылку на Lua-функцию запуска handler'а // Кешируем ссылку на Lua-функцию запуска handler'а