Line data Source code
1 : /*
2 : ** $Id: ltm.c,v 2.38.1.1 2017/04/19 17:39:34 roberto Exp $
3 : ** Tag methods
4 : ** See Copyright Notice in lua.h
5 : */
6 :
7 : #define ltm_c
8 : #define LUA_CORE
9 :
10 : #include "lprefix.h"
11 :
12 :
13 : #include <string.h>
14 :
15 : #include "lua.h"
16 :
17 : #include "ldebug.h"
18 : #include "ldo.h"
19 : #include "lobject.h"
20 : #include "lstate.h"
21 : #include "lstring.h"
22 : #include "ltable.h"
23 : #include "ltm.h"
24 : #include "lvm.h"
25 :
26 : // lua code does lots of casting, these warnings are not helpful
27 : #pragma GCC diagnostic ignored "-Wcast-align"
28 :
29 : static const char udatatypename[] = "userdata";
30 :
31 : LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTAGS] = {
32 : "no value",
33 : "nil", "boolean", udatatypename, "number",
34 : "string", "table", "function", udatatypename, "thread",
35 : "proto" /* this last case is used for tests only */
36 : };
37 :
38 :
39 97 : void luaT_init (lua_State *L) {
40 : static const char *const luaT_eventname[] = { /* ORDER TM */
41 : "__index", "__newindex",
42 : "__gc", "__mode", "__len", "__eq",
43 : "__add", "__sub", "__mul", "__mod", "__pow",
44 : "__div", "__idiv",
45 : "__band", "__bor", "__bxor", "__shl", "__shr",
46 : "__unm", "__bnot", "__lt", "__le",
47 : "__concat", "__call"
48 : };
49 : int i;
50 2425 : for (i=0; i<TM_N; i++) {
51 2328 : G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
52 2328 : luaC_fix(L, obj2gco(G(L)->tmname[i])); /* never collect these names */
53 : }
54 97 : }
55 :
56 :
57 : /*
58 : ** function to be used with macro "fasttm": optimized for absence of
59 : ** tag methods
60 : */
61 2288393 : const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
62 2288393 : const TValue *tm = luaH_getshortstr(events, ename);
63 : lua_assert(event <= TM_EQ);
64 2288393 : if (ttisnil(tm)) { /* no tag method? */
65 969 : events->flags |= cast_byte(1u<<event); /* cache this fact */
66 969 : return NULL;
67 : }
68 2287424 : else return tm;
69 : }
70 :
71 :
72 3317915 : const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
73 : Table *mt;
74 3317915 : switch (ttnov(o)) {
75 112 : case LUA_TTABLE:
76 112 : mt = hvalue(o)->metatable;
77 112 : break;
78 3304802 : case LUA_TUSERDATA:
79 3304802 : mt = uvalue(o)->metatable;
80 3304802 : break;
81 13001 : default:
82 13001 : mt = G(L)->mt[ttnov(o)];
83 : }
84 3317915 : return (mt ? luaH_getshortstr(mt, G(L)->tmname[event]) : luaO_nilobject);
85 : }
86 :
87 :
88 : /*
89 : ** Return the name of the type of an object. For tables and userdata
90 : ** with metatable, use their '__name' metafield, if present.
91 : */
92 2 : const char *luaT_objtypename (lua_State *L, const TValue *o) {
93 : Table *mt;
94 2 : if ((ttistable(o) && (mt = hvalue(o)->metatable) != NULL) ||
95 2 : (ttisfulluserdata(o) && (mt = uvalue(o)->metatable) != NULL)) {
96 0 : const TValue *name = luaH_getshortstr(mt, luaS_new(L, "__name"));
97 0 : if (ttisstring(name)) /* is '__name' a string? */
98 0 : return getstr(tsvalue(name)); /* use it as type name */
99 : }
100 2 : return ttypename(ttnov(o)); /* else use standard type name */
101 : }
102 :
103 :
104 3305283 : void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1,
105 : const TValue *p2, TValue *p3, int hasres) {
106 3305283 : ptrdiff_t result = savestack(L, p3);
107 3305283 : StkId func = L->top;
108 3305283 : setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */
109 3305283 : setobj2s(L, func + 1, p1); /* 1st argument */
110 3305283 : setobj2s(L, func + 2, p2); /* 2nd argument */
111 3305283 : L->top += 3;
112 3305283 : if (!hasres) /* no result? 'p3' is third argument */
113 0 : setobj2s(L, L->top++, p3); /* 3rd argument */
114 : /* metamethod may yield only when called from Lua code */
115 3305283 : if (isLua(L->ci))
116 3305283 : luaD_call(L, func, hasres);
117 : else
118 0 : luaD_callnoyield(L, func, hasres);
119 3305283 : if (hasres) { /* if has result, move it to its place */
120 3305283 : p3 = restorestack(L, result);
121 3305283 : setobjs2s(L, p3, --L->top);
122 : }
123 3305283 : }
124 :
125 :
126 193279 : int luaT_callbinTM (lua_State *L, const TValue *p1, const TValue *p2,
127 : StkId res, TMS event) {
128 193279 : const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */
129 193279 : if (ttisnil(tm))
130 12975 : tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
131 193279 : if (ttisnil(tm)) return 0;
132 193271 : luaT_callTM(L, tm, p1, p2, res, 1);
133 193271 : return 1;
134 : }
135 :
136 :
137 180121 : void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
138 : StkId res, TMS event) {
139 180121 : if (!luaT_callbinTM(L, p1, p2, res, event)) {
140 8 : switch (event) {
141 0 : case TM_CONCAT:
142 0 : luaG_concaterror(L, p1, p2);
143 : /* call never returns, but to avoid warnings: *//* FALLTHROUGH */
144 8 : case TM_BAND: case TM_BOR: case TM_BXOR:
145 : case TM_SHL: case TM_SHR: case TM_BNOT: {
146 : lua_Number dummy;
147 8 : if (tonumber(p1, &dummy) && tonumber(p2, &dummy))
148 8 : luaG_tointerror(L, p1, p2);
149 : else
150 0 : luaG_opinterror(L, p1, p2, "perform bitwise operation on");
151 : }
152 : /* calls never return, but to avoid warnings: *//* FALLTHROUGH */
153 0 : default:
154 0 : luaG_opinterror(L, p1, p2, "perform arithmetic on");
155 : }
156 : }
157 180113 : }
158 :
159 :
160 13158 : int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2,
161 : TMS event) {
162 13158 : if (!luaT_callbinTM(L, p1, p2, L->top, event))
163 0 : return -1; /* no metamethod */
164 : else
165 13158 : return !l_isfalse(L->top);
166 : }
167 :
|