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