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()
coroutine.yield(0.016)
end, "", 20000)
local ok, err = pcall(fn, a1, a2, a3, a4)
if not ok then
__log("error", "[handler-fn-error] " .. tostring(err))
end
-- ВНУТРЕННИЙ pcall: игнорирует runtime errors handler'а
-- ВНЕШНИЙ pcall: ловит yield-across-C-boundary
-- Все возвращаемые значения отбрасываем (не возвращаем из coroutine
-- что-либо, чтобы wasmoon Promise-detection не сработал на null).
pcall(function() pcall(fn, a1, a2, a3, a4) end)
return 1 -- возвращаем НЕ-nil чтобы wasmoon не падал на null.then
end)
__rbxl_register_coroutine(handlerId, co)
local ok, ret = coroutine.resume(co)
if not ok 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
pcall(coroutine.resume, co)
if coroutine.status(co) == 'dead' then
__rbxl_unregister_coroutine(handlerId)
end
return 1 -- возвращаем НЕ-nil
end
`);
// Кешируем ссылку на Lua-функцию запуска handler'а