Skip to content
Snippets Groups Projects
Commit 346f0c1e authored by Roman Tsisyk's avatar Roman Tsisyk
Browse files

Rewrite tuple[x] and #tuple bindings using FFI

parent 07d6a020
No related branches found
No related tags found
No related merge requests found
...@@ -111,14 +111,6 @@ lbox_tuple_gc(struct lua_State *L) ...@@ -111,14 +111,6 @@ lbox_tuple_gc(struct lua_State *L)
return 0; return 0;
} }
static int
lbox_tuple_len(struct lua_State *L)
{
struct tuple *tuple = lua_checktuple(L, 1);
lua_pushnumber(L, tuple_arity(tuple));
return 1;
}
static int static int
lbox_tuple_slice(struct lua_State *L) lbox_tuple_slice(struct lua_State *L)
{ {
...@@ -425,37 +417,6 @@ lbox_tuple_totable(struct lua_State *L) ...@@ -425,37 +417,6 @@ lbox_tuple_totable(struct lua_State *L)
return 1; return 1;
} }
/**
* Implementation of tuple __index metamethod.
*
* Provides operator [] access to individual fields for integer
* indexes, as well as searches and invokes metatable methods
* for strings.
*/
static int
lbox_tuple_index(struct lua_State *L)
{
struct tuple *tuple = lua_checktuple(L, 1);
/* For integer indexes, implement [] operator */
if (lua_isnumber(L, 2)) {
int i = luaL_checkint(L, 2);
const char *field = tuple_field(tuple, i);
if (field == NULL) {
const char *data = tuple->data;
luaL_error(L, "%s: index %d is out of bounds (0..%d)",
tuplelib_name, i, mp_decode_array(&data));
}
luamp_decode(L, &field);
return 1;
}
/* If we got a string, try to find a method for it. */
const char *sz = luaL_checkstring(L, 2);
lua_getmetatable(L, 1);
lua_getfield(L, -1, sz);
return 1;
}
void void
lbox_pushtuple(struct lua_State *L, struct tuple *tuple) lbox_pushtuple(struct lua_State *L, struct tuple *tuple)
{ {
...@@ -524,8 +485,6 @@ lbox_tuple_pairs(struct lua_State *L) ...@@ -524,8 +485,6 @@ lbox_tuple_pairs(struct lua_State *L)
static const struct luaL_reg lbox_tuple_meta[] = { static const struct luaL_reg lbox_tuple_meta[] = {
{"__gc", lbox_tuple_gc}, {"__gc", lbox_tuple_gc},
{"__len", lbox_tuple_len},
{"__index", lbox_tuple_index},
{"next", lbox_tuple_next}, {"next", lbox_tuple_next},
{"pairs", lbox_tuple_pairs}, {"pairs", lbox_tuple_pairs},
{"slice", lbox_tuple_slice}, {"slice", lbox_tuple_slice},
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
local ffi = require('ffi') local ffi = require('ffi')
local yaml = require('yaml') local yaml = require('yaml')
local msgpackffi = require('msgpackffi')
ffi.cdef([[ ffi.cdef([[
struct tuple struct tuple
...@@ -12,6 +13,11 @@ struct tuple ...@@ -12,6 +13,11 @@ struct tuple
uint32_t _bsize; uint32_t _bsize;
char data[0]; char data[0];
} __attribute__((packed)); } __attribute__((packed));
uint32_t
tuple_arity(const struct tuple *tuple);
const char *
tuple_field(const struct tuple *tuple, uint32_t i);
]]) ]])
local builtin = ffi.C local builtin = ffi.C
...@@ -33,10 +39,19 @@ local methods = { ...@@ -33,10 +39,19 @@ local methods = {
local tuple_gc = cfuncs.__gc; local tuple_gc = cfuncs.__gc;
local tuple_field = cfuncs.__index local tuple_field = function(tuple, field_n)
local field = builtin.tuple_field(tuple, field_n)
if field == nil then
return nil
end
return msgpackffi.decode_unchecked(field)
end
ffi.metatype('struct tuple', { ffi.metatype('struct tuple', {
__gc = tuple_gc; __gc = tuple_gc;
__len = cfuncs.__len; __len = function(tuple)
return builtin.tuple_arity(tuple)
end;
__tostring = function(tuple) __tostring = function(tuple)
-- Unpack tuple, call yaml.encode, remove yaml header and footer -- Unpack tuple, call yaml.encode, remove yaml header and footer
-- 5 = '---\n\n' (header), -6 = '\n...\n' (footer) -- 5 = '---\n\n' (header), -6 = '\n...\n' (footer)
......
...@@ -206,7 +206,7 @@ tuple_format(const struct tuple *tuple) ...@@ -206,7 +206,7 @@ tuple_format(const struct tuple *tuple)
* @param tuple * @param tuple
* @return the number of fields in tuple * @return the number of fields in tuple
*/ */
static inline uint32_t extern "C" inline uint32_t
tuple_arity(const struct tuple *tuple) tuple_arity(const struct tuple *tuple)
{ {
const char *data = tuple->data; const char *data = tuple->data;
...@@ -220,7 +220,7 @@ tuple_arity(const struct tuple *tuple) ...@@ -220,7 +220,7 @@ tuple_arity(const struct tuple *tuple)
* @pre field < tuple->field_count. * @pre field < tuple->field_count.
* @returns field data if field exists or NULL * @returns field data if field exists or NULL
*/ */
static inline const char * inline const char *
tuple_field_old(const struct tuple_format *format, tuple_field_old(const struct tuple_format *format,
const struct tuple *tuple, uint32_t i) const struct tuple *tuple, uint32_t i)
{ {
...@@ -261,7 +261,7 @@ tuple_field_old(const struct tuple_format *format, ...@@ -261,7 +261,7 @@ tuple_field_old(const struct tuple_format *format,
* or NULL if field is out of range * or NULL if field is out of range
* @param len pointer where the len of the field will be stored * @param len pointer where the len of the field will be stored
*/ */
inline const char * extern "C" inline const char *
tuple_field(const struct tuple *tuple, uint32_t i) tuple_field(const struct tuple *tuple, uint32_t i)
{ {
return tuple_field_old(tuple_format(tuple), tuple, i); return tuple_field_old(tuple_format(tuple), tuple, i);
......
#include <bit/bit.h> #include <bit/bit.h>
#include <lib/msgpuck/msgpuck.h> #include <lib/msgpuck/msgpuck.h>
#include <box/tuple.h>
/* /*
* A special hack to cc/ld to keep symbols in an optimized binary. * A special hack to cc/ld to keep symbols in an optimized binary.
...@@ -9,5 +10,7 @@ void *ffi_symbols[] = { ...@@ -9,5 +10,7 @@ void *ffi_symbols[] = {
(void *) bswap_u32, (void *) bswap_u32,
(void *) bswap_u64, (void *) bswap_u64,
(void *) mp_bswap_float, (void *) mp_bswap_float,
(void *) mp_bswap_double (void *) mp_bswap_double,
(void *) tuple_arity,
(void *) tuple_field
}; };
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment