3

I have C++ application which uses Lua C API. I declared global table via lua api:

lua_newtable(L);

lua_pushstring(L, "someLuaFunc");
lua_pushcfunction(L, &someCFunc);
lua_settable(L, -3);

lua_setglobal(L, "table1");

and now I can call someLuaFunc using '.' or ':'

table1.someLuaFunc()
table1:someLuaFunc()

and both cases will run someCFunc.

Question is: is there any way, inside someCFunc, to determine how it was called (via : or .)?

Checking argument count and types is not an option in my case.

warspyking
  • 3,045
  • 4
  • 20
  • 37
  • 1
    Maybe someone could help further if you specify, what you are trying to achieve at all, i.e. why it is no option to check argument count or types, which would be the obvious way – Ctx Dec 14 '15 at 13:15

2 Answers2

2

No, you can't.

object:method()

is directly translated to

main <123.lua:0,0> (4 instructions, 16 bytes at 00020510)
0+ params, 2 slots, 0 upvalues, 0 locals, 2 constants, 0 functions
        1       [1]     GETGLOBAL       0 -1    ; object
        2       [1]     SELF            0 0 -2  ; "method"
        3       [1]     CALL            0 2 1

That is, SELF opcode aranges function right near calling object on registers and then CALL opcode performs regular call.

Lua's paradigm in this case is duck typing. There's no distinct type, just table (or userinfo) anyway, so just check if your argument have necessary data/methods you want to process/call and reject if it doesn't.

Oleg V. Volkov
  • 21,719
  • 4
  • 44
  • 68
  • Is it possible to get those instructions in pure Lua? (Like ```GetInstructions(func)```?) If so how would you? – warspyking Dec 14 '15 at 16:00
  • @warspyking, yes and no. You can use `string.dump` to get opcode dump, but its usage is not supported in any way except `loadstring`ing it back, so you're on your own with parsing it. – Oleg V. Volkov Dec 14 '15 at 16:26
  • Actually, there's also @lhf's bytecode inspector library [lbci](http://www.tecgraf.puc-rio.br/~lhf/ftp/lua/#lbci) (also available via LuaRocks). – siffiejoe Dec 14 '15 at 17:50
  • @Oleg When I print out string.dump character by character I don't get instructions, what am I missing? – warspyking Dec 14 '15 at 18:27
2

I probably wouldn't rely on it, but Lua's debug library can figure this out (by looking for the OP_SELF opcode in the bytecode). In Lua:

local t = {}
function t:f()
  print( debug.getinfo( 1, "n" ).namewhat )
end

t.f( t ) --> prints "field"
t:f()    --> prints "method"

In C you would need lua_getstack() and lua_getinfo().

siffiejoe
  • 4,141
  • 1
  • 16
  • 16