Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Schema #82

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 3 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

all: luv.so
all: luv

libuv/include:
git submodule update --init libuv
Expand All @@ -10,15 +10,13 @@ luajit/src:
build/Makefile: libuv/include luajit/src
cmake -H. -Bbuild

build/luv.so: build/Makefile
luv: build/Makefile
cmake --build build --config Release

luv.so: build/luv.so
ln -sf build/luv.so

clean:
rm -rf build luv.so

test: luv.so
test: luv
build/luajit tests/run.lua

33 changes: 23 additions & 10 deletions src/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,18 +254,31 @@ static int luv_fs_open(lua_State* L) {
}

static int luv_fs_read(lua_State* L) {
uv_file file = luaL_checkinteger(L, 1);
int64_t len = luaL_checkinteger(L, 2);
int64_t offset = luaL_checkinteger(L, 3);
uv_file file;
int64_t len, offset;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uint64_t?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just trying to match what libuv is expecting to go through minimal typecasts.
offset declared at https://github.com/joyent/libuv/blob/a4f88760be1838603fe2eae89a651066cc42eedd/include/uv.h#L1072
though I got size wrong, it should be unsigned int from https://github.com/joyent/libuv/blob/a4f88760be1838603fe2eae89a651066cc42eedd/include/uv.h#L416

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

k. that sounds reasonable.

uv_buf_t buf;
int ref;
uv_fs_t* req;
char* data = malloc(len);
if (!data) return luaL_error(L, "Failure to allocate buffer");
buf = uv_buf_init(data, len);
ref = luv_check_continuation(L, 4);
req = lua_newuserdata(L, sizeof(*req));
req->data = luv_setup_req(L, ref);

lschema_check(L, (lschema_entry[]) {
{"file", luv_isfile},
{"length", luv_ispositive},
{"offset", luv_ispositive},
{"callback", luv_iscontinuation},
{NULL}
});

file = lua_tointeger(L, 1);
len = lua_tointeger(L, 2);
offset = lua_tointeger(L, 3);
req = luv_push_req(L, 4, sizeof(*req));

buf.base = malloc(len);
if (!buf.base) {
req->data = luv_cleanup_req(L, req->data);
return luaL_error(L, "Failure to allocate buffer");
}
buf.len = len;

// TODO: find out why we can't just use req->ptr for the base
((luv_req_t*)req->data)->data = buf.base;
FS_CALL(read, req, file, &buf, 1, offset);
Expand Down
28 changes: 27 additions & 1 deletion src/lreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,31 @@
*/
#include "lreq.h"

static void* luv_push_req(lua_State* L, int index, size_t size) {
uv_req_t* req;
luv_req_t* data;

data = calloc(1, sizeof(*data));
if (!data) luaL_error(L, "Problem allocating luv request");

req = lua_newuserdata(L, size);
req->data = data;
luaL_getmetatable(L, "uv_req");
lua_setmetatable(L, -2);

lua_pushvalue(L, -1);
data->req_ref = luaL_ref(L, LUA_REGISTRYINDEX);
if (lua_isfunction(L, index)) {
lua_pushvalue(L, index);
data->callback_ref = luaL_ref(L, LUA_REGISTRYINDEX);;
}
else {
data->callback_ref = LUA_NOREF;
}

return req;
}


static int luv_check_continuation(lua_State* L, int index) {
if (lua_isnoneornil(L, index)) return LUA_NOREF;
Expand Down Expand Up @@ -61,9 +86,10 @@ static void luv_fulfill_req(lua_State* L, luv_req_t* data, int nargs) {
}
}

static void luv_cleanup_req(lua_State* L, luv_req_t* data) {
static luv_req_t* luv_cleanup_req(lua_State* L, luv_req_t* data) {
luaL_unref(L, LUA_REGISTRYINDEX, data->req_ref);
luaL_unref(L, LUA_REGISTRYINDEX, data->callback_ref);
free(data->data);
free(data);
return NULL;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return NULL? should it be void?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}
6 changes: 5 additions & 1 deletion src/lreq.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ typedef struct {
void* data; // extra data
} luv_req_t;

// Create a new userdata for a uv_req_t and setup it's data member
// Index if the stack index where the optional callback resides.
static void* luv_push_req(lua_State* L, int index, size_t size);

// Used in the top of a setup function to check the arg
// and ref the callback to an integer.
static int luv_check_continuation(lua_State* L, int index);
Expand All @@ -35,6 +39,6 @@ static luv_req_t* luv_setup_req(lua_State* L, int ref);

static void luv_fulfill_req(lua_State* L, luv_req_t* data, int nargs);

static void luv_cleanup_req(lua_State* L, luv_req_t* data);
static luv_req_t* luv_cleanup_req(lua_State* L, luv_req_t* data);

#endif
1 change: 1 addition & 0 deletions src/luv.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/

#include "luv.h"
#include "schema.c"
#include "util.c"
#include "lhandle.c"
#include "lreq.c"
Expand Down
1 change: 1 addition & 0 deletions src/luv.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ static uv_loop_t* luv_loop(lua_State* L);
// as you use a different lua_State and thread for each.
LUALIB_API int luaopen_luv (lua_State *L);

#include "schema.h"
#include "util.h"
#include "lhandle.h"
#include "lreq.h"
Expand Down
28 changes: 28 additions & 0 deletions src/schema.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,31 @@
* limitations under the License.
*
*/
#include "schema.h"

// Platform specefic file handle
static int luv_isfile(lua_State* L, int index) {
// TODO: this should act different on windows maybe.
return lua_isnumber(L, index);
}

// Optional function
static int luv_iscontinuation(lua_State* L, int index) {
return lua_isnone(L, index) || lua_isfunction(L, index);
}

static int luv_ispositive(lua_State* L, int index) {
return lua_isnumber(L, index) && lua_tonumber(L, index) >= 0;
}

void lschema_check(lua_State* L, lschema_entry schema[]) {
int num = lua_gettop(L) - 1;
int i;
for (i = 0; schema[i].name;) {
lschema_entry entry = schema[i++];
luaL_argcheck(L, entry.checker(L, i), i, entry.name);
}
if (num > i) {
luaL_argerror(L, i, "Too many arguments");
}
}
16 changes: 16 additions & 0 deletions src/schema.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#ifndef LSCHEMA_H
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

may as well add the license header.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

#define LSCHEMA_H

#include "luv.h"

typedef const struct {
const char* name;
int (*checker)(lua_State* L, int index);
} lschema_entry;

static int luv_isfile(lua_State* L, int index);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no static here, and the next 3 lines

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But they are static on the C file. Shouldn't they match? The use of header files at all is questionable with the current way it builds since you could never use these header files without also including the corresponding C files.

With dukluv I recently made the files actually standalone and link them together as a last step. It made the build a little slower and exported a lot more symbols into the final object, but it made my lint tool happier.

static int luv_iscontinuation(lua_State* L, int index);
static int luv_ispositive(lua_State* L, int index);
void lschema_check(lua_State* L, lschema_entry schema[]);

#endif