Fiberクラスの実装
monorubyにFiberクラスを実装した。
code: Ruby
fib = Fiber.new do
a = b = 1
loop do
Fiber.yield a
a, b = a + b, a
end
end
Fiber.new 新しいFiberを生成する
Fiber.yield Fiberの実行を中断し、値を親Fiberへ返す
Fiber#resume Fiberの実行を再開する
monorubyでの実装
Fiberオブジェクトを生成する際にExecutorを新しく生成し、1対1で紐づける。
Executorに対応するマシンスタック領域を準備する。
resume/yieldでスタックポインタを切り替える
Enumeratorクラスの実装
code:Ruby
fib = Enumerator.new do |y|
a = b = 1
loop do
y << a
a, b = a + b, a
end
end
fib.next
fib.each do |x|
if x > 30 then raise StopIteration end
puts x.to_s
end
code:Ruby
e.each do |x|
puts x
end
今後の課題
Fiber用のスタックプールを作って使いまわす。
Fiber.yield、Fiber#resumeのインライン化
code: Rust
extern "C" fn resume_fiber(vm: *mut Executor, child: &mut Executor, val: Value) -> Option<Value> {
unsafe {
std::arch::asm!(
"push r15",
"push r14",
"push r13",
"push r12",
"push rbx",
"push rbp",
"mov rsi + 24, rdi", // 呼び出し元のExecutorを毎回保存 "pop rbp",
"pop rbx",
"pop r12",
"pop r13",
"pop r14",
"pop r15",
"mov rax, rdx",
"ret",
options(noreturn)
);
}
}