Updated Lua extension to handle fielddefs.

pull/13171/head
Joshua Haberman 15 years ago
parent 71ac83fe7a
commit 21ee24a730
  1. 1
      core/upb_def.c
  2. 22
      core/upb_def.h
  3. 2
      core/upb_table.c
  4. 71
      lang_ext/lua/upb.c
  5. 2
      tests/test_def.c

@ -355,6 +355,7 @@ static bool upb_addfield(upb_src *src, upb_msgdef *m, upb_status *status)
f->name = NULL;
f->def = NULL;
f->owned = false;
f->msgdef = m;
upb_fielddef *parsed_f;
int32_t tmp;
while((parsed_f = upb_src_getdef(src))) {

@ -87,23 +87,27 @@ INLINE void upb_def_unref(upb_def *def) {
// is either a field of a upb_msgdef or contained inside a upb_extensiondef.
// It is also reference-counted.
typedef struct _upb_fielddef {
upb_atomic_refcount_t refcount;
upb_string *name;
upb_field_number_t number;
upb_field_type_t type;
upb_label_t label;
upb_value default_value;
upb_string *name;
struct _upb_msgdef *msgdef;
// For the case of an enum or a submessage, points to the def for that type.
upb_def *def;
// True if we own a ref on "def" (above). This is true unless this edge is
// part of a cycle.
bool owned;
upb_atomic_refcount_t refcount;
uint32_t byte_offset; // Where in a upb_msg to find the data.
// These are set only when this fielddef is part of a msgdef.
uint32_t byte_offset; // Where in a upb_msg to find the data.
upb_field_count_t field_index; // Indicates set bit.
upb_field_number_t number;
upb_field_type_t type;
upb_label_t label;
// True if we own a ref on "def" (above). This is true unless this edge is
// part of a cycle.
bool owned;
} upb_fielddef;
// A variety of tests about the type of a field.

@ -28,7 +28,7 @@ void upb_table_init(upb_table *t, uint32_t size, uint16_t entry_size)
{
t->count = 0;
t->entry_size = entry_size;
t->size_lg2 = 1;
t->size_lg2 = 0;
while(size >>= 1) t->size_lg2++;
size_t bytes = upb_table_size(t) * t->entry_size;
t->mask = upb_table_size(t) - 1;

@ -15,10 +15,14 @@
// We cache all the lua objects (userdata) we vend in a weak table, indexed by
// the C pointer of the object they are caching.
typedef void (*lupb_unref)(void *cobj);
typedef void (*lupb_cb)(void *cobj);
static void lupb_nop(void *foo) {
(void)foo;
}
static void lupb_cache_getorcreate(lua_State *L, void *cobj, const char *type,
lupb_unref unref) {
lupb_cb ref, lupb_cb unref) {
// Lookup our cache in the registry (we don't put our objects in the registry
// directly because we need our cache to be a weak table).
lua_getfield(L, LUA_REGISTRYINDEX, "upb.objcache");
@ -40,6 +44,7 @@ static void lupb_cache_getorcreate(lua_State *L, void *cobj, const char *type,
lua_pushlightuserdata(L, cobj);
lua_pushvalue(L, -2);
lua_rawset(L, -4);
ref(cobj);
} else {
unref(cobj);
}
@ -73,29 +78,21 @@ static void lupb_def_getorcreate(lua_State *L, upb_def *def) {
luaL_error(L, "unknown deftype %d", def->type);
type_name = NULL; // Placate the compiler.
}
return lupb_cache_getorcreate(L, def, type_name, lupb_def_unref);
return lupb_cache_getorcreate(L, def, type_name, lupb_nop, lupb_def_unref);
}
// msgdef
static lupb_def *lupb_msgdef_check(lua_State *L, int narg) {
return luaL_checkudata(L, narg, "upb.msgdef");
}
static lupb_def *lupb_enumdef_check(lua_State *L, int narg) {
return luaL_checkudata(L, narg, "upb.enumdef");
}
static int lupb_msgdef_gc(lua_State *L) {
lupb_def *ldef = lupb_msgdef_check(L, 1);
upb_def_unref(ldef->def);
return 0;
}
static int lupb_enumdef_gc(lua_State *L) {
lupb_def *ldef = lupb_enumdef_check(L, 1);
upb_def_unref(ldef->def);
return 0;
}
static const struct luaL_Reg lupb_msgdef_mm[] = {
{"__gc", lupb_msgdef_gc},
{NULL, NULL}
@ -105,6 +102,18 @@ static const struct luaL_Reg lupb_msgdef_m[] = {
{NULL, NULL}
};
// enumdef
static lupb_def *lupb_enumdef_check(lua_State *L, int narg) {
return luaL_checkudata(L, narg, "upb.enumdef");
}
static int lupb_enumdef_gc(lua_State *L) {
lupb_def *ldef = lupb_enumdef_check(L, 1);
upb_def_unref(ldef->def);
return 0;
}
static const struct luaL_Reg lupb_enumdef_mm[] = {
{"__gc", lupb_enumdef_gc},
{NULL, NULL}
@ -115,6 +124,40 @@ static const struct luaL_Reg lupb_enumdef_m[] = {
};
/* lupb_fielddef **************************************************************/
typedef struct {
upb_fielddef *field;
} lupb_fielddef;
static void lupb_fielddef_ref(void *cobj) {
upb_def_ref(UPB_UPCAST(((upb_fielddef*)cobj)->msgdef));
}
static void lupb_fielddef_getorcreate(lua_State *L, upb_fielddef *f) {
lupb_cache_getorcreate(L, f, "upb.fielddef", lupb_fielddef_ref, lupb_nop);
}
static lupb_fielddef *lupb_fielddef_check(lua_State *L, int narg) {
return luaL_checkudata(L, narg, "upb.fielddef");
}
static int lupb_fielddef_gc(lua_State *L) {
lupb_fielddef *lfielddef = lupb_fielddef_check(L, 1);
upb_def_unref(UPB_UPCAST(lfielddef->field->msgdef));
return 0;
}
static const struct luaL_Reg lupb_fielddef_mm[] = {
{"__gc", lupb_fielddef_gc},
{NULL, NULL}
};
static const struct luaL_Reg lupb_fielddef_m[] = {
{NULL, NULL}
};
/* lupb_symtab ****************************************************************/
typedef struct {
@ -193,7 +236,7 @@ static const struct luaL_Reg lupb_symtab_mm[] = {
static int lupb_symtab_new(lua_State *L) {
upb_symtab *s = upb_symtab_new();
lupb_cache_getorcreate(L, s, "upb.symtab", lupb_symtab_unref);
lupb_cache_getorcreate(L, s, "upb.symtab", lupb_nop, lupb_symtab_unref);
return 1;
}

@ -14,6 +14,8 @@ int main() {
}
free(defs);
printf("Size: %zd\n", sizeof(upb_ntof_ent));
upb_string *str = upb_strdupc("google.protobuf.FileDescriptorSet");
upb_def *fds = upb_symtab_lookup(s, str);
assert(fds != NULL);

Loading…
Cancel
Save