Coco API Extensions

LuaJIT

# Coco API Extensions

Coco changes the semantics of several standard API functions and provides a few API extensions for Lua.

By default all your coroutines get an associated C stack. If you want to be more selective, see below.

## Lua API extensions

All `coroutine.*` functions should be fully upwards compatible.

### `coroutine.coco`

This field is `true` when Coco is present (nil otherwise).

### `coro = coroutine.create(f [, cstacksize])
func = coroutine.wrap(f [, cstacksize])`

The optional argument `cstacksize` specifies the size of the C stack to allocate for the coroutine:

- A default stack size is used if `cstacksize` is not given or is nil or zero.
- No C stack is allocated if `cstacksize` is -1.
- Any other value is rounded up to the minimum size (i.e. use 1 to get the minimum size).

Important notice for LuaJIT: JIT compiled functions cannot yield if a coroutine does not have a dedicated C stack.

### `olddefault = coroutine.cstacksize([newdefault])`

Returns the current default C stack size (may be 0 if the underlying context switch method has its own default). Sets a new default C stack size if `newdefault` is present. Use 0 to reset it to the default C stack size. Any other value is rounded up to the minimum size.

## C API extensions

All C API functions are either unchanged or upwards compatible.

### `int lua_yield(lua_State *L, int nresults)`

The semantics for `lua_yield()` have changed slightly. Existing programs should work fine as long as they follow the usage conventions from the Lua manual:

    return lua_yield(L, nresults);

Previously `lua_yield()` returned a 'magic' value (`-1`) that indicated a yield. Your C function had to pass this value on to the Lua core and was not called again.

Now, if the current coroutine has an associated C stack, `lua_yield()` returns the number of arguments passed back from the resume. This just happens to be the right convention for returning them as a result from a C function. I.e. if you used the above convention, you'll never notice the change.

But the results are on the Lua stack when `lua_yield()` returns. So the C function can just continue and process them or retry an I/O operation etc. And your whole C stack frame (local variables etc.) is still there, too. You can yield from anywhere in your C program, even several call levels deeper.

Of course all of this only works with Lua+Coco and not with standard Lua.

### `lua_State *lua_newcthread(lua_State *L, int cstacksize)`

This is an (optional) new function that allows you to create a coroutine with an associated C stack directly from the C API. Other than that it works the same as `lua_newthread(L)`.

You have to declare this function as `extern` yourself, since it's not part of the official Lua API. This means that a C module that uses this call cannot be loaded with standard Lua. This may be intentional.

If you want your C module to work with both standard Lua and Lua+Coco you can check whether Coco is available with:

      lua_getfield(L, LUA_GLOBALSINDEX, "coroutine");
      lua_getfield(L, -1, "coco");
      coco_available = lua_toboolean(L, -1);
      lua_pop(L, 2);

You can create coroutines with a C stack by calling the Lua function `coroutine.create()` from C, too.

Copyright © 2005-2008 Mike Pall · Contact