Ejemplo n.º 1
0
  Fiber* Fiber::current(STATE) {
#ifdef RBX_FIBER_ENABLED
    Fiber* fib = state->vm()->current_fiber.get();

    // Lazily allocate a root fiber.
    if(fib->nil_p()) {
      fib = state->memory()->new_object<Fiber>(state, G(fiber));
      fib->root(true);
      fib->status(Fiber::eRunning);

      fib->data(state->vm()->new_fiber_data(true, fib->stack_size()->to_native()));
      fib->data()->set_call_frame(state->vm()->call_frame());

      state->memory()->native_finalizer(state, fib,
          (memory::FinalizerFunction)&Fiber::finalize);

      state->vm()->current_fiber.set(fib);
      state->vm()->root_fiber.set(fib);
    }

    return fib;
#else
    Exception::raise_not_implemented_error(state, "Fibers not supported on this platform");
#endif
  }
Ejemplo n.º 2
0
  Object* Fiber::s_yield(STATE, Arguments& args) {
#ifdef RBX_FIBER_ENABLED
    Fiber* cur = Fiber::current(state);
    Fiber* dest_fib = cur->prev();

    assert(cur != dest_fib);

    if(cur->root()) {
      Exception::raise_fiber_error(state, "can't yield from root fiber");
    }

    cur->prev(state, nil<Fiber>());

    Array* val = args.as_array(state);
    dest_fib->value(state, val);

    cur->sleep(state);

    dest_fib->run(state);

    dest_fib->data()->switch_to(state, cur->data());

    // Back here when someone yields back to us!
    // Beware here, because the GC has probably run so GC pointers on the C++ stack
    // can't be accessed.

    cur = Fiber::current(state);

    Array* ret = cur->value();

    if(ret->nil_p()) return cNil;

    switch(ret->size()) {
    case 0:  return cNil;
    case 1:  return ret->get(state, 0);
    default: return ret;
    }
#else
    Exception::raise_not_implemented_error(state, "Fibers not supported on this platform");
#endif
  }