Skip to content

Instantly share code, notes, and snippets.

@kazupon
Created September 25, 2012 17:16
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save kazupon/3783231 to your computer and use it in GitHub Desktop.
Save kazupon/3783231 to your computer and use it in GitHub Desktop.
lua: native C-API coroutine sample
print('load end.lua')
INCDIR = $(HOME)/opt/local/include/luajit-2.0
LIBDIR = $(HOME)/opt/local/lib
LIB = -lluajit-51
all: native
native:
cc --std=c99 -o native-co native.c -I$(INCDIR) -L$(LIBDIR) $(LIB) -pagezero_size 10000 -image_base 100000000
clean:
rm native-co
.PHONY: clean native
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <lua.h>
#include <lauxlib.h>
#define STACK_DUMP(L, Name) stack_dump(L, Name)
bool running;
void error(lua_State *L, const char *fmt, ...) {
va_list argp;
va_start(argp, fmt);
vfprintf(stderr, fmt, argp);
va_end(argp);
lua_close(L);
exit(EXIT_FAILURE);
}
static void stack_dump(lua_State *L, const char *stackname) {
int i;
int top = lua_gettop(L);
printf("--------------- %s STACK ---------------\n", stackname);
for (i = top; i >= 1; i--) {
int t = lua_type(L, i);
printf("[%2d - %8s] : ", i, lua_typename(L, t));
switch (t) {
case LUA_TSTRING:
printf("%s", lua_tostring(L, i));
break;
case LUA_TBOOLEAN:
printf(lua_toboolean(L, i) ? "true" : "false");
break;
case LUA_TNUMBER:
printf("%g", lua_tonumber(L, i));
break;
case LUA_TNIL:
printf("nil");
break;
case LUA_TNONE:
printf("none");
break;
case LUA_TFUNCTION:
printf("<function %p>", lua_topointer(L, i));
break;
case LUA_TTABLE:
printf("<table %p>", lua_topointer(L, i));
break;
case LUA_TTHREAD:
printf("<thread %p>", lua_topointer(L, i));
break;
case LUA_TUSERDATA:
printf("<userdata %p>", lua_topointer(L, i));
break;
case LUA_TLIGHTUSERDATA:
printf("<lightuserdata %p>", lua_topointer(L, i));
break;
default:
printf("unknown %s", lua_typename(L, t));
break;
}
printf("\n");
}
printf("--------------- %s STACK ---------------\n", stackname);
}
static int lua_cb(lua_State *L) {
printf("called lua_cb\n");
return 0;
}
static int lua_mynext(lua_State *L) {
printf("called lua_mynext\n");
lua_pushnumber(L, 1);
lua_pushnumber(L, 2);
lua_pushcfunction(L, lua_cb);
return lua_yield(L, 3);
}
int main (void) {
int status = 0;
int result = 0;
lua_State *L = luaL_newstate();
luaL_openlibs(L);
status = luaL_loadfile(L, "start.lua"); /* L[ function ] */
if (status) {
fprintf(stderr, "could not load start.lua: %s\n", lua_tostring(L, -1));
exit(1);
}
result = lua_pcall(L, 0, LUA_MULTRET, 0); /* L[ ] */
if (result) {
fprintf(stderr, "failed to run start.lua script: %s\n", lua_tostring(L, -1));
exit(1);
}
lua_State *L1 = lua_newthread(L);
luaL_openlibs(L1);
lua_register(L1, "next", lua_mynext);
luaL_dofile(L1, "proc.lua");
lua_getglobal(L1, "step");
do {
lua_pushnumber(L1, 1);
lua_pushstring(L1, "hello");
status = lua_resume(L1, 2);
printf("lua_resume: %d\n", status);
if (status == LUA_YIELD) {
lua_CFunction f = lua_tocfunction(L1, -1);
f(L1);
}
} while (status == LUA_YIELD);
status = luaL_loadfile(L, "end.lua");
if (status) {
fprintf(stderr, "could not load end.lua: %s\n", lua_tostring(L, -1));
exit(1);
}
result = lua_pcall(L, 0, LUA_MULTRET, 0);
if (result) {
fprintf(stderr, "failed to run end.lua script: %s\n", lua_tostring(L, -1));
exit(1);
}
lua_close(L);
return 0;
}
--[[
local i = 0
while true do
print('iterate', i)
sleep(1000000)
i = i + 1
if i == 4 then
print('bkrea!')
break
end
end
--]]
function step ()
print('next', next(1))
print('next', next('hello', 2))
print('next', next(function () end))
end
--finish()
print('load proc.lua')
print('load start.lua')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment