summaryrefslogtreecommitdiff
path: root/upb/bindings/lua/upb/pb.c
diff options
context:
space:
mode:
authorJosh Haberman <jhaberman@gmail.com>2016-09-09 14:03:25 -0700
committerJosh Haberman <jhaberman@gmail.com>2016-11-29 17:56:13 +0000
commit4b0c4ca7fb0aa9207af3398e04534b23fbb88f27 (patch)
tree045750c6262e74f366ae2ec29797d3816005c21a /upb/bindings/lua/upb/pb.c
parent77c97fd3f29caa5c243294b5f4e6763b3ed3c36f (diff)
New upb_msg code and Lua bindings around it.
There are still some things that are unfinished, but we are at parity with what Lua had before.
Diffstat (limited to 'upb/bindings/lua/upb/pb.c')
-rw-r--r--upb/bindings/lua/upb/pb.c94
1 files changed, 41 insertions, 53 deletions
diff --git a/upb/bindings/lua/upb/pb.c b/upb/bindings/lua/upb/pb.c
index f095a61..d6f13d9 100644
--- a/upb/bindings/lua/upb/pb.c
+++ b/upb/bindings/lua/upb/pb.c
@@ -10,59 +10,24 @@
#define LUPB_PBDECODERMETHOD "lupb.pb.decodermethod"
-#define MSGDEF_INDEX 1
-
-static upb_pbdecodermethod *lupb_pbdecodermethod_check(lua_State *L, int narg) {
- return lupb_refcounted_check(L, narg, LUPB_PBDECODERMETHOD);
-}
-
-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);
-
- m = upb_pbdecodermethod_new(&opts, &m);
- upb_handlers_unref(handlers, &handlers);
- 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(). */
- lua_newtable(L);
- lua_pushvalue(L, 1);
- lua_rawseti(L, -2, MSGDEF_INDEX);
- lua_setuservalue(L, -2);
-
- 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. */
-static int lupb_pbdecodermethod_parse(lua_State *L) {
+static int lupb_pb_strtomessage(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;
+ const char *pb = lua_tolstring(L, 1, &len);
+ const upb_msglayout *layout = lua_touserdata(L, lua_upvalueindex(1));
+ const upb_pbdecodermethod *method = lua_touserdata(L, lua_upvalueindex(2));
+ const upb_handlers *handlers = upb_pbdecodermethod_desthandlers(method);
+
+ upb_arena *msg_arena;
upb_env env;
upb_sink sink;
upb_pbdecoder *decoder;
+ void *msg;
- 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. */
- msg = lua_touserdata(L, -1);
-
- /* Handlers need this. */
- lua_getuservalue(L, -1);
+ lupb_arena_new(L);
+ msg_arena = lupb_arena_check(L, -1);
+ msg = upb_msg_new(layout, upb_arena_alloc(msg_arena));
upb_env_init(&env);
upb_env_reporterrorsto(&env, &status);
upb_sink_reset(&sink, handlers, msg);
@@ -76,18 +41,42 @@ static int lupb_pbdecodermethod_parse(lua_State *L) {
lupb_checkstatus(L, &status);
- lua_pop(L, 1); /* Uservalue. */
-
+ /* References the arena at the top of the stack. */
+ lupb_msg_pushref(L, lua_upvalueindex(3), msg);
return 1;
}
-static const struct luaL_Reg lupb_pbdecodermethod_m[] = {
- {"parse", lupb_pbdecodermethod_parse},
+static int lupb_pb_makestrtomsgdecoder(lua_State *L) {
+ const upb_msglayout *layout = lupb_msgclass_getlayout(L, 1);
+ const upb_handlers *handlers = lupb_msgclass_getmergehandlers(L, 1);
+ const upb_pbdecodermethod *m;
+
+ upb_pbdecodermethodopts opts;
+ upb_pbdecodermethodopts_init(&opts, handlers);
+
+ m = upb_pbdecodermethod_new(&opts, &m);
+
+ /* Push upvalues for the closure. */
+ lua_pushlightuserdata(L, (void*)layout);
+ lua_pushlightuserdata(L, (void*)m);
+ lua_pushvalue(L, 1);
+
+ /* Upvalue for the closure, only to keep the decodermethod alive. */
+ lupb_refcounted_pushnewrapper(
+ L, upb_pbdecodermethod_upcast(m), LUPB_PBDECODERMETHOD, &m);
+
+ lua_pushcclosure(L, &lupb_pb_strtomessage, 4);
+
+ return 1; /* The decoder closure. */
+}
+
+static const struct luaL_Reg decodermethod_mm[] = {
+ {"__gc", lupb_refcounted_gc},
{NULL, NULL}
};
static const struct luaL_Reg toplevel_m[] = {
- {"DecoderMethod", lupb_pbdecodermethod_new},
+ {"MakeStringToMessageDecoder", lupb_pb_makestrtomsgdecoder},
{NULL, NULL}
};
@@ -97,8 +86,7 @@ int luaopen_upb_pb_c(lua_State *L) {
return 1;
}
- lupb_register_type(L, LUPB_PBDECODERMETHOD, lupb_pbdecodermethod_m, NULL,
- true);
+ lupb_register_type(L, LUPB_PBDECODERMETHOD, NULL, decodermethod_mm);
return 1;
}
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback