Внутри песочницы coroutine.yield переопределён:
yield = function(...) -- custom yield part for bubbling sysyields
return coroutine.yield(nil, ...)
end
Также переопределён и coroutine.resume.
resume = function(co, ...) -- custom resume part for bubbling sysyields
checkArg(1, co, "thread")
local args = table.pack(...)
while true do -- for consecutive sysyields
debug.sethook(co, checkDeadline, "", hookInterval)
local result = table.pack(
coroutine.resume(co, table.unpack(args, 1, args.n)))
debug.sethook(co) -- avoid gc issues
checkDeadline()
if result[1] then -- success: (true, sysval?, ...?)
if coroutine.status(co) == "dead" then -- return: (true, ...)
return true, table.unpack(result, 2, result.n)
elseif result[2] ~= nil then -- yield: (true, sysval)
args = table.pack(coroutine.yield(result[2]))
else -- yield: (true, nil, ...)
return true, table.unpack(result, 3, result.n)
end
else -- error: result = (false, string)
return false, result[2]
end
end
end
Работает это так:
Если корутина вернула true, nil, ... — отдать true, ... (поэтому внутри песочницы разница между обычными и переопределёнными функциями не видна).
Если корутина йелднулась без нила в начале, то это "системный вызов". Потому что доступ к непереопределённой функции coroutine.yield есть только внутри machine.lua. В таком случае йелдится и текущая корутина вверх по цепочке.
EEPROM запускается в корутине. Если корутина эта йелдится, случается следующее:
yield(false) — это выключить компьютер;
yield(true) — ребутнуть его;
yield(n), где type(n) == "number", — спать n секунд;
yield(f), где type(f) == "function", — это вызвать непрямую функцию.
yield с любым другим аргументом — спать до скончания века.
Дополнительно обрабатывается умирание корутины: return посреди еепрома — это error("computer halted", 0); другие ошибки прокидываются.
А теперь смотрим на наш вызов.
В EEPROM вызвана coroutine.yield(0).
Эта функция переопределена, чтобы вызвать нативный coroutine.yield(nil, 0).
Корутина тогда йелдится и отдаёт nil, 0.
В списке выше это пункт 3.5. Компьютер уйдёт в вечный сон.
Ну, конечно, я преувеличиваю. Компьютер спит до момента получения сигнала и, получив, продолжит работу.
Но вообще, незачем звать coroutine.yield напрямую. Есть computer.pullSignal, computer.shutdown, component.invoke(addr, nonDirectMethod, ...).