diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-06-25 17:45:50 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-06-25 17:45:50 -0300 |
commit | c1a63c45f8ec5932993c8cec40d3c5ec0743349c (patch) | |
tree | a61e8edb10b498c25e961cd7b2c7cb857e9db4c7 /ldo.c | |
parent | 4487c28ced3dcf47c3ee19b6f6eeb0089ec64ba5 (diff) | |
download | lua-c1a63c45f8ec5932993c8cec40d3c5ec0743349c.tar.gz lua-c1a63c45f8ec5932993c8cec40d3c5ec0743349c.tar.bz2 lua-c1a63c45f8ec5932993c8cec40d3c5ec0743349c.zip |
'__call' metamethod can be any callable object
Removed the restriction that a '__call' metamethod must be an actual
function.
Diffstat (limited to 'ldo.c')
-rw-r--r-- | ldo.c | 28 |
1 files changed, 14 insertions, 14 deletions
@@ -348,18 +348,18 @@ static StkId rethook (lua_State *L, CallInfo *ci, StkId firstres, int nres) { | |||
348 | 348 | ||
349 | 349 | ||
350 | /* | 350 | /* |
351 | ** Check whether __call metafield of 'func' is a function. If so, put | 351 | ** Check whether 'func' has a '__call' metafield. If so, put it in the |
352 | ** it in stack below original 'func' so that 'luaD_call' can call | 352 | ** stack, below original 'func', so that 'luaD_call' can call it. Raise |
353 | ** it. Raise an error if __call metafield is not a function. | 353 | ** an error if there is no '__call' metafield. |
354 | */ | 354 | */ |
355 | void luaD_tryfuncTM (lua_State *L, StkId func) { | 355 | void luaD_tryfuncTM (lua_State *L, StkId func) { |
356 | const TValue *tm = luaT_gettmbyobj(L, s2v(func), TM_CALL); | 356 | const TValue *tm = luaT_gettmbyobj(L, s2v(func), TM_CALL); |
357 | StkId p; | 357 | StkId p; |
358 | if (unlikely(!ttisfunction(tm))) | 358 | if (unlikely(ttisnil(tm))) |
359 | luaG_typeerror(L, s2v(func), "call"); | 359 | luaG_typeerror(L, s2v(func), "call"); /* nothing to call */ |
360 | for (p = L->top; p > func; p--) | 360 | for (p = L->top; p > func; p--) /* open space for metamethod */ |
361 | setobjs2s(L, p, p-1); | 361 | setobjs2s(L, p, p-1); |
362 | L->top++; /* assume EXTRA_STACK */ | 362 | L->top++; /* stack space pre-allocated by the caller */ |
363 | setobj2s(L, func, tm); /* metamethod is the new function to be called */ | 363 | setobj2s(L, func, tm); /* metamethod is the new function to be called */ |
364 | } | 364 | } |
365 | 365 | ||
@@ -457,13 +457,13 @@ void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int narg1) { | |||
457 | */ | 457 | */ |
458 | void luaD_call (lua_State *L, StkId func, int nresults) { | 458 | void luaD_call (lua_State *L, StkId func, int nresults) { |
459 | lua_CFunction f; | 459 | lua_CFunction f; |
460 | TValue *funcv = s2v(func); | 460 | retry: |
461 | switch (ttypetag(funcv)) { | 461 | switch (ttypetag(s2v(func))) { |
462 | case LUA_TCCL: /* C closure */ | 462 | case LUA_TCCL: /* C closure */ |
463 | f = clCvalue(funcv)->f; | 463 | f = clCvalue(s2v(func))->f; |
464 | goto Cfunc; | 464 | goto Cfunc; |
465 | case LUA_TLCF: /* light C function */ | 465 | case LUA_TLCF: /* light C function */ |
466 | f = fvalue(funcv); | 466 | f = fvalue(s2v(func)); |
467 | Cfunc: { | 467 | Cfunc: { |
468 | int n; /* number of returns */ | 468 | int n; /* number of returns */ |
469 | CallInfo *ci; | 469 | CallInfo *ci; |
@@ -487,7 +487,7 @@ void luaD_call (lua_State *L, StkId func, int nresults) { | |||
487 | } | 487 | } |
488 | case LUA_TLCL: { /* Lua function */ | 488 | case LUA_TLCL: { /* Lua function */ |
489 | CallInfo *ci; | 489 | CallInfo *ci; |
490 | Proto *p = clLvalue(funcv)->p; | 490 | Proto *p = clLvalue(s2v(func))->p; |
491 | int narg = cast_int(L->top - func) - 1; /* number of real arguments */ | 491 | int narg = cast_int(L->top - func) - 1; /* number of real arguments */ |
492 | int nfixparams = p->numparams; | 492 | int nfixparams = p->numparams; |
493 | int fsize = p->maxstacksize; /* frame size */ | 493 | int fsize = p->maxstacksize; /* frame size */ |
@@ -505,9 +505,9 @@ void luaD_call (lua_State *L, StkId func, int nresults) { | |||
505 | break; | 505 | break; |
506 | } | 506 | } |
507 | default: { /* not a function */ | 507 | default: { /* not a function */ |
508 | checkstackp(L, 1, func); /* space for metamethod */ | ||
508 | luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */ | 509 | luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */ |
509 | luaD_call(L, func, nresults); /* now it must be a function */ | 510 | goto retry; /* try again with metamethod */ |
510 | break; | ||
511 | } | 511 | } |
512 | } | 512 | } |
513 | } | 513 | } |