Merge branch 'master' into v2.1
[luajit-2.0.git] / src / lj_meta.c
blobdea456f2eac79dcc4cb578df6b43e207132a67af
1 /*
2 ** Metamethod handling.
3 ** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h
4 **
5 ** Portions taken verbatim or adapted from the Lua interpreter.
6 ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
7 */
9 #define lj_meta_c
10 #define LUA_CORE
12 #include "lj_obj.h"
13 #include "lj_gc.h"
14 #include "lj_err.h"
15 #include "lj_buf.h"
16 #include "lj_str.h"
17 #include "lj_tab.h"
18 #include "lj_meta.h"
19 #include "lj_frame.h"
20 #include "lj_bc.h"
21 #include "lj_vm.h"
22 #include "lj_strscan.h"
23 #include "lj_strfmt.h"
24 #include "lj_lib.h"
26 /* -- Metamethod handling ------------------------------------------------- */
28 /* String interning of metamethod names for fast indexing. */
29 void lj_meta_init(lua_State *L)
31 #define MMNAME(name) "__" #name
32 const char *metanames = MMDEF(MMNAME);
33 #undef MMNAME
34 global_State *g = G(L);
35 const char *p, *q;
36 uint32_t mm;
37 for (mm = 0, p = metanames; *p; mm++, p = q) {
38 GCstr *s;
39 for (q = p+2; *q && *q != '_'; q++) ;
40 s = lj_str_new(L, p, (size_t)(q-p));
41 /* NOBARRIER: g->gcroot[] is a GC root. */
42 setgcref(g->gcroot[GCROOT_MMNAME+mm], obj2gco(s));
46 /* Negative caching of a few fast metamethods. See the lj_meta_fast() macro. */
47 cTValue *lj_meta_cache(GCtab *mt, MMS mm, GCstr *name)
49 cTValue *mo = lj_tab_getstr(mt, name);
50 lua_assert(mm <= MM_FAST);
51 if (!mo || tvisnil(mo)) { /* No metamethod? */
52 mt->nomm |= (uint8_t)(1u<<mm); /* Set negative cache flag. */
53 return NULL;
55 return mo;
58 /* Lookup metamethod for object. */
59 cTValue *lj_meta_lookup(lua_State *L, cTValue *o, MMS mm)
61 GCtab *mt;
62 if (tvistab(o))
63 mt = tabref(tabV(o)->metatable);
64 else if (tvisudata(o))
65 mt = tabref(udataV(o)->metatable);
66 else
67 mt = tabref(basemt_obj(G(L), o));
68 if (mt) {
69 cTValue *mo = lj_tab_getstr(mt, mmname_str(G(L), mm));
70 if (mo)
71 return mo;
73 return niltv(L);
76 #if LJ_HASFFI
77 /* Tailcall from C function. */
78 int lj_meta_tailcall(lua_State *L, cTValue *tv)
80 TValue *base = L->base;
81 TValue *top = L->top;
82 const BCIns *pc = frame_pc(base-1); /* Preserve old PC from frame. */
83 copyTV(L, base-1, tv); /* Replace frame with new object. */
84 top->u32.lo = LJ_CONT_TAILCALL;
85 setframe_pc(top, pc);
86 setframe_gc(top+1, obj2gco(L)); /* Dummy frame object. */
87 setframe_ftsz(top+1, (int)((char *)(top+2) - (char *)base) + FRAME_CONT);
88 L->base = L->top = top+2;
90 ** before: [old_mo|PC] [... ...]
91 ** ^base ^top
92 ** after: [new_mo|itype] [... ...] [NULL|PC] [dummy|delta]
93 ** ^base/top
94 ** tailcall: [new_mo|PC] [... ...]
95 ** ^base ^top
97 return 0;
99 #endif
101 /* Setup call to metamethod to be run by Assembler VM. */
102 static TValue *mmcall(lua_State *L, ASMFunction cont, cTValue *mo,
103 cTValue *a, cTValue *b)
106 ** |-- framesize -> top top+1 top+2 top+3
107 ** before: [func slots ...]
108 ** mm setup: [func slots ...] [cont|?] [mo|tmtype] [a] [b]
109 ** in asm: [func slots ...] [cont|PC] [mo|delta] [a] [b]
110 ** ^-- func base ^-- mm base
111 ** after mm: [func slots ...] [result]
112 ** ^-- copy to base[PC_RA] --/ for lj_cont_ra
113 ** istruecond + branch for lj_cont_cond*
114 ** ignore for lj_cont_nop
115 ** next PC: [func slots ...]
117 TValue *top = L->top;
118 if (curr_funcisL(L)) top = curr_topL(L);
119 setcont(top, cont); /* Assembler VM stores PC in upper word. */
120 copyTV(L, top+1, mo); /* Store metamethod and two arguments. */
121 copyTV(L, top+2, a);
122 copyTV(L, top+3, b);
123 return top+2; /* Return new base. */
126 /* -- C helpers for some instructions, called from assembler VM ----------- */
128 /* Helper for TGET*. __index chain and metamethod. */
129 cTValue *lj_meta_tget(lua_State *L, cTValue *o, cTValue *k)
131 int loop;
132 for (loop = 0; loop < LJ_MAX_IDXCHAIN; loop++) {
133 cTValue *mo;
134 if (LJ_LIKELY(tvistab(o))) {
135 GCtab *t = tabV(o);
136 cTValue *tv = lj_tab_get(L, t, k);
137 if (!tvisnil(tv) ||
138 !(mo = lj_meta_fast(L, tabref(t->metatable), MM_index)))
139 return tv;
140 } else if (tvisnil(mo = lj_meta_lookup(L, o, MM_index))) {
141 lj_err_optype(L, o, LJ_ERR_OPINDEX);
142 return NULL; /* unreachable */
144 if (tvisfunc(mo)) {
145 L->top = mmcall(L, lj_cont_ra, mo, o, k);
146 return NULL; /* Trigger metamethod call. */
148 o = mo;
150 lj_err_msg(L, LJ_ERR_GETLOOP);
151 return NULL; /* unreachable */
154 /* Helper for TSET*. __newindex chain and metamethod. */
155 TValue *lj_meta_tset(lua_State *L, cTValue *o, cTValue *k)
157 TValue tmp;
158 int loop;
159 for (loop = 0; loop < LJ_MAX_IDXCHAIN; loop++) {
160 cTValue *mo;
161 if (LJ_LIKELY(tvistab(o))) {
162 GCtab *t = tabV(o);
163 cTValue *tv = lj_tab_get(L, t, k);
164 if (LJ_LIKELY(!tvisnil(tv))) {
165 t->nomm = 0; /* Invalidate negative metamethod cache. */
166 lj_gc_anybarriert(L, t);
167 return (TValue *)tv;
168 } else if (!(mo = lj_meta_fast(L, tabref(t->metatable), MM_newindex))) {
169 t->nomm = 0; /* Invalidate negative metamethod cache. */
170 lj_gc_anybarriert(L, t);
171 if (tv != niltv(L))
172 return (TValue *)tv;
173 if (tvisnil(k)) lj_err_msg(L, LJ_ERR_NILIDX);
174 else if (tvisint(k)) { setnumV(&tmp, (lua_Number)intV(k)); k = &tmp; }
175 else if (tvisnum(k) && tvisnan(k)) lj_err_msg(L, LJ_ERR_NANIDX);
176 return lj_tab_newkey(L, t, k);
178 } else if (tvisnil(mo = lj_meta_lookup(L, o, MM_newindex))) {
179 lj_err_optype(L, o, LJ_ERR_OPINDEX);
180 return NULL; /* unreachable */
182 if (tvisfunc(mo)) {
183 L->top = mmcall(L, lj_cont_nop, mo, o, k);
184 /* L->top+2 = v filled in by caller. */
185 return NULL; /* Trigger metamethod call. */
187 copyTV(L, &tmp, mo);
188 o = &tmp;
190 lj_err_msg(L, LJ_ERR_SETLOOP);
191 return NULL; /* unreachable */
194 static cTValue *str2num(cTValue *o, TValue *n)
196 if (tvisnum(o))
197 return o;
198 else if (tvisint(o))
199 return (setnumV(n, (lua_Number)intV(o)), n);
200 else if (tvisstr(o) && lj_strscan_num(strV(o), n))
201 return n;
202 else
203 return NULL;
206 /* Helper for arithmetic instructions. Coercion, metamethod. */
207 TValue *lj_meta_arith(lua_State *L, TValue *ra, cTValue *rb, cTValue *rc,
208 BCReg op)
210 MMS mm = bcmode_mm(op);
211 TValue tempb, tempc;
212 cTValue *b, *c;
213 if ((b = str2num(rb, &tempb)) != NULL &&
214 (c = str2num(rc, &tempc)) != NULL) { /* Try coercion first. */
215 setnumV(ra, lj_vm_foldarith(numV(b), numV(c), (int)mm-MM_add));
216 return NULL;
217 } else {
218 cTValue *mo = lj_meta_lookup(L, rb, mm);
219 if (tvisnil(mo)) {
220 mo = lj_meta_lookup(L, rc, mm);
221 if (tvisnil(mo)) {
222 if (str2num(rb, &tempb) == NULL) rc = rb;
223 lj_err_optype(L, rc, LJ_ERR_OPARITH);
224 return NULL; /* unreachable */
227 return mmcall(L, lj_cont_ra, mo, rb, rc);
231 /* Helper for CAT. Coercion, iterative concat, __concat metamethod. */
232 TValue *lj_meta_cat(lua_State *L, TValue *top, int left)
234 int fromc = 0;
235 if (left < 0) { left = -left; fromc = 1; }
236 do {
237 if (!(tvisstr(top) || tvisnumber(top)) ||
238 !(tvisstr(top-1) || tvisnumber(top-1))) {
239 cTValue *mo = lj_meta_lookup(L, top-1, MM_concat);
240 if (tvisnil(mo)) {
241 mo = lj_meta_lookup(L, top, MM_concat);
242 if (tvisnil(mo)) {
243 if (tvisstr(top-1) || tvisnumber(top-1)) top++;
244 lj_err_optype(L, top-1, LJ_ERR_OPCAT);
245 return NULL; /* unreachable */
248 /* One of the top two elements is not a string, call __cat metamethod:
250 ** before: [...][CAT stack .........................]
251 ** top-1 top top+1 top+2
252 ** pick two: [...][CAT stack ...] [o1] [o2]
253 ** setup mm: [...][CAT stack ...] [cont|?] [mo|tmtype] [o1] [o2]
254 ** in asm: [...][CAT stack ...] [cont|PC] [mo|delta] [o1] [o2]
255 ** ^-- func base ^-- mm base
256 ** after mm: [...][CAT stack ...] <--push-- [result]
257 ** next step: [...][CAT stack .............]
259 copyTV(L, top+2, top); /* Careful with the order of stack copies! */
260 copyTV(L, top+1, top-1);
261 copyTV(L, top, mo);
262 setcont(top-1, lj_cont_cat);
263 return top+1; /* Trigger metamethod call. */
264 } else {
265 /* Pick as many strings as possible from the top and concatenate them:
267 ** before: [...][CAT stack ...........................]
268 ** pick str: [...][CAT stack ...] [...... strings ......]
269 ** concat: [...][CAT stack ...] [result]
270 ** next step: [...][CAT stack ............]
272 TValue *e, *o = top;
273 uint64_t tlen = tvisstr(o) ? strV(o)->len : STRFMT_MAXBUF_NUM;
274 char *p, *buf;
275 do {
276 o--; tlen += tvisstr(o) ? strV(o)->len : STRFMT_MAXBUF_NUM;
277 } while (--left > 0 && (tvisstr(o-1) || tvisnumber(o-1)));
278 if (tlen >= LJ_MAX_STR) lj_err_msg(L, LJ_ERR_STROV);
279 p = buf = lj_buf_tmp(L, (MSize)tlen);
280 for (e = top, top = o; o <= e; o++) {
281 if (tvisstr(o)) {
282 GCstr *s = strV(o);
283 MSize len = s->len;
284 p = lj_buf_wmem(p, strdata(s), len);
285 } else if (tvisint(o)) {
286 p = lj_strfmt_wint(p, intV(o));
287 } else {
288 lua_assert(tvisnum(o));
289 p = lj_strfmt_wnum(p, o);
292 setstrV(L, top, lj_str_new(L, buf, (size_t)(p-buf)));
294 } while (left >= 1);
295 if (LJ_UNLIKELY(G(L)->gc.total >= G(L)->gc.threshold)) {
296 if (!fromc) L->top = curr_topL(L);
297 lj_gc_step(L);
299 return NULL;
302 /* Helper for LEN. __len metamethod. */
303 TValue * LJ_FASTCALL lj_meta_len(lua_State *L, cTValue *o)
305 cTValue *mo = lj_meta_lookup(L, o, MM_len);
306 if (tvisnil(mo)) {
307 if (LJ_52 && tvistab(o))
308 tabref(tabV(o)->metatable)->nomm |= (uint8_t)(1u<<MM_len);
309 else
310 lj_err_optype(L, o, LJ_ERR_OPLEN);
311 return NULL;
313 return mmcall(L, lj_cont_ra, mo, o, LJ_52 ? o : niltv(L));
316 /* Helper for equality comparisons. __eq metamethod. */
317 TValue *lj_meta_equal(lua_State *L, GCobj *o1, GCobj *o2, int ne)
319 /* Field metatable must be at same offset for GCtab and GCudata! */
320 cTValue *mo = lj_meta_fast(L, tabref(o1->gch.metatable), MM_eq);
321 if (mo) {
322 TValue *top;
323 uint32_t it;
324 if (tabref(o1->gch.metatable) != tabref(o2->gch.metatable)) {
325 cTValue *mo2 = lj_meta_fast(L, tabref(o2->gch.metatable), MM_eq);
326 if (mo2 == NULL || !lj_obj_equal(mo, mo2))
327 return (TValue *)(intptr_t)ne;
329 top = curr_top(L);
330 setcont(top, ne ? lj_cont_condf : lj_cont_condt);
331 copyTV(L, top+1, mo);
332 it = ~(uint32_t)o1->gch.gct;
333 setgcV(L, top+2, o1, it);
334 setgcV(L, top+3, o2, it);
335 return top+2; /* Trigger metamethod call. */
337 return (TValue *)(intptr_t)ne;
340 #if LJ_HASFFI
341 TValue * LJ_FASTCALL lj_meta_equal_cd(lua_State *L, BCIns ins)
343 ASMFunction cont = (bc_op(ins) & 1) ? lj_cont_condf : lj_cont_condt;
344 int op = (int)bc_op(ins) & ~1;
345 TValue tv;
346 cTValue *mo, *o2, *o1 = &L->base[bc_a(ins)];
347 cTValue *o1mm = o1;
348 if (op == BC_ISEQV) {
349 o2 = &L->base[bc_d(ins)];
350 if (!tviscdata(o1mm)) o1mm = o2;
351 } else if (op == BC_ISEQS) {
352 setstrV(L, &tv, gco2str(proto_kgc(curr_proto(L), ~(ptrdiff_t)bc_d(ins))));
353 o2 = &tv;
354 } else if (op == BC_ISEQN) {
355 o2 = &mref(curr_proto(L)->k, cTValue)[bc_d(ins)];
356 } else {
357 lua_assert(op == BC_ISEQP);
358 setitype(&tv, ~bc_d(ins));
359 o2 = &tv;
361 mo = lj_meta_lookup(L, o1mm, MM_eq);
362 if (LJ_LIKELY(!tvisnil(mo)))
363 return mmcall(L, cont, mo, o1, o2);
364 else
365 return (TValue *)(intptr_t)(bc_op(ins) & 1);
367 #endif
369 /* Helper for ordered comparisons. String compare, __lt/__le metamethods. */
370 TValue *lj_meta_comp(lua_State *L, cTValue *o1, cTValue *o2, int op)
372 if (LJ_HASFFI && (tviscdata(o1) || tviscdata(o2))) {
373 ASMFunction cont = (op & 1) ? lj_cont_condf : lj_cont_condt;
374 MMS mm = (op & 2) ? MM_le : MM_lt;
375 cTValue *mo = lj_meta_lookup(L, tviscdata(o1) ? o1 : o2, mm);
376 if (LJ_UNLIKELY(tvisnil(mo))) goto err;
377 return mmcall(L, cont, mo, o1, o2);
378 } else if (LJ_52 || itype(o1) == itype(o2)) {
379 /* Never called with two numbers. */
380 if (tvisstr(o1) && tvisstr(o2)) {
381 int32_t res = lj_str_cmp(strV(o1), strV(o2));
382 return (TValue *)(intptr_t)(((op&2) ? res <= 0 : res < 0) ^ (op&1));
383 } else {
384 trymt:
385 while (1) {
386 ASMFunction cont = (op & 1) ? lj_cont_condf : lj_cont_condt;
387 MMS mm = (op & 2) ? MM_le : MM_lt;
388 cTValue *mo = lj_meta_lookup(L, o1, mm);
389 #if LJ_52
390 if (tvisnil(mo) && tvisnil((mo = lj_meta_lookup(L, o2, mm))))
391 #else
392 cTValue *mo2 = lj_meta_lookup(L, o2, mm);
393 if (tvisnil(mo) || !lj_obj_equal(mo, mo2))
394 #endif
396 if (op & 2) { /* MM_le not found: retry with MM_lt. */
397 cTValue *ot = o1; o1 = o2; o2 = ot; /* Swap operands. */
398 op ^= 3; /* Use LT and flip condition. */
399 continue;
401 goto err;
403 return mmcall(L, cont, mo, o1, o2);
406 } else if (tvisbool(o1) && tvisbool(o2)) {
407 goto trymt;
408 } else {
409 err:
410 lj_err_comp(L, o1, o2);
411 return NULL;
415 /* Helper for ISTYPE and ISNUM. Implicit coercion or error. */
416 void lj_meta_istype(lua_State *L, BCReg ra, BCReg tp)
418 L->top = curr_topL(L);
419 ra++; tp--;
420 lua_assert(LJ_DUALNUM || tp != ~LJ_TNUMX); /* ISTYPE -> ISNUM broken. */
421 if (LJ_DUALNUM && tp == ~LJ_TNUMX) lj_lib_checkint(L, ra);
422 else if (tp == ~LJ_TNUMX+1) lj_lib_checknum(L, ra);
423 else if (tp == ~LJ_TSTR) lj_lib_checkstr(L, ra);
424 else lj_err_argtype(L, ra, lj_obj_itypename[tp]);
427 /* Helper for calls. __call metamethod. */
428 void lj_meta_call(lua_State *L, TValue *func, TValue *top)
430 cTValue *mo = lj_meta_lookup(L, func, MM_call);
431 TValue *p;
432 if (!tvisfunc(mo))
433 lj_err_optype_call(L, func);
434 for (p = top; p > func; p--) copyTV(L, p, p-1);
435 copyTV(L, func, mo);
438 /* Helper for FORI. Coercion. */
439 void LJ_FASTCALL lj_meta_for(lua_State *L, TValue *o)
441 if (!lj_strscan_numberobj(o)) lj_err_msg(L, LJ_ERR_FORINIT);
442 if (!lj_strscan_numberobj(o+1)) lj_err_msg(L, LJ_ERR_FORLIM);
443 if (!lj_strscan_numberobj(o+2)) lj_err_msg(L, LJ_ERR_FORSTEP);
444 if (LJ_DUALNUM) {
445 /* Ensure all slots are integers or all slots are numbers. */
446 int32_t k[3];
447 int nint = 0;
448 ptrdiff_t i;
449 for (i = 0; i <= 2; i++) {
450 if (tvisint(o+i)) {
451 k[i] = intV(o+i); nint++;
452 } else {
453 k[i] = lj_num2int(numV(o+i)); nint += ((lua_Number)k[i] == numV(o+i));
456 if (nint == 3) { /* Narrow to integers. */
457 setintV(o, k[0]);
458 setintV(o+1, k[1]);
459 setintV(o+2, k[2]);
460 } else if (nint != 0) { /* Widen to numbers. */
461 if (tvisint(o)) setnumV(o, (lua_Number)intV(o));
462 if (tvisint(o+1)) setnumV(o+1, (lua_Number)intV(o+1));
463 if (tvisint(o+2)) setnumV(o+2, (lua_Number)intV(o+2));