lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


It was thus said that the Great Laurent FAILLIE once stated:

> Arg, in this case, I'm facing a STRONG problem as I'm using this mechanism
> in other stuffs (like Marcel which is the daemon providing most of MQTT
> data from my 1-wire network).I don't have the choice, I need
> multi-threading as MQTT data have to arrive asynchronously (there is also
> a synchronous mode, but it not suitable as my tool is doing heavy
> graphical tasks, and it's cleaners in architectural point of view).
> 
> Obviously, I can delegate what I want to do to C side but in this case, I
> will loose the flexibility the have Lua code in early message arrival ...
> and all in all, I'm interested to know how I can exchange stuffs b/w
> totally different states.

  You are now talking about serialization.  Upshot:  for nil, booleans,
numbers, strings and tables (consisting of the previous types and containing
no cycles) there are any number of solutions available [1].  But for tables
containing cycles, userdata, lightuserdata, functions and threads ... not so
much.  I know of one module that can easily handle table cycles [2] but not
functions, threads, or userdata.

  For userdata, it might be possible to serialize, but 1) it is really
dependent upon the userdata in question and 2) will need code for both
encoding and decoding to work.  Lightuserdata ... more problematic as Lua
really treats the pointer as a glorified integer.

  Functions are an interesting problem.  Yes, you can get the bytecode
(string.dump()) but there are issues:  1) the default serialization of
functions will only work on the same architecture and 2) does not contain
the current values of any upvalues.  1) is not an issue with your usecase,
but 2) is.  Again, that can be worked around by not only encoding the
function (via string.dump()) but also including any upvalues, which can get
quite interesting (oh, an upvalue might be math.floor() or _G itself!).

  A few years ago I was able to do this (using an initial version of my CBOR
module [2]) and here's what I ended up having to do (NOTE: CBOR allows the
semtantic tagging of values, which makes this much easier):

	1) A function ended up being a CBOR array (if I recall) tagged as a
	   Lua function (the array is tagged).  The first element was either
	   a string, meaning the actual name of a known function, or a CBOR
	   array, comprising the actual bytecode (which should technically
	   be architecturally neutral but still limited to the same version
	   of Lua, like Lua 5.1 to 5.1, or Lua 5.3 to 5.3).

	2) The upvalues in another array (and if one of the upvalues was a
	   function, well, here we go again ... ),

	3) followed by the constants array, then any strings, then debugging
	   information---basically, I wrote my own version of string.dump()
	   on steroids [3].

I never finished it, not really needing it and having grown weary of the
whole endevour.  For me, in this instance, knowing what needs to be done was
good enough (wow!  harder than I thought).

  -spc

[1]	http://lua-users.org/wiki/TableSerialization

[2]	https://github.com/spc476/CBOR
	(disclaimer:  I wrote this)

[3]	So, if one of the upvalues was actually _G, then I would tag the
	string "_G" with *LuaKnownValue* so I knew to use _G on the
	receiving end.  All known globals like math and io.stdin were
	handled this way.