diff options
Diffstat (limited to 'upb/bindings')
-rw-r--r-- | upb/bindings/googlepb/proto2.cc | 5 | ||||
-rw-r--r-- | upb/bindings/lua/upb.c | 523 | ||||
-rw-r--r-- | upb/bindings/lua/upb.h | 82 | ||||
-rw-r--r-- | upb/bindings/lua/upb/pb.c | 44 | ||||
-rw-r--r-- | upb/bindings/lua/upb/table.c | 62 |
5 files changed, 379 insertions, 337 deletions
diff --git a/upb/bindings/googlepb/proto2.cc b/upb/bindings/googlepb/proto2.cc index 87c13b6..636bb90 100644 --- a/upb/bindings/googlepb/proto2.cc +++ b/upb/bindings/googlepb/proto2.cc @@ -449,12 +449,13 @@ case goog::FieldDescriptor::cpptype: \ enum OneofType { ONEOF_TYPE_NONE, ONEOF_TYPE_STRING, - ONEOF_TYPE_MESSAGE, + ONEOF_TYPE_MESSAGE #ifdef UPB_GOOGLE3 + , ONEOF_TYPE_GLOBALSTRING, ONEOF_TYPE_CORD, ONEOF_TYPE_STRINGPIECE, - ONEOF_TYPE_LAZYFIELD, + ONEOF_TYPE_LAZYFIELD #endif }; diff --git a/upb/bindings/lua/upb.c b/upb/bindings/lua/upb.c index aebf9f7..2b05938 100644 --- a/upb/bindings/lua/upb.c +++ b/upb/bindings/lua/upb.c @@ -33,7 +33,7 @@ #include "upb/pb/glue.h" #include "upb/shim/shim.h" -// Lua metatable types. +/* Lua metatable types. */ #define LUPB_MSG "lupb.msg" #define LUPB_ARRAY "lupb.array" #define LUPB_MSGDEF "lupb.msgdef" @@ -41,7 +41,7 @@ #define LUPB_FIELDDEF "lupb.fielddef" #define LUPB_SYMTAB "lupb.symtab" -// Other table constants. +/* Other table constants. */ #define LUPB_OBJCACHE "lupb.objcache" static void lupb_msgdef_init(lua_State *L); @@ -49,13 +49,13 @@ static size_t lupb_msgdef_sizeof(); /* Lua compatibility code *****************************************************/ -// Lua 5.1 and Lua 5.2 have slightly incompatible APIs. A little bit of -// compatibility code can help hide the difference. Not too many people still -// use Lua 5.1 but LuaJIT uses the Lua 5.1 API in some ways. +/* Lua 5.1 and Lua 5.2 have slightly incompatible APIs. A little bit of + * compatibility code can help hide the difference. Not too many people still + * use Lua 5.1 but LuaJIT uses the Lua 5.1 API in some ways. */ -#if LUA_VERSION_NUM == 501 +#if lua_version_num == 501 -// Taken from Lua 5.2's source. +/* taken from lua 5.2's source. */ void *luaL_testudata(lua_State *L, int ud, const char *tname) { void *p = lua_touserdata(L, ud); if (p != NULL) { /* value is a userdata? */ @@ -85,12 +85,12 @@ int luaL_typerror(lua_State *L, int narg, const char *tname) { } static void lupb_newlib(lua_State *L, const char *name, const luaL_Reg *funcs) { - // Lua 5.2 modules are not expected to set a global variable, so "name" is - // unused. + /* Lua 5.2 modules are not expected to set a global variable, so "name" is + * unused. */ UPB_UNUSED(name); - // Can't use luaL_newlib(), because funcs is not the actual array. - // Could (micro-)optimize this a bit to count funcs for initial table size. + /* Can't use luaL_newlib(), because funcs is not the actual array. + * Could (micro-)optimize this a bit to count funcs for initial table size. */ lua_createtable(L, 0, 8); luaL_setfuncs(L, funcs, 0); } @@ -101,7 +101,7 @@ static void lupb_newlib(lua_State *L, const char *name, const luaL_Reg *funcs) { #error Only Lua 5.1 and 5.2 are supported #endif -// Shims for upcoming Lua 5.3 functionality. +/* Shims for upcoming Lua 5.3 functionality. */ bool lua_isinteger(lua_State *L, int argn) { UPB_UNUSED(L); UPB_UNUSED(argn); @@ -111,12 +111,12 @@ bool lua_isinteger(lua_State *L, int argn) { /* Utility functions **********************************************************/ -// We store our module table in the registry, keyed by ptr. -// For more info about the motivation/rationale, see this thread: -// http://thread.gmane.org/gmane.comp.lang.lua.general/110632 +/* We store our module table in the registry, keyed by ptr. + * For more info about the motivation/rationale, see this thread: + * http://thread.gmane.org/gmane.comp.lang.lua.general/110632 */ bool lupb_openlib(lua_State *L, void *ptr, const char *name, const luaL_Reg *funcs) { - // Lookup cached module table. + /* Lookup cached module table. */ lua_pushlightuserdata(L, ptr); lua_rawget(L, LUA_REGISTRYINDEX); if (!lua_isnil(L, -1)) { @@ -125,7 +125,7 @@ bool lupb_openlib(lua_State *L, void *ptr, const char *name, lupb_newlib(L, name, funcs); - // Save module table in cache. + /* Save module table in cache. */ lua_pushlightuserdata(L, ptr); lua_pushvalue(L, -2); lua_rawset(L, LUA_REGISTRYINDEX); @@ -133,15 +133,15 @@ bool lupb_openlib(lua_State *L, void *ptr, const char *name, return false; } -// Pushes a new userdata with the given metatable and ensures that it has a -// uservalue. +/* Pushes a new userdata with the given metatable and ensures that it has a + * uservalue. */ static void *newudata_with_userval(lua_State *L, size_t size, const char *type) { void *ret = lua_newuserdata(L, size); - // Set metatable. + /* Set metatable. */ luaL_getmetatable(L, type); - assert(!lua_isnil(L, -1)); // Should have been created by luaopen_upb. + assert(!lua_isnil(L, -1)); /* Should have been created by luaopen_upb. */ lua_setmetatable(L, -2); lua_newtable(L); @@ -165,26 +165,29 @@ bool lupb_checkbool(lua_State *L, int narg) { return lua_toboolean(L, narg); } -// Unlike luaL_checkstring(), this does not allow implicit conversion to string. +/* Unlike luaL_checkstring(), this does not allow implicit conversion to + * string. */ void lupb_checkstring(lua_State *L, int narg) { if (lua_type(L, narg) != LUA_TSTRING) luaL_error(L, "Expected string"); } -// Unlike luaL_checkinteger, these do not implicitly convert from string or -// round an existing double value. We allow floating-point input, but only if -// the actual value is integral. +/* Unlike luaL_checkinteger, these do not implicitly convert from string or + * round an existing double value. We allow floating-point input, but only if + * the actual value is integral. */ #define INTCHECK(type, ctype) \ ctype lupb_check##type(lua_State *L, int narg) { \ + double n; \ + ctype i; \ if (lua_isinteger(L, narg)) { \ return lua_tointeger(L, narg); \ } \ \ /* Prevent implicit conversion from string. */ \ luaL_checktype(L, narg, LUA_TNUMBER); \ - double n = lua_tonumber(L, narg); \ + n = lua_tonumber(L, narg); \ \ - ctype i = (ctype)n; \ + i = (ctype)n; \ if ((double)i != n) { \ /* double -> ctype truncated or rounded. */ \ luaL_error(L, "number %f was not an integer or out of range for " #type, \ @@ -199,28 +202,28 @@ void lupb_checkstring(lua_State *L, int narg) { lua_pushnumber(L, val); \ } -INTCHECK(int64, int64_t); -INTCHECK(int32, int32_t); -INTCHECK(uint64, uint64_t); -INTCHECK(uint32, uint32_t); +INTCHECK(int64, int64_t) +INTCHECK(int32, int32_t) +INTCHECK(uint64, uint64_t) +INTCHECK(uint32, uint32_t) double lupb_checkdouble(lua_State *L, int narg) { - // If we were being really hard-nosed here, we'd check whether the input was - // an integer that has no precise double representation. But doubles aren't - // generally expected to be exact like integers are, and worse this could - // cause data-dependent runtime errors: one run of the program could work fine - // because the integer calculations happened to be exactly representable in - // double, while the next could crash because of subtly different input. - - luaL_checktype(L, narg, LUA_TNUMBER); // lua_tonumber() implicitly converts. + /* If we were being really hard-nosed here, we'd check whether the input was + * an integer that has no precise double representation. But doubles aren't + * generally expected to be exact like integers are, and worse this could + * cause data-dependent runtime errors: one run of the program could work fine + * because the integer calculations happened to be exactly representable in + * double, while the next could crash because of subtly different input. */ + + luaL_checktype(L, narg, LUA_TNUMBER); /* lua_tonumber() auto-converts. */ return lua_tonumber(L, narg); } float lupb_checkfloat(lua_State *L, int narg) { - // We don't worry about checking whether the input can be exactly converted to - // float -- see above. + /* We don't worry about checking whether the input can be exactly converted to + * float -- see above. */ - luaL_checktype(L, narg, LUA_TNUMBER); // lua_tonumber() implicitly converts. + luaL_checktype(L, narg, LUA_TNUMBER); /* lua_tonumber() auto-converts. */ return lua_tonumber(L, narg); } @@ -288,15 +291,15 @@ static upb_fieldtype_t lupb_checkfieldtype(lua_State *L, int narg) { /* lupb_refcounted ************************************************************/ -// All upb objects that use upb_refcounted have a userdata that begins with a -// pointer to that object. Each type has its own metatable. Objects are cached -// in a weak table indexed by the C pointer of the object they are caching. -// -// Note that we consistently use memcpy() to read to/from the object. This -// allows the userdata to use its own struct without violating aliasing, as -// long as it begins with a pointer. +/* All upb objects that use upb_refcounted have a userdata that begins with a + * pointer to that object. Each type has its own metatable. Objects are cached + * in a weak table indexed by the C pointer of the object they are caching. + * + * Note that we consistently use memcpy() to read to/from the object. This + * allows the userdata to use its own struct without violating aliasing, as + * long as it begins with a pointer. */ -// Checks type; if it matches, pulls the pointer out of the wrapper. +/* Checks type; if it matches, pulls the pointer out of the wrapper. */ void *lupb_refcounted_check(lua_State *L, int narg, const char *type) { void *ud = luaL_checkudata(L, narg, type); void *ret; @@ -308,59 +311,62 @@ void *lupb_refcounted_check(lua_State *L, int narg, const char *type) { bool lupb_refcounted_pushwrapper(lua_State *L, const upb_refcounted *obj, const char *type, const void *ref_donor, size_t size) { + bool create; + void *ud; + if (obj == NULL) { lua_pushnil(L); return false; } - // 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). + /* 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, LUPB_OBJCACHE); - assert(!lua_isnil(L, -1)); // Should have been created by luaopen_upb. + assert(!lua_isnil(L, -1)); /* Should have been created by luaopen_upb. */ lua_pushlightuserdata(L, (void*)obj); lua_rawget(L, -2); - // Stack is now: objcache, cached value. + /* Stack is now: objcache, cached value. */ - bool create = false; + create = false; if (lua_isnil(L, -1)) { create = true; } else { void *ud = lua_touserdata(L, -1); - lupb_assert(L, ud); void *ud_obj; + lupb_assert(L, ud); memcpy(&ud_obj, ud, sizeof(void*)); - // A corner case: it is possible for the value to be GC'd - // already, in which case we should evict this entry and create - // a new one. + /* A corner case: it is possible for the value to be GC'd + * already, in which case we should evict this entry and create + * a new one. */ if (ud_obj == NULL) { create = true; } } - void *ud = NULL; + ud = NULL; if (create) { - // Remove bad cached value and push new value. + /* Remove bad cached value and push new value. */ lua_pop(L, 1); - // All of our userdata begin with a pointer to the obj. + /* All of our userdata begin with a pointer to the obj. */ ud = lua_newuserdata(L, size); memcpy(ud, &obj, sizeof(void*)); upb_refcounted_donateref(obj, ref_donor, ud); luaL_getmetatable(L, type); - // Should have been created by luaopen_upb. + /* Should have been created by luaopen_upb. */ lupb_assert(L, !lua_isnil(L, -1)); lua_setmetatable(L, -2); - // Set it in the cache. + /* Set it in the cache. */ lua_pushlightuserdata(L, (void*)obj); lua_pushvalue(L, -2); lua_rawset(L, -4); } else { - // Existing wrapper obj already has a ref. + /* Existing wrapper obj already has a ref. */ ud = lua_touserdata(L, -1); upb_refcounted_checkref(obj, ud); if (ref_donor) @@ -381,13 +387,14 @@ void lupb_refcounted_pushnewrapper(lua_State *L, const upb_refcounted *obj, static int lupb_refcounted_gc(lua_State *L) { void *ud = lua_touserdata(L, 1); + void *nullp; upb_refcounted *obj; - memcpy(&obj, ud, sizeof obj); + memcpy(&obj, ud, sizeof(obj)); upb_refcounted_unref(obj, ud); - // Zero out pointer so we can detect a call into a GC'd object. - void *nullp = NULL; - memcpy(ud, &nullp, sizeof nullp); + /* Zero out pointer so we can detect a call into a GC'd object. */ + nullp = NULL; + memcpy(ud, &nullp, sizeof(nullp)); return 0; } @@ -401,12 +408,12 @@ static const struct luaL_Reg lupb_refcounted_mm[] = { /* lupb_def *******************************************************************/ static const upb_def *lupb_def_check(lua_State *L, int narg) { + upb_def *ret; void *ud = luaL_testudata(L, narg, LUPB_MSGDEF); if (!ud) ud = luaL_testudata(L, narg, LUPB_ENUMDEF); if (!ud) ud = luaL_testudata(L, narg, LUPB_FIELDDEF); if (!ud) luaL_typerror(L, narg, "upb def"); - upb_def *ret; memcpy(&ret, ud, sizeof ret); if (!ret) luaL_error(L, "called into dead object"); return ret; @@ -421,14 +428,15 @@ static upb_def *lupb_def_checkmutable(lua_State *L, int narg) { bool lupb_def_pushwrapper(lua_State *L, const upb_def *def, const void *ref_donor) { + const char *type = NULL; + size_t size = sizeof(void*); + bool created; + if (def == NULL) { lua_pushnil(L); return false; } - const char *type = NULL; - size_t size = sizeof(void*); - switch (upb_def_type(def)) { case UPB_DEF_MSG: { type = LUPB_MSGDEF; @@ -437,11 +445,11 @@ bool lupb_def_pushwrapper(lua_State *L, const upb_def *def, } case UPB_DEF_ENUM: type = LUPB_ENUMDEF; break; case UPB_DEF_FIELD: type = LUPB_FIELDDEF; break; - default: luaL_error(L, "unknown deftype %d", def->type); + default: luaL_error(L, "unknown deftype %d", upb_def_type(def)); } - bool created = - lupb_refcounted_pushwrapper(L, UPB_UPCAST(def), type, ref_donor, size); + created = + lupb_refcounted_pushwrapper(L, upb_def_upcast(def), type, ref_donor, size); if (created && upb_def_type(def) == UPB_DEF_MSG) { lupb_msgdef_init(L); @@ -509,15 +517,16 @@ static upb_fielddef *lupb_fielddef_checkmutable(lua_State *L, int narg) { static int lupb_fielddef_new(lua_State *L) { upb_fielddef *f = upb_fielddef_new(&f); - lupb_def_pushnewrapper(L, UPB_UPCAST(f), &f); + lupb_def_pushnewrapper(L, upb_fielddef_upcast(f), &f); return 1; } -// Getters +/* Getters */ static int lupb_fielddef_containingtype(lua_State *L) { const upb_fielddef *f = lupb_fielddef_check(L, 1); - lupb_def_pushwrapper(L, UPB_UPCAST(upb_fielddef_containingtype(f)), NULL); + lupb_def_pushwrapper(L, upb_msgdef_upcast(upb_fielddef_containingtype(f)), + NULL); return 1; } @@ -645,9 +654,11 @@ static int lupb_fielddef_packed(lua_State *L) { static int lupb_fielddef_subdef(lua_State *L) { const upb_fielddef *f = lupb_fielddef_check(L, 1); + const upb_def *def; + if (!upb_fielddef_hassubdef(f)) luaL_error(L, "Tried to get subdef of non-message field"); - const upb_def *def = upb_fielddef_subdef(f); + def = upb_fielddef_subdef(f); lupb_def_pushwrapper(L, def, NULL); return 1; } @@ -669,7 +680,7 @@ static int lupb_fielddef_type(lua_State *L) { return 1; } -// Setters +/* Setters */ static int lupb_fielddef_setcontainingtypename(lua_State *L) { upb_fielddef *f = lupb_fielddef_checkmutable(L, 1); @@ -712,7 +723,7 @@ static int lupb_fielddef_setdefault(lua_State *L) { upb_fielddef_setdefaultint32(f, lupb_checkint32(L, 2)); break; } - // Else fall through and set string default. + /* Else fall through and set string default. */ case UPB_TYPE_BYTES: case UPB_TYPE_STRING: { size_t len; @@ -802,14 +813,6 @@ static int lupb_fielddef_settagdelim(lua_State *L) { return 0; } -static int lupb_fielddef_selectorbase(lua_State *L) { - const upb_fielddef *f = lupb_fielddef_check(L, 1); - if (!upb_fielddef_isfrozen(f)) - luaL_error(L, "_selectorbase is only defined for frozen fielddefs"); - lua_pushinteger(L, f->selector_base); - return 1; -} - static const struct luaL_Reg lupb_fielddef_m[] = { LUPB_COMMON_DEF_METHODS @@ -845,9 +848,6 @@ static const struct luaL_Reg lupb_fielddef_m[] = { {"set_intfmt", lupb_fielddef_setintfmt}, {"set_tagdelim", lupb_fielddef_settagdelim}, - // Internal-only. - {"_selector_base", lupb_fielddef_selectorbase}, - {NULL, NULL} }; @@ -857,8 +857,8 @@ static const struct luaL_Reg lupb_fielddef_m[] = { typedef struct { const upb_msgdef *md; - // These members are initialized lazily the first time a message is created - // for this def. + /* These members are initialized lazily the first time a message is created + * for this def. */ uint16_t *field_offsets; size_t msg_size; size_t hasbits_size; @@ -886,16 +886,16 @@ static upb_msgdef *lupb_msgdef_checkmutable(lua_State *L, int narg) { static int lupb_msgdef_new(lua_State *L) { upb_msgdef *md = upb_msgdef_new(&md); - lupb_def_pushnewrapper(L, UPB_UPCAST(md), &md); + lupb_def_pushnewrapper(L, upb_msgdef_upcast(md), &md); return 1; } -// Unlike other refcounted types we need a custom __gc so that we free our field -// offsets. +/* Unlike other refcounted types we need a custom __gc so that we free our field + * offsets. */ static int lupb_msgdef_gc(lua_State *L) { - lupb_refcounted_gc(L); - lupb_msgdef *lmd = luaL_checkudata(L, -1, LUPB_MSGDEF); + lupb_msgdef *lmd = luaL_checkudata(L, 1, LUPB_MSGDEF); free(lmd->field_offsets); + lupb_refcounted_gc(L); return 0; } @@ -918,18 +918,6 @@ static int lupb_msgdef_len(lua_State *L) { return 1; } -static int lupb_msgdef_selectorcount(lua_State *L) { - const upb_msgdef *m = lupb_msgdef_check(L, 1); - lua_pushinteger(L, m->selector_count); - return 1; -} - -static int lupb_msgdef_submsgfieldcount(lua_State *L) { - const upb_msgdef *m = lupb_msgdef_check(L, 1); - lua_pushinteger(L, m->submsg_field_count); - return 1; -} - static int lupb_msgdef_field(lua_State *L) { const upb_msgdef *m = lupb_msgdef_check(L, 1); int type = lua_type(L, 2); @@ -944,14 +932,14 @@ static int lupb_msgdef_field(lua_State *L) { return luaL_argerror(L, 2, msg); } - lupb_def_pushwrapper(L, UPB_UPCAST(f), NULL); + lupb_def_pushwrapper(L, upb_fielddef_upcast(f), NULL); return 1; } static int lupb_msgiter_next(lua_State *L) { upb_msg_field_iter *i = lua_touserdata(L, lua_upvalueindex(1)); if (upb_msg_field_done(i)) return 0; - lupb_def_pushwrapper(L, UPB_UPCAST(upb_msg_iter_field(i)), NULL); + lupb_def_pushwrapper(L, upb_fielddef_upcast(upb_msg_iter_field(i)), NULL); upb_msg_field_next(i); return 1; } @@ -960,7 +948,7 @@ static int lupb_msgdef_fields(lua_State *L) { const upb_msgdef *m = lupb_msgdef_check(L, 1); upb_msg_field_iter *i = lua_newuserdata(L, sizeof(upb_msg_field_iter)); upb_msg_field_begin(i, m); - // Need to guarantee that the msgdef outlives the iter. + /* Need to guarantee that the msgdef outlives the iter. */ lua_pushvalue(L, 1); lua_pushcclosure(L, &lupb_msgiter_next, 2); return 1; @@ -978,10 +966,6 @@ static const struct luaL_Reg lupb_msgdef_m[] = { {"field", lupb_msgdef_field}, {"fields", lupb_msgdef_fields}, - // Internal-only. - {"_selector_count", lupb_msgdef_selectorcount}, - {"_submsg_field_count", lupb_msgdef_submsgfieldcount}, - {NULL, NULL} }; @@ -1001,7 +985,7 @@ static upb_enumdef *lupb_enumdef_checkmutable(lua_State *L, int narg) { static int lupb_enumdef_new(lua_State *L) { upb_enumdef *e = upb_enumdef_new(&e); - lupb_def_pushnewrapper(L, UPB_UPCAST(e), &e); + lupb_def_pushnewrapper(L, upb_enumdef_upcast(e), &e); return 1; } @@ -1023,7 +1007,7 @@ static int lupb_enumdef_value(lua_State *L) { const upb_enumdef *e = lupb_enumdef_check(L, 1); int type = lua_type(L, 2); if (type == LUA_TNUMBER) { - // Pushes "nil" for a NULL pointer. + /* Pushes "nil" for a NULL pointer. */ int32_t key = lupb_checkint32(L, 2); lua_pushstring(L, upb_enumdef_iton(e, key)); } else if (type == LUA_TSTRING) { @@ -1055,7 +1039,7 @@ static int lupb_enumdef_values(lua_State *L) { const upb_enumdef *e = lupb_enumdef_check(L, 1); upb_enum_iter *i = lua_newuserdata(L, sizeof(upb_enum_iter)); upb_enum_begin(i, e); - // Need to guarantee that the enumdef outlives the iter. + /* Need to guarantee that the enumdef outlives the iter. */ lua_pushvalue(L, 1); lua_pushcclosure(L, &lupb_enumiter_next, 2); return 1; @@ -1077,9 +1061,9 @@ static const struct luaL_Reg lupb_enumdef_m[] = { /* lupb_symtab ****************************************************************/ -// Inherits a ref on the symtab. -// Checks that narg is a proper lupb_symtab object. If it is, leaves its -// metatable on the stack for cache lookups/updates. +/* Inherits a ref on the symtab. + * Checks that narg is a proper lupb_symtab object. If it is, leaves its + * metatable on the stack for cache lookups/updates. */ const upb_symtab *lupb_symtab_check(lua_State *L, int narg) { return lupb_refcounted_check(L, narg, LUPB_SYMTAB); } @@ -1093,13 +1077,14 @@ static upb_symtab *lupb_symtab_checkmutable(lua_State *L, int narg) { void lupb_symtab_pushwrapper(lua_State *L, const upb_symtab *s, const void *ref_donor) { - lupb_refcounted_pushwrapper(L, UPB_UPCAST(s), LUPB_SYMTAB, ref_donor, + lupb_refcounted_pushwrapper(L, upb_symtab_upcast(s), LUPB_SYMTAB, ref_donor, sizeof(void *)); } void lupb_symtab_pushnewrapper(lua_State *L, const upb_symtab *s, const void *ref_donor) { - lupb_refcounted_pushnewrapper(L, UPB_UPCAST(s), LUPB_SYMTAB, ref_donor); + lupb_refcounted_pushnewrapper(L, upb_symtab_upcast(s), LUPB_SYMTAB, + ref_donor); } static int lupb_symtab_new(lua_State *L) { @@ -1120,19 +1105,22 @@ static int lupb_symtab_isfrozen(lua_State *L) { static int lupb_symtab_add(lua_State *L) { upb_symtab *s = lupb_symtab_checkmutable(L, 1); + int n; + upb_def **defs; + luaL_checktype(L, 2, LUA_TTABLE); - // Iterate over table twice. First iteration to count entries and - // check constraints. - int n = 0; + /* Iterate over table twice. First iteration to count entries and + * check constraints. */ + n = 0; for (lua_pushnil(L); lua_next(L, 2); lua_pop(L, 1)) { lupb_def_checkmutable(L, -1); ++n; } - // Second iteration to build deflist. - // Allocate list with lua_newuserdata() so it is anchored as a GC root in - // case any Lua functions longjmp(). - upb_def **defs = lua_newuserdata(L, n * sizeof(*defs)); + /* Second iteration to build deflist. + * Allocate list with lua_newuserdata() so it is anchored as a GC root in + * case any Lua functions longjmp(). */ + defs = lua_newuserdata(L, n * sizeof(*defs)); n = 0; for (lua_pushnil(L); lua_next(L, 2); lua_pop(L, 1)) { upb_def *def = lupb_def_checkmutable(L, -1); @@ -1145,7 +1133,8 @@ static int lupb_symtab_add(lua_State *L) { static int lupb_symtab_lookup(lua_State *L) { const upb_symtab *s = lupb_symtab_check(L, 1); - for (int i = 2; i <= lua_gettop(L); i++) { + int i; + for (i = 2; i <= lua_gettop(L); i++) { const upb_def *def = upb_symtab_lookup(s, luaL_checkstring(L, i)); lupb_def_pushwrapper(L, def, NULL); lua_replace(L, i); @@ -1166,15 +1155,15 @@ static int lupb_symtab_defs(lua_State *L) { upb_deftype_t type = lua_gettop(L) > 1 ? luaL_checkint(L, 2) : UPB_DEF_ANY; upb_symtab_iter *i = lua_newuserdata(L, sizeof(upb_symtab_iter)); upb_symtab_begin(i, s, type); - // Need to guarantee that the symtab outlives the iter. + /* Need to guarantee that the symtab outlives the iter. */ lua_pushvalue(L, 1); lua_pushcclosure(L, &lupb_symtabiter_next, 2); return 1; } -// This is a *temporary* API that will be removed once pending refactorings are -// complete (it does not belong here in core because it depends on both -// the descriptor.proto schema and the protobuf binary format. +/* This is a *temporary* API that will be removed once pending refactorings are + * complete (it does not belong here in core because it depends on both + * the descriptor.proto schema and the protobuf binary format. */ static int lupb_symtab_load_descriptor(lua_State *L) { size_t len; upb_symtab *s = lupb_symtab_checkmutable(L, 1); @@ -1196,23 +1185,23 @@ static const struct luaL_Reg lupb_symtab_m[] = { /* lupb_array *****************************************************************/ -// A lupb_array provides a strongly-typed array. -// -// For the moment we store all values in the userdata's environment table / -// userval, for simplicity. Later we may wish to move the data into raw -// memory as both a space and time optimization. -// -// Compared to regular Lua tables: -// -// - we only allow integer indices. -// - all entries must match the type of the table. -// - we do not allow "holes" in the array; you can only assign to an existing -// index or one past the end (which will grow the array by one). +/* A lupb_array provides a strongly-typed array. + * + * For the moment we store all values in the userdata's environment table / + * userval, for simplicity. Later we may wish to move the data into raw + * memory as both a space and time optimization + * + * Compared to regular Lua tables: + * + * - we only allow integer indices. + * - all entries must match the type of the table. + * - we do not allow "holes" in the array; you can only assign to an existing + * index or one past the end (which will grow the array by one). */ typedef struct { uint32_t size; upb_fieldtype_t type; - const upb_msgdef *msgdef; // Only when type == UPB_TYPE_MESSAGE + const upb_msgdef *msgdef; /* Only when type == UPB_TYPE_MESSAGE */ } lupb_array; static lupb_array *lupb_array_check(lua_State *L, int narg) { @@ -1221,7 +1210,7 @@ static lupb_array *lupb_array_check(lua_State *L, int narg) { static uint32_t lupb_array_checkindex(lua_State *L, int narg, uint32_t max) { uint32_t n = lupb_checkuint32(L, narg); - if (n == 0 || n > max) { // Lua uses 1-based indexing. :( + if (n == 0 || n > max) { /* Lua uses 1-based indexing. :( */ luaL_error(L, "Invalid array index."); } return n; @@ -1241,12 +1230,12 @@ static int lupb_array_new(lua_State *L) { array->type = UPB_TYPE_MESSAGE; array->msgdef = lupb_msgdef_check(L, 1); - // Store a reference to this msgdef in the environment table to ensure it - // outlives this array. + /* Store a reference to this msgdef in the environment table to ensure it + * outlives this array. */ lua_getuservalue(L, -1); lua_pushvalue(L, 1); lua_rawseti(L, -2, 0); - lua_pop(L, 1); // Pop userval. + lua_pop(L, 1); /* Pop userval. */ } return 1; @@ -1268,12 +1257,12 @@ static int lupb_array_newindex(lua_State *L) { lupb_checkval(L, 3, array->type); } - // Write value to userval table. + /* Write value to userval table. */ lua_getuservalue(L, 1); lua_pushvalue(L, 3); lua_rawseti(L, -2, n); - return 0; // 1 for chained assignments? + return 0; /* 1 for chained assignments? */ } static int lupb_array_index(lua_State *L) { @@ -1300,15 +1289,15 @@ static const struct luaL_Reg lupb_array_mm[] = { /* lupb_msg **************************************************************/ -// A lupb_msg is a userdata where: -// -// - the userdata's memory contains hasbits and primitive fields. -// - the userdata's environment table / uservalue contains references to string -// fields, submessage fields, and array fields. +/* A lupb_msg is a userdata where: + * + * - the userdata's memory contains hasbits and primitive fields. + * - the userdata's environment table / uservalue contains references to string + * fields, submessage fields, and array fields. */ typedef struct { const lupb_msgdef *lmd; - char data[]; + /* Data follows, in a flat buffer. */ } lupb_msg; #define MSGDEF_INDEX 0 @@ -1342,8 +1331,8 @@ static size_t lupb_sizeof(lua_State *L, const upb_fielddef *f) { static int div_round_up(size_t n, size_t d) { int ret = n / d; - // If there was a positive remainder, then the result was rounded down and we - // need to compensate by adding one. + /* If there was a positive remainder, then the result was rounded down and we + * need to compensate by adding one. */ if (n % d > 0) ++ret; return ret; } @@ -1352,9 +1341,11 @@ static size_t align_up(size_t val, size_t align) { return val % align == 0 ? val : val + align - (val % align); } -// If we always read/write as a consistent type to each value, this shouldn't -// violate aliasing. -#define DEREF(msg, ofs, type) *(type*)((char*)msg + sizeof(lupb_msg) + ofs) +#define CHARPTR_AT(msg, ofs) ((char*)msg + sizeof(lupb_msg) + ofs) + +/* If we always read/write as a consistent type to each value, this shouldn't + * violate aliasing. */ +#define DEREF(msg, ofs, type) *(type*)CHARPTR_AT(msg, ofs) lupb_msg *lupb_msg_check(lua_State *L, int narg) { lupb_msg *msg = luaL_checkudata(L, narg, LUPB_MSG); @@ -1376,71 +1367,75 @@ static const upb_fielddef *lupb_msg_checkfield(lua_State *L, if (!f) { const char *msg = lua_pushfstring(L, "no such field: %s", fieldname); luaL_argerror(L, fieldarg, msg); - return NULL; // Never reached. + return NULL; /* Never reached. */ } return f; } -// Assigns offsets for storing data in instances of messages for this type, if -// they have not already been assigned. "narg" should be the stack location of -// a Lua msgdef object. It should be frozen (if it is not, we will throw an -// error). It should not throw errors in any other case, since we may have -// values on our stack that would leak if we longjmp'd across them. -// -// TODO(haberman): (if we want to avoid this and be robust against even lua -// errors due to OOM, we should stop using upb_handlers_newfrozen() and -// implement it ourselves with a Lua table as cache, since that would get -// cleaned up properly on error). +/* Assigns offsets for storing data in instances of messages for this type, if + * they have not already been assigned. "narg" should be the stack location of + * a Lua msgdef object. It should be frozen (if it is not, we will throw an + * error). It should not throw errors in any other case, since we may have + * values on our stack that would leak if we longjmp'd across them. + * + * TODO(haberman): (if we want to avoid this and be robust against even lua + * errors due to OOM, we should stop using upb_handlers_newfrozen() and + * implement it ourselves with a Lua table as cache, since that would get + * cleaned up properly on error). */ static lupb_msgdef *lupb_msg_assignoffsets(lua_State *L, int narg) { + int idx; + upb_msg_field_iter i; lupb_msgdef *lmd = lupb_msgdef_check2(L, narg); + if (!upb_msgdef_isfrozen(lmd->md)) luaL_error(L, "msgdef must be frozen"); if (lmd->field_offsets) { - // Already assigned. + /* Already assigned. */ return lmd; } - int n = upb_msgdef_numfields(lmd->md); - uint16_t *offsets = malloc(sizeof(*offsets) * n); - - // Offset with the raw data part; starts with hasbits. - size_t hasbits_size = div_round_up(n, 8); - size_t data_ofs = hasbits_size; - // Index within the userval. - // Starts at one to not collide with MSGDEF_INDEX. - size_t userval_idx = 1; - - // Assign offsets. - upb_msg_field_iter i; - for (upb_msg_field_begin(&i, lmd->md); - !upb_msg_field_done(&i); - upb_msg_field_next(&i)) { - upb_fielddef *f = upb_msg_iter_field(&i); - if (in_userval(f)) { - offsets[upb_fielddef_index(f)] = userval_idx++; - } else { - size_t size = lupb_sizeof(L, f); - data_ofs = align_up(data_ofs, size); - offsets[upb_fielddef_index(f)] = data_ofs; - data_ofs += size; + { + int n = upb_msgdef_numfields(lmd->md); + uint16_t *offsets = malloc(sizeof(*offsets) * n); + + /* Offset with the raw data part; starts with hasbits. */ + size_t hasbits_size = div_round_up(n, 8); + size_t data_ofs = hasbits_size; + /* Index within the userval. + * Starts at one to not collide with MSGDEF_INDEX. */ + size_t userval_idx = 1; + + /* Assign offsets. */ + for (upb_msg_field_begin(&i, lmd->md); + !upb_msg_field_done(&i); + upb_msg_field_next(&i)) { + upb_fielddef *f = upb_msg_iter_field(&i); + if (in_userval(f)) { + offsets[upb_fielddef_index(f)] = userval_idx++; + } else { + size_t size = lupb_sizeof(L, f); + data_ofs = align_up(data_ofs, size); + offsets[upb_fielddef_index(f)] = data_ofs; + data_ofs += size; + } } - } - lmd->field_offsets = offsets; - lmd->msg_size = sizeof(lupb_msg) + data_ofs; - lmd->hasbits_size = hasbits_size; + lmd->field_offsets = offsets; + lmd->msg_size = sizeof(lupb_msg) + data_ofs; + lmd->hasbits_size = hasbits_size; + } - // Now recursively assign offsets for all submessages, and also add them to - // the uservalue to ensure that all the lupb_msgdef objects for our - // submessages outlive us. This is particularly important if/when we build - // handlers to populate this msgdef. + /* Now recursively assign offsets for all submessages, and also add them to + * the uservalue to ensure that all the lupb_msgdef objects for our + * submessages outlive us. This is particularly important if/when we build + * handlers to populate this msgdef. */ lua_pushvalue(L, narg); - lua_newtable(L); // This will be our userval. + lua_newtable(L); /* This will be our userval. */ - int idx = 1; + idx = 1; for (upb_msg_field_begin(&i, lmd->md); !upb_msg_field_done(&i); upb_msg_field_next(&i)) { @@ -1449,38 +1444,39 @@ static lupb_msgdef *lupb_msg_assignoffsets(lua_State *L, int narg) { bool created = lupb_def_pushwrapper(L, upb_fielddef_subdef(f), NULL); UPB_ASSERT_VAR(created, !created); lupb_msg_assignoffsets(L, -1); - lua_rawseti(L, -2, idx++); // Append to uservalue. + lua_rawseti(L, -2, idx++); /* Append to uservalue. */ } } lua_setuservalue(L, -2); - lua_pop(L, 1); // copy of msgdef + lua_pop(L, 1); /* copy of msgdef */ return lmd; } void lupb_msg_pushnew(lua_State *L, int narg) { lupb_msgdef *lmd = lupb_msg_assignoffsets(L, narg); + lupb_msg *msg; - // Add passed-in MessageDef to a table which will become the msg's userval. + /* Add passed-in MessageDef to a table which will become the msg's userval. */ lua_pushvalue(L, narg); lua_newtable(L); lua_pushvalue(L, narg); lua_rawseti(L, -2, MSGDEF_INDEX); - lupb_msg *msg = newudata_with_userval(L, lmd->msg_size, LUPB_MSG); + msg = newudata_with_userval(L, lmd->msg_size, LUPB_MSG); memset(msg, 0, lmd->msg_size); - // Create a msg->msgdef reference, both: - // 1. a pointer in the userdata itself (for easy access) and + /* Create a msg->msgdef reference, both: + * 1. a pointer in the userdata itself (for easy access) and */ msg->lmd = lmd; - // 2. a reference in Lua-space from the msg's uservalue to the messagedef - // wrapper object (so the msgdef wrapper object will always outlive us, - // GC-wise). - lua_pushvalue(L, -2); // Push the table from before. - lua_setuservalue(L, -2); // Pop table, now msg is at top again. - lua_remove(L, -2); // Remove table, so new message is only new value. + /* 2. a reference in Lua-space from the msg's uservalue to the messagedef + * wrapper object (so the msgdef wrapper object will always outlive us, + * GC-wise). */ + lua_pushvalue(L, -2); /* Push the table from before. */ + lua_setuservalue(L, -2); /* Pop table, now msg is at top again. */ + lua_remove(L, -2); /* Remove table, so new message is only new val. */ } static int lupb_msg_new(lua_State *L) { @@ -1490,24 +1486,25 @@ static int lupb_msg_new(lua_State *L) { static bool lupb_msg_has(const lupb_msg *msg, const upb_fielddef *f) { uint16_t idx = upb_fielddef_index(f); - return msg->data[idx / 8] & (1 << (idx % 8)); + return *CHARPTR_AT(msg, idx / 8) & (1 << (idx % 8)); } static void lupb_msg_set(lupb_msg *msg, const upb_fielddef *f) { uint16_t idx = upb_fielddef_index(f); - msg->data[idx / 8] |= (1 << (idx % 8)); + *CHARPTR_AT(msg, idx / 8) |= (1 << (idx % 8)); } static int lupb_msg_index(lua_State *L) { lupb_msg *msg = lupb_msg_check(L, 1); const upb_fielddef *f = lupb_msg_checkfield(L, msg->lmd, 2); + int ofs; if (!upb_fielddef_isseq(f) && !lupb_msg_has(msg, f)) { lua_pushnil(L); return 1; } - int ofs = msg->lmd->field_offsets[upb_fielddef_index(f)]; + ofs = msg->lmd->field_offsets[upb_fielddef_index(f)]; if (in_userval(f)) { lua_getuservalue(L, 1); @@ -1533,15 +1530,15 @@ static int lupb_msg_index(lua_State *L) { break; case UPB_TYPE_INT64: if (LUA_VERSION_NUM < 503) { - // Check value? Lua < 5.3.0 has no native integer support, lua_Number - // is probably double which can't exactly represent large int64s. + /* Check value? Lua < 5.3.0 has no native integer support, lua_Number + * is probably double which can't exactly represent large int64s. */ } lupb_pushint64(L, DEREF(msg, ofs, int64_t)); break; case UPB_TYPE_UINT64: if (LUA_VERSION_NUM < 503) { - // Check value? Lua < 5.3.0 has no native integer support, lua_Number - // is probably double which can't exactly represent large uint64s. + /* Check value? Lua < 5.3.0 has no native integer support, lua_Number + * is probably double which can't exactly represent large uint64s. */ } lupb_pushuint64(L, DEREF(msg, ofs, uint64_t)); break; @@ -1559,13 +1556,14 @@ static int lupb_msg_index(lua_State *L) { int lupb_msg_newindex(lua_State *L) { lupb_msg *msg = lupb_msg_check(L, 1); const upb_fielddef *f = lupb_msg_checkfield(L, msg->lmd, 2); + int ofs; lupb_msg_set(msg, f); - int ofs = msg->lmd->field_offsets[upb_fielddef_index(f)]; + ofs = msg->lmd->field_offsets[upb_fielddef_index(f)]; if (in_userval(f)) { - // Type-check and then store in the userval. + /* Type-check and then store in the userval. */ if (upb_fielddef_isseq(f)) { lupb_array *array = lupb_array_check(L, 3); if (array->type != upb_fielddef_type(f) || @@ -1614,7 +1612,7 @@ int lupb_msg_newindex(lua_State *L) { } } - return 0; // 1 for chained assignments? + return 0; /* 1 for chained assignments? */ } static const struct luaL_Reg lupb_msg_mm[] = { @@ -1626,7 +1624,7 @@ static const struct luaL_Reg lupb_msg_mm[] = { /* lupb_msg populating handlers ***********************************************/ -// NOTE: doesn't support repeated or submessage fields yet. Coming soon. +/* NOTE: doesn't support repeated or submessage fields yet. Coming soon. */ typedef struct { uint32_t ofs; @@ -1634,15 +1632,16 @@ typedef struct { } lupb_handlerdata; static void lupb_sethasbit(lupb_msg *msg, uint32_t hasbit) { - msg->data[hasbit / 8] |= 1 << (hasbit % 8); + *CHARPTR_AT(msg, hasbit / 8) |= 1 << (hasbit % 8); } static size_t strhandler(void *closure, const void *hd, const char *str, size_t len, const upb_bufhandle *handle) { - UPB_UNUSED(handle); lupb_msg *msg = closure; const lupb_handlerdata *data = hd; lua_State *L = msg->lmd->L; + UPB_UNUSED(handle); + lua_pushlstring(L, str, len); lua_rawseti(L, -2, data->ofs); lupb_sethasbit(msg, data->hasbit); @@ -1659,9 +1658,11 @@ const void *newhandlerdata(upb_handlers *h, uint32_t ofs, uint32_t hasbit) { void callback(const void *closure, upb_handlers *h) { lua_State *L = (lua_State*)closure; - lupb_def_pushwrapper(L, UPB_UPCAST(upb_handlers_msgdef(h)), NULL); - lupb_msgdef *lmd = lupb_msg_assignoffsets(L, -1); + lupb_msgdef *lmd; upb_msg_field_iter i; + + lupb_def_pushwrapper(L, upb_msgdef_upcast(upb_handlers_msgdef(h)), NULL); + lmd = lupb_msg_assignoffsets(L, -1); upb_msg_field_begin(&i, upb_handlers_msgdef(h)); for (; !upb_msg_field_done(&i); upb_msg_field_next(&i)) { upb_fielddef *f = upb_msg_iter_field(&i); @@ -1679,15 +1680,15 @@ void callback(const void *closure, upb_handlers *h) { case UPB_TYPE_INT64: case UPB_TYPE_UINT64: case UPB_TYPE_DOUBLE: - hasbit += offsetof(lupb_msg, data) * 8; - ofs += offsetof(lupb_msg, data); + hasbit += sizeof(lupb_msg) * 8; + ofs += sizeof(lupb_msg); upb_shim_set(h, f, ofs, hasbit); break; case UPB_TYPE_STRING: case UPB_TYPE_BYTES: { upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; upb_handlerattr_sethandlerdata(&attr, newhandlerdata(h, ofs, hasbit)); - // XXX: does't currently handle split buffers. + /* XXX: does't currently handle split buffers. */ upb_handlers_setstring(h, f, strhandler, &attr); upb_handlerattr_uninit(&attr); break; @@ -1698,7 +1699,7 @@ void callback(const void *closure, upb_handlers *h) { } } } - lua_pop(L, 1); // msgdef wrapper + lua_pop(L, 1); /* msgdef wrapper */ } const upb_handlers *lupb_msg_newwritehandlers(lua_State *L, int narg, @@ -1712,11 +1713,13 @@ const upb_handlers *lupb_msg_newwritehandlers(lua_State *L, int narg, static int lupb_freeze(lua_State *L) { int n = lua_gettop(L); - // Scratch memory; lua_newuserdata() anchors it as a GC root in case any Lua - // functions fail. + int i; + /* Scratch memory; lua_newuserdata() anchors it as a GC root in case any Lua + * functions fail. */ upb_def **defs = lua_newuserdata(L, n * sizeof(upb_def*)); - for (int i = 0; i < n; i++) { - // Could allow an array of defs here also. + + for (i = 0; i < n; i++) { + /* Could allow an array of defs here also. */ defs[i] = lupb_def_checkmutable(L, i + 1); } CHK(upb_def_freeze(defs, n, &status)); @@ -1748,8 +1751,8 @@ void lupb_register_type(lua_State *L, const char *name, const luaL_Reg *m, } if (m) { - // Methods go in the mt's __index method. This implies that you can't - // implement __index and also have methods. + /* Methods go in the mt's __index method. This implies that you can' + * implement __index and also have methods. */ lua_getfield(L, -1, "__index"); lupb_assert(L, lua_isnil(L, -1)); lua_pop(L, 1); @@ -1759,7 +1762,7 @@ void lupb_register_type(lua_State *L, const char *name, const luaL_Reg *m, lua_setfield(L, -2, "__index"); } - lua_pop(L, 1); // The mt. + lua_pop(L, 1); /* The mt. */ } static void lupb_setfieldi(lua_State *L, const char *field, int i) { @@ -1773,27 +1776,27 @@ int luaopen_upb_c(lua_State *L) { return 1; } - // Non-refcounted types. + /* Non-refcounted types. */ lupb_register_type(L, LUPB_ARRAY, NULL, lupb_array_mm, false); lupb_register_type(L, LUPB_MSG, NULL, lupb_msg_mm, false); - // Refcounted types. + /* Refcounted types. */ lupb_register_type(L, LUPB_ENUMDEF, lupb_enumdef_m, lupb_enumdef_mm, true); lupb_register_type(L, LUPB_FIELDDEF, lupb_fielddef_m, NULL, true); lupb_register_type(L, LUPB_SYMTAB, lupb_symtab_m, NULL, true); - // Refcounted but with custom __gc. + /* Refcounted but with custom __gc. */ lupb_register_type(L, LUPB_MSGDEF, lupb_msgdef_m, lupb_msgdef_mm, false); - // Create our object cache. + /* Create our object cache. */ lua_newtable(L); - lua_createtable(L, 0, 1); // Cache metatable. - lua_pushstring(L, "v"); // Values are weak. + lua_createtable(L, 0, 1); /* Cache metatable. */ + lua_pushstring(L, "v"); /* Values are weak. */ lua_setfield(L, -2, "__mode"); lua_setmetatable(L, -2); lua_setfield(L, LUA_REGISTRYINDEX, LUPB_OBJCACHE); - // Register constants. + /* Register constants. */ lupb_setfieldi(L, "LABEL_OPTIONAL", UPB_LABEL_OPTIONAL); lupb_setfieldi(L, "LABEL_REQUIRED", UPB_LABEL_REQUIRED); lupb_setfieldi(L, "LABEL_REPEATED", UPB_LABEL_REPEATED); @@ -1854,5 +1857,5 @@ int luaopen_upb_c(lua_State *L) { lupb_setfieldi(L, "HANDLER_STARTSEQ", UPB_HANDLER_STARTSEQ); lupb_setfieldi(L, "HANDLER_ENDSEQ", UPB_HANDLER_ENDSEQ); - return 1; // Return package table. + return 1; /* Return package table. */ } diff --git a/upb/bindings/lua/upb.h b/upb/bindings/lua/upb.h index 99fe8fe..09ffaa9 100644 --- a/upb/bindings/lua/upb.h +++ b/upb/bindings/lua/upb.h @@ -15,14 +15,14 @@ #include "upb/handlers.h" #include "upb/symtab.h" -// Lua 5.1/5.2 compatibility code. +/* Lua 5.1/5.2 compatibility code. */ #if LUA_VERSION_NUM == 501 #define lua_rawlen lua_objlen -// Lua >= 5.2's getuservalue/setuservalue functions do not exist in prior -// versions but the older function lua_getfenv() can provide 100% of its -// capabilities (the reverse is not true). +/* Lua >= 5.2's getuservalue/setuservalue functions do not exist in prior + * versions but the older function lua_getfenv() can provide 100% of its + * capabilities (the reverse is not true). */ #define lua_getuservalue(L, index) lua_getfenv(L, index) #define lua_setuservalue(L, index) lua_setfenv(L, index) @@ -40,33 +40,33 @@ int luaL_typerror(lua_State *L, int narg, const char *tname); if (!(predicate)) \ luaL_error(L, "internal error: %s, %s:%d ", #predicate, __FILE__, __LINE__); -// Function for initializing the core library. This function is idempotent, -// and should be called at least once before calling any of the functions that -// construct core upb types. +/* Function for initializing the core library. This function is idempotent, + * and should be called at least once before calling any of the functions that + * construct core upb types. */ int luaopen_upb(lua_State *L); -// Gets or creates a package table for a C module that is uniquely identified by -// "ptr". The easiest way to supply a unique "ptr" is to pass the address of a -// static variable private in the module's .c file. -// -// If this module has already been registered in this lua_State, pushes it and -// returns true. -// -// Otherwise, creates a new module table for this module with the given name, -// pushes it, and registers the given top-level functions in it. It also sets -// it as a global variable, but only if the current version of Lua expects that -// (ie Lua 5.1/LuaJIT). -// -// If "false" is returned, the caller is guaranteed that this lib has not been -// registered in this Lua state before (regardless of any funny business the -// user might have done to the global state), so the caller can safely perform -// one-time initialization. +/* Gets or creates a package table for a C module that is uniquely identified by + * "ptr". The easiest way to supply a unique "ptr" is to pass the address of a + * static variable private in the module's .c file. + * + * If this module has already been registered in this lua_State, pushes it and + * returns true. + * + * Otherwise, creates a new module table for this module with the given name, + * pushes it, and registers the given top-level functions in it. It also sets + * it as a global variable, but only if the current version of Lua expects that + * (ie Lua 5.1/LuaJIT). + * + * If "false" is returned, the caller is guaranteed that this lib has not been + * registered in this Lua state before (regardless of any funny business the + * user might have done to the global state), so the caller can safely perform + * one-time initialization. */ bool lupb_openlib(lua_State *L, void *ptr, const char *name, const luaL_Reg *funcs); -// Custom check/push functions. Unlike the Lua equivalents, they are pinned to -// specific types (instead of lua_Number, etc), and do not allow any implicit -// conversion or data loss. +/* Custom check/push functions. Unlike the Lua equivalents, they are pinned to + * specific types (instead of lua_Number, etc), and do not allow any implicit + * conversion or data loss. */ int64_t lupb_checkint64(lua_State *L, int narg); int32_t lupb_checkint32(lua_State *L, int narg); uint64_t lupb_checkuint64(lua_State *L, int narg); @@ -84,8 +84,8 @@ void lupb_pushdouble(lua_State *L, double val); void lupb_pushfloat(lua_State *L, float val); void lupb_pushbool(lua_State *L, bool val); -// Functions for getting/pushing wrappers to various types defined in the -// core library. +/* Functions for getting/pushing wrappers to various types defined in the + * core library. */ void *lupb_refcounted_check(lua_State *L, int narg, const char *type); const upb_msgdef *lupb_msg_checkdef(lua_State *L, int narg); const upb_msgdef *lupb_msgdef_check(lua_State *L, int narg); @@ -104,26 +104,26 @@ void lupb_symtab_pushwrapper(lua_State *L, const upb_symtab *s, void lupb_symtab_pushnewrapper(lua_State *L, const upb_symtab *s, const void *ref_donor); -// For constructing a new message. narg is the Lua value for the MessageDef -// object. +/* For constructing a new message. narg is the Lua value for the MessageDef + * object. */ void lupb_msg_pushnew(lua_State *L, int narg); -// Builds and returns a handlers object for populating a lupb_msg described by -// the MessageDef at "narg". -// -// TODO(haberman): factor this so it doesn't have to take a lua_State. We -// should be able to generate message handlers for a upb_msgdef that can be used -// across many Lua states, so we can shared JIT code across lua_States. +/* Builds and returns a handlers object for populating a lupb_msg described by + * the MessageDef at "narg". + * + * TODO(haberman): factor this so it doesn't have to take a lua_State. We + * should be able to generate message handlers for a upb_msgdef that can be used + * across many Lua states, so we can shared JIT code across lua_States. */ const upb_handlers *lupb_msg_newwritehandlers(lua_State *L, int narg, const void *owner); -// Registers a type with the given name, methods, and metamethods. -// If "refcount_gc" is true, adds a __gc metamethod that does an unref. -// Refcounted types must be allocated with lupb_refcounted_push[new]wrapper. +/* Registers a type with the given name, methods, and metamethods. + * If "refcount_gc" is true, adds a __gc metamethod that does an unref. + * Refcounted types must be allocated with lupb_refcounted_push[new]wrapper. */ void lupb_register_type(lua_State *L, const char *name, const luaL_Reg *m, const luaL_Reg *mm, bool refcount_gc); -// Checks the given upb_status and throws a Lua error if it is not ok. +/* Checks the given upb_status and throws a Lua error if it is not ok. */ void lupb_checkstatus(lua_State *L, upb_status *s); -#endif // UPB_LUA_UPB_H_ +#endif /* UPB_LUA_UPB_H_ */ diff --git a/upb/bindings/lua/upb/pb.c b/upb/bindings/lua/upb/pb.c index bf82a9b..b85da18 100644 --- a/upb/bindings/lua/upb/pb.c +++ b/upb/bindings/lua/upb/pb.c @@ -23,61 +23,65 @@ static upb_pbdecodermethod *lupb_pbdecodermethod_check(lua_State *L, int narg) { static int lupb_pbdecodermethod_new(lua_State *L) { const upb_handlers *handlers = lupb_msg_newwritehandlers(L, 1, &handlers); + const upb_pbdecodermethod *m; upb_pbdecodermethodopts opts; upb_pbdecodermethodopts_init(&opts, handlers); - const upb_pbdecodermethod *m = upb_pbdecodermethod_new(&opts, &m); + m = upb_pbdecodermethod_new(&opts, &m); upb_handlers_unref(handlers, &handlers); - lupb_refcounted_pushnewrapper(L, UPB_UPCAST(m), LUPB_PBDECODERMETHOD, &m); + lupb_refcounted_pushnewrapper( + L, upb_pbdecodermethod_upcast(m), LUPB_PBDECODERMETHOD, &m); - // We need to keep a pointer to the MessageDef (in Lua space) so we can - // construct new messages in parse(). + /* We need to keep a pointer to the MessageDef (in Lua space) so we can + * construct new messages in parse(). */ lua_newtable(L); lua_pushvalue(L, 1); lua_rawseti(L, -2, MSGDEF_INDEX); lua_setuservalue(L, -2); - return 1; // The DecoderMethod wrapper. + return 1; /* The DecoderMethod wrapper. */ } -// Unlike most of our exposed Lua functions, this does not correspond to an -// actual method on the underlying DecoderMethod. But it's convenient, and -// important to implement in C because we can do stack allocation and -// initialization of our runtime structures like the Decoder and Sink. +/* Unlike most of our exposed Lua functions, this does not correspond to an + * actual method on the underlying DecoderMethod. But it's convenient, and + * important to implement in C because we can do stack allocation and + * initialization of our runtime structures like the Decoder and Sink. */ static int lupb_pbdecodermethod_parse(lua_State *L) { size_t len; const upb_pbdecodermethod *method = lupb_pbdecodermethod_check(L, 1); const char *pb = lua_tolstring(L, 2, &len); + void *msg; + upb_status status = UPB_STATUS_INIT; + upb_env env; + upb_sink sink; + upb_pbdecoder *decoder; const upb_handlers *handlers = upb_pbdecodermethod_desthandlers(method); lua_getuservalue(L, 1); lua_rawgeti(L, -1, MSGDEF_INDEX); lupb_assert(L, !lua_isnil(L, -1)); - lupb_msg_pushnew(L, -1); // Push new message. - void *msg = lua_touserdata(L, -1); + lupb_msg_pushnew(L, -1); /* Push new message. */ + msg = lua_touserdata(L, -1); - // Handlers need this. + /* Handlers need this. */ lua_getuservalue(L, -1); - upb_status status = UPB_STATUS_INIT; - upb_env env; upb_env_init(&env); upb_env_reporterrorsto(&env, &status); - upb_sink sink; upb_sink_reset(&sink, handlers, msg); - upb_pbdecoder *decoder = upb_pbdecoder_create(&env, method, &sink); + decoder = upb_pbdecoder_create(&env, method, &sink); upb_bufsrc_putbuf(pb, len, upb_pbdecoder_input(decoder)); - // TODO: This won't get called in the error case, which longjmp's across us. - // This will cause the memory to leak. To remedy this, we should make the - // upb_env wrapped in a userdata that guarantees this will get called. + /* TODO: This won't get called in the error case, which longjmp's across us. + * This will cause the memory to leak. To remedy this, we should make the + * upb_env wrapped in a userdata that guarantees this will get called. */ upb_env_uninit(&env); lupb_checkstatus(L, &status); - lua_pop(L, 1); // Uservalue. + lua_pop(L, 1); /* Uservalue. */ return 1; } diff --git a/upb/bindings/lua/upb/table.c b/upb/bindings/lua/upb/table.c index 4bda63d..b82b3f8 100644 --- a/upb/bindings/lua/upb/table.c +++ b/upb/bindings/lua/upb/table.c @@ -25,7 +25,9 @@ #include "lauxlib.h" #include "upb/bindings/lua/upb.h" #include "upb/def.h" +#include "upb/structdefs.int.h" #include "upb/symtab.h" +#include "upb/table.int.h" static void lupbtable_setnum(lua_State *L, int tab, const char *key, lua_Number val) { @@ -33,30 +35,30 @@ static void lupbtable_setnum(lua_State *L, int tab, const char *key, lua_setfield(L, tab - 1, key); } -static void lupbtable_pushval(lua_State *L, _upb_value val, upb_ctype_t ctype) { +static void lupbtable_pushval(lua_State *L, upb_tabval val, upb_ctype_t ctype) { switch (ctype) { case UPB_CTYPE_INT32: - lua_pushnumber(L, val.int32); + lua_pushnumber(L, val.val); break; case UPB_CTYPE_PTR: - lupb_def_pushwrapper(L, val.ptr, NULL); + lupb_def_pushwrapper(L, (void*)val.val, NULL); break; case UPB_CTYPE_CSTR: - lua_pushstring(L, val.cstr); + lua_pushstring(L, (const char*)val.val); break; default: luaL_error(L, "Unexpected type: %d", ctype); } } -// Sets a few fields common to both hash table entries and arrays. +/* Sets a few fields common to both hash table entries and arrays. */ static void lupbtable_setmetafields(lua_State *L, int ctype, const void *ptr) { - // We tack this onto every entry so we know it even if the entries - // don't stay with the table. + /* We tack this onto every entry so we know it even if the entries + * don't stay with the table. */ lua_pushnumber(L, ctype); lua_setfield(L, -2, "valtype"); - // Set this to facilitate linking. + /* Set this to facilitate linking. */ lua_pushlightuserdata(L, (void*)ptr); lua_setfield(L, -2, "ptr"); } @@ -81,8 +83,10 @@ static void lupbtable_pushent(lua_State *L, const upb_tabent *e, lupbtable_setmetafields(L, ctype, e); } -// Dumps the shared part of upb_table into a Lua table. +/* Dumps the shared part of upb_table into a Lua table. */ static void lupbtable_pushtable(lua_State *L, const upb_table *t, bool inttab) { + size_t i; + lua_newtable(L); lupbtable_setnum(L, -1, "count", t->count); lupbtable_setnum(L, -1, "mask", t->mask); @@ -90,21 +94,23 @@ static void lupbtable_pushtable(lua_State *L, const upb_table *t, bool inttab) { lupbtable_setnum(L, -1, "size_lg2", t->size_lg2); lua_newtable(L); - for (size_t i = 0; i < upb_table_size(t); i++) { + for (i = 0; i < upb_table_size(t); i++) { lupbtable_pushent(L, &t->entries[i], inttab, t->ctype); lua_rawseti(L, -2, i + 1); } lua_setfield(L, -2, "entries"); } -// Dumps a upb_inttable to a Lua table. +/* Dumps a upb_inttable to a Lua table. */ static void lupbtable_pushinttable(lua_State *L, const upb_inttable *t) { + size_t i; + lupbtable_pushtable(L, &t->t, true); lupbtable_setnum(L, -1, "array_size", t->array_size); lupbtable_setnum(L, -1, "array_count", t->array_count); lua_newtable(L); - for (size_t i = 0; i < t->array_size; i++) { + for (i = 0; i < t->array_size; i++) { lua_newtable(L); if (upb_arrhas(t->array[i])) { lupbtable_pushval(L, t->array[i], t->t.ctype); @@ -155,12 +161,40 @@ static void lupbtable_setfieldi(lua_State *L, const char *field, int i) { lua_setfield(L, -2, field); } +/* These aren't from the table, but they access other internal-only + * definitions. */ +static int lupb_fielddef_selectorbase(lua_State *L) { + const upb_fielddef *f = lupb_fielddef_check(L, 1); + if (!upb_fielddef_isfrozen(f)) + luaL_error(L, "_selectorbase is only defined for frozen fielddefs"); + lua_pushinteger(L, f->selector_base); + return 1; +} + +static int lupb_msgdef_selectorcount(lua_State *L) { + const upb_msgdef *m = lupb_msgdef_check(L, 1); + lua_pushinteger(L, m->selector_count); + return 1; +} + +static int lupb_msgdef_submsgfieldcount(lua_State *L) { + const upb_msgdef *m = lupb_msgdef_check(L, 1); + lua_pushinteger(L, m->submsg_field_count); + return 1; +} + static const struct luaL_Reg lupbtable_toplevel_m[] = { {"msgdef_itof", lupbtable_msgdef_itof}, {"msgdef_ntof", lupbtable_msgdef_ntof}, {"enumdef_iton", lupbtable_enumdef_iton}, {"enumdef_ntoi", lupbtable_enumdef_ntoi}, {"symtab_symtab", lupbtable_symtab_symtab}, + + {"msgdef_selector_count", lupb_msgdef_selectorcount}, + {"msgdef_submsg_field_count", lupb_msgdef_submsgfieldcount}, + + {"fielddef_selector_base", lupb_fielddef_selectorbase}, + {NULL, NULL} }; @@ -170,7 +204,7 @@ int luaopen_upb_table_c(lua_State *L) { return 1; } - // We define these here because they are not public. + /* We define these here because they are not public. */ lupbtable_setfieldi(L, "CTYPE_PTR", UPB_CTYPE_PTR); lupbtable_setfieldi(L, "CTYPE_CSTR", UPB_CTYPE_CSTR); lupbtable_setfieldi(L, "CTYPE_INT32", UPB_CTYPE_INT32); @@ -178,5 +212,5 @@ int luaopen_upb_table_c(lua_State *L) { lua_pushlightuserdata(L, NULL); lua_setfield(L, -2, "NULL"); - return 1; // Return a single Lua value, the package table created above. + return 1; /* Return a single Lua value, the package table created above. */ } |