[Tarantool-patches] [PATCH v2 1/2] uuid: support comparison of uuid values in Lua

Igor Munkin imun at tarantool.org
Tue Nov 24 16:06:42 MSK 2020


Oleg,

This is not a review, I just want to clarify Vlad's point here. I'll
make a review in a separate reply.

On 24.11.20, Oleg Babin wrote:
> Hi! Thanks for comments!
> 
> On 24/11/2020 00:58, Vladislav Shpilevoy wrote:

<snipped>

> 
> > But I can't give you a test, since I have no idea how to provide
> > lhs with non-uuid type. Igor said we can give metatable of uuid to
> > some non-uuid value, but I failed to assign uuid metatable to
> > anything else.
> 
> It's possible but I don't think it's really needed. I put small snippet 
> below:
> 
> uuid = require('uuid')
> eq = debug.getmetatable(uuid()).__eq
> eq('', uuid()) -- error: incorrect value to compare with uuid as 1 argument
> proxy = newproxy()
> debug.setmetatable(proxy, {__eq = eq})
> proxy == uuid() -- error: '[string "return proxy == uuid()"]:1: 
> incorrect value to compare with uuid as 1 argument'
> 
> I can add it to our test suite but it looks really strange

Unfortunately this simply doesn't work the way you want. Consider the
following:
| $ ./src/tarantool
| Tarantool 2.7.0-42-g374917337
| type 'help' for interactive help
| tarantool> require('ffi').typeof(box.error.new(box.error.UNKNOWN))
| ---
| - ctype<const struct error &>
| ...
| 
| tarantool> require('ffi').typeof(require('uuid')())
| ---
| - ctype<struct tt_uuid>
| ...
| 
| tarantool> debug.getmetatable(box.error.new(box.error.UNKNOWN)) == debug.getmetatable(require('uuid')())
| ---
| - true
| ...
| 
| tarantool>

Oops... It occurs ctype<const struct error &> shares the same metatable
as ctype<struct tt_uuid>, doesn't it? Yes, it does. At this place FFI
conforms Lua reference manual section[1] describing the metatables:
| Tables and full userdata have individual metatables (although multiple
| tables and userdata can share their metatables). Values of all other
| types share one single metatable per type; that is, there is one single
| metatable for all numbers, one for all strings, etc.

I guess there is no legal (i.e. using only Lua with no LuaJIT internals)
way to check that the function you obtained in the test is
<lj_cf_ffi_meta___eq> fast function (although, you can check yourself
via luajit-gdb.py), so just trust me. */me making Jedi mind tricks here*

Anyway, how does this magic work? We need to distinguish *metatables*
and *metatypes* -- the latter one is specific only for GCcdata. The
metatype metamethod is chosen underneath <lj_cf_ffi_meta___eq>
considering the ctype passed via the one of the arguments. I've already
described metatype metamethods resolution in the previous reply.

There is uuid in both of the tests above, so we can see only the error
related to the miscomparison, but AFAIU Vlad asked about the error
raised on check_uuid (with the "Usage: blah-blah" error message). The
current implementation provides no way to reproduce it (maybe via other
debug.* interfaces, I haven't checked this yet).

> 

<snipped>

> 

[1]: https://www.lua.org/manual/5.1/manual.html#2.8

-- 
Best regards,
IM


More information about the Tarantool-patches mailing list