diff options
Diffstat (limited to 'src/lj_obj.h')
-rw-r--r-- | src/lj_obj.h | 229 |
1 files changed, 119 insertions, 110 deletions
diff --git a/src/lj_obj.h b/src/lj_obj.h index 819930c6..f29ecb0b 100644 --- a/src/lj_obj.h +++ b/src/lj_obj.h | |||
@@ -211,111 +211,6 @@ typedef const TValue cTValue; | |||
211 | #define LJ_TISGCV (LJ_TSTR+1) | 211 | #define LJ_TISGCV (LJ_TSTR+1) |
212 | #define LJ_TISTABUD LJ_TTAB | 212 | #define LJ_TISTABUD LJ_TTAB |
213 | 213 | ||
214 | /* -- TValue getters/setters ---------------------------------------------- */ | ||
215 | |||
216 | /* Macros to test types. */ | ||
217 | #define itype(o) ((o)->it) | ||
218 | #define tvisnil(o) (itype(o) == LJ_TNIL) | ||
219 | #define tvisfalse(o) (itype(o) == LJ_TFALSE) | ||
220 | #define tvistrue(o) (itype(o) == LJ_TTRUE) | ||
221 | #define tvisbool(o) (tvisfalse(o) || tvistrue(o)) | ||
222 | #if LJ_64 | ||
223 | #define tvislightud(o) (((int32_t)itype(o) >> 15) == -2) | ||
224 | #else | ||
225 | #define tvislightud(o) (itype(o) == LJ_TLIGHTUD) | ||
226 | #endif | ||
227 | #define tvisstr(o) (itype(o) == LJ_TSTR) | ||
228 | #define tvisfunc(o) (itype(o) == LJ_TFUNC) | ||
229 | #define tvisthread(o) (itype(o) == LJ_TTHREAD) | ||
230 | #define tvisproto(o) (itype(o) == LJ_TPROTO) | ||
231 | #define tvistab(o) (itype(o) == LJ_TTAB) | ||
232 | #define tvisudata(o) (itype(o) == LJ_TUDATA) | ||
233 | #define tvisnum(o) (itype(o) <= LJ_TISNUM) | ||
234 | |||
235 | #define tvistruecond(o) (itype(o) < LJ_TISTRUECOND) | ||
236 | #define tvispri(o) (itype(o) >= LJ_TISPRI) | ||
237 | #define tvistabud(o) (itype(o) <= LJ_TISTABUD) /* && !tvisnum() */ | ||
238 | #define tvisgcv(o) ((itype(o) - LJ_TISGCV) > (LJ_TNUMX - LJ_TISGCV)) | ||
239 | |||
240 | /* Special macros to test numbers for NaN, +0, -0, +1 and raw equality. */ | ||
241 | #define tvisnan(o) ((o)->n != (o)->n) | ||
242 | #define tvispzero(o) ((o)->u64 == 0) | ||
243 | #define tvismzero(o) ((o)->u64 == U64x(80000000,00000000)) | ||
244 | #define tvispone(o) ((o)->u64 == U64x(3ff00000,00000000)) | ||
245 | #define rawnumequal(o1, o2) ((o1)->u64 == (o2)->u64) | ||
246 | |||
247 | /* Macros to convert type ids. */ | ||
248 | #if LJ_64 | ||
249 | #define itypemap(o) \ | ||
250 | (tvisnum(o) ? ~LJ_TNUMX : tvislightud(o) ? ~LJ_TLIGHTUD : ~itype(o)) | ||
251 | #else | ||
252 | #define itypemap(o) (tvisnum(o) ? ~LJ_TNUMX : ~itype(o)) | ||
253 | #endif | ||
254 | |||
255 | /* Macros to get tagged values. */ | ||
256 | #define gcval(o) (gcref((o)->gcr)) | ||
257 | #define boolV(o) check_exp(tvisbool(o), (LJ_TFALSE - (o)->it)) | ||
258 | #if LJ_64 | ||
259 | #define lightudV(o) check_exp(tvislightud(o), \ | ||
260 | (void *)((o)->u64 & U64x(00007fff,ffffffff))) | ||
261 | #else | ||
262 | #define lightudV(o) check_exp(tvislightud(o), gcrefp((o)->gcr, void)) | ||
263 | #endif | ||
264 | #define gcV(o) check_exp(tvisgcv(o), gcval(o)) | ||
265 | #define strV(o) check_exp(tvisstr(o), &gcval(o)->str) | ||
266 | #define funcV(o) check_exp(tvisfunc(o), &gcval(o)->fn) | ||
267 | #define threadV(o) check_exp(tvisthread(o), &gcval(o)->th) | ||
268 | #define protoV(o) check_exp(tvisproto(o), &gcval(o)->pt) | ||
269 | #define tabV(o) check_exp(tvistab(o), &gcval(o)->tab) | ||
270 | #define udataV(o) check_exp(tvisudata(o), &gcval(o)->ud) | ||
271 | #define numV(o) check_exp(tvisnum(o), (o)->n) | ||
272 | |||
273 | /* Macros to set tagged values. */ | ||
274 | #define setitype(o, i) ((o)->it = (i)) | ||
275 | #define setnilV(o) ((o)->it = LJ_TNIL) | ||
276 | #define setboolV(o, x) ((o)->it = LJ_TFALSE-(x)) | ||
277 | |||
278 | #if LJ_64 | ||
279 | #define checklightudptr(L, p) \ | ||
280 | (((uint64_t)(p) >> 47) ? (lj_err_msg(L, LJ_ERR_BADLU), NULL) : (p)) | ||
281 | #define setlightudV(o, x) \ | ||
282 | ((o)->u64 = (uint64_t)(x) | (((uint64_t)0xffff) << 48)) | ||
283 | #define setcont(o, x) \ | ||
284 | ((o)->u64 = (uint64_t)(x) - (uint64_t)lj_vm_asm_begin) | ||
285 | #else | ||
286 | #define checklightudptr(L, p) (p) | ||
287 | #define setlightudV(o, x) \ | ||
288 | { TValue *i_o = (o); \ | ||
289 | setgcrefp(i_o->gcr, (x)); i_o->it = LJ_TLIGHTUD; } | ||
290 | #define setcont(o, x) \ | ||
291 | { TValue *i_o = (o); \ | ||
292 | setgcrefp(i_o->gcr, (x)); i_o->it = LJ_TLIGHTUD; } | ||
293 | #endif | ||
294 | |||
295 | #define tvchecklive(g, o) \ | ||
296 | lua_assert(!tvisgcv(o) || \ | ||
297 | ((~itype(o) == gcval(o)->gch.gct) && !isdead(g, gcval(o)))) | ||
298 | |||
299 | #define setgcV(L, o, x, itype) \ | ||
300 | { TValue *i_o = (o); \ | ||
301 | setgcrefp(i_o->gcr, &(x)->nextgc); i_o->it = itype; \ | ||
302 | tvchecklive(G(L), i_o); } | ||
303 | #define setstrV(L, o, x) setgcV(L, o, x, LJ_TSTR) | ||
304 | #define setthreadV(L, o, x) setgcV(L, o, x, LJ_TTHREAD) | ||
305 | #define setprotoV(L, o, x) setgcV(L, o, x, LJ_TPROTO) | ||
306 | #define setfuncV(L, o, x) setgcV(L, o, &(x)->l, LJ_TFUNC) | ||
307 | #define settabV(L, o, x) setgcV(L, o, x, LJ_TTAB) | ||
308 | #define setudataV(L, o, x) setgcV(L, o, x, LJ_TUDATA) | ||
309 | |||
310 | #define setnumV(o, x) ((o)->n = (x)) | ||
311 | #define setnanV(o) ((o)->u64 = U64x(fff80000,00000000)) | ||
312 | #define setintV(o, i) ((o)->n = cast_num((int32_t)(i))) | ||
313 | |||
314 | /* Copy tagged values. */ | ||
315 | #define copyTV(L, o1, o2) \ | ||
316 | { cTValue *i_o2 = (o2); TValue *i_o1 = (o1); \ | ||
317 | *i_o1 = *i_o2; tvchecklive(G(L), i_o1); } | ||
318 | |||
319 | /* -- String object ------------------------------------------------------- */ | 214 | /* -- String object ------------------------------------------------------- */ |
320 | 215 | ||
321 | /* String object header. String payload follows. */ | 216 | /* String object header. String payload follows. */ |
@@ -694,7 +589,125 @@ typedef union GCobj { | |||
694 | #define gco2ud(o) check_exp((o)->gch.gct == ~LJ_TUDATA, &(o)->ud) | 589 | #define gco2ud(o) check_exp((o)->gch.gct == ~LJ_TUDATA, &(o)->ud) |
695 | 590 | ||
696 | /* Macro to convert any collectable object into a GCobj pointer. */ | 591 | /* Macro to convert any collectable object into a GCobj pointer. */ |
697 | #define obj2gco(v) (cast(GCobj *, (v))) | 592 | #define obj2gco(v) ((GCobj *)(v)) |
593 | |||
594 | /* -- TValue getters/setters ---------------------------------------------- */ | ||
595 | |||
596 | #ifdef LUA_USE_ASSERT | ||
597 | #include "lj_gc.h" | ||
598 | #endif | ||
599 | |||
600 | /* Macros to test types. */ | ||
601 | #define itype(o) ((o)->it) | ||
602 | #define tvisnil(o) (itype(o) == LJ_TNIL) | ||
603 | #define tvisfalse(o) (itype(o) == LJ_TFALSE) | ||
604 | #define tvistrue(o) (itype(o) == LJ_TTRUE) | ||
605 | #define tvisbool(o) (tvisfalse(o) || tvistrue(o)) | ||
606 | #if LJ_64 | ||
607 | #define tvislightud(o) (((int32_t)itype(o) >> 15) == -2) | ||
608 | #else | ||
609 | #define tvislightud(o) (itype(o) == LJ_TLIGHTUD) | ||
610 | #endif | ||
611 | #define tvisstr(o) (itype(o) == LJ_TSTR) | ||
612 | #define tvisfunc(o) (itype(o) == LJ_TFUNC) | ||
613 | #define tvisthread(o) (itype(o) == LJ_TTHREAD) | ||
614 | #define tvisproto(o) (itype(o) == LJ_TPROTO) | ||
615 | #define tvistab(o) (itype(o) == LJ_TTAB) | ||
616 | #define tvisudata(o) (itype(o) == LJ_TUDATA) | ||
617 | #define tvisnum(o) (itype(o) <= LJ_TISNUM) | ||
618 | |||
619 | #define tvistruecond(o) (itype(o) < LJ_TISTRUECOND) | ||
620 | #define tvispri(o) (itype(o) >= LJ_TISPRI) | ||
621 | #define tvistabud(o) (itype(o) <= LJ_TISTABUD) /* && !tvisnum() */ | ||
622 | #define tvisgcv(o) ((itype(o) - LJ_TISGCV) > (LJ_TNUMX - LJ_TISGCV)) | ||
623 | |||
624 | /* Special macros to test numbers for NaN, +0, -0, +1 and raw equality. */ | ||
625 | #define tvisnan(o) ((o)->n != (o)->n) | ||
626 | #define tvispzero(o) ((o)->u64 == 0) | ||
627 | #define tvismzero(o) ((o)->u64 == U64x(80000000,00000000)) | ||
628 | #define tvispone(o) ((o)->u64 == U64x(3ff00000,00000000)) | ||
629 | #define rawnumequal(o1, o2) ((o1)->u64 == (o2)->u64) | ||
630 | |||
631 | /* Macros to convert type ids. */ | ||
632 | #if LJ_64 | ||
633 | #define itypemap(o) \ | ||
634 | (tvisnum(o) ? ~LJ_TNUMX : tvislightud(o) ? ~LJ_TLIGHTUD : ~itype(o)) | ||
635 | #else | ||
636 | #define itypemap(o) (tvisnum(o) ? ~LJ_TNUMX : ~itype(o)) | ||
637 | #endif | ||
638 | |||
639 | /* Macros to get tagged values. */ | ||
640 | #define gcval(o) (gcref((o)->gcr)) | ||
641 | #define boolV(o) check_exp(tvisbool(o), (LJ_TFALSE - (o)->it)) | ||
642 | #if LJ_64 | ||
643 | #define lightudV(o) \ | ||
644 | check_exp(tvislightud(o), (void *)((o)->u64 & U64x(00007fff,ffffffff))) | ||
645 | #else | ||
646 | #define lightudV(o) check_exp(tvislightud(o), gcrefp((o)->gcr, void)) | ||
647 | #endif | ||
648 | #define gcV(o) check_exp(tvisgcv(o), gcval(o)) | ||
649 | #define strV(o) check_exp(tvisstr(o), &gcval(o)->str) | ||
650 | #define funcV(o) check_exp(tvisfunc(o), &gcval(o)->fn) | ||
651 | #define threadV(o) check_exp(tvisthread(o), &gcval(o)->th) | ||
652 | #define protoV(o) check_exp(tvisproto(o), &gcval(o)->pt) | ||
653 | #define tabV(o) check_exp(tvistab(o), &gcval(o)->tab) | ||
654 | #define udataV(o) check_exp(tvisudata(o), &gcval(o)->ud) | ||
655 | #define numV(o) check_exp(tvisnum(o), (o)->n) | ||
656 | |||
657 | /* Macros to set tagged values. */ | ||
658 | #define setitype(o, i) ((o)->it = (i)) | ||
659 | #define setnilV(o) ((o)->it = LJ_TNIL) | ||
660 | #define setboolV(o, x) ((o)->it = LJ_TFALSE-(uint32_t)(x)) | ||
661 | |||
662 | static LJ_AINLINE void setlightudV(TValue *o, void *p) | ||
663 | { | ||
664 | #if LJ_64 | ||
665 | o->u64 = (uint64_t)p | (((uint64_t)0xffff) << 48); | ||
666 | #else | ||
667 | setgcrefp(o->gcr, p); setitype(o, LJ_TLIGHTUD); | ||
668 | #endif | ||
669 | } | ||
670 | |||
671 | #if LJ_64 | ||
672 | #define checklightudptr(L, p) \ | ||
673 | (((uint64_t)(p) >> 47) ? (lj_err_msg(L, LJ_ERR_BADLU), NULL) : (p)) | ||
674 | #define setcont(o, f) \ | ||
675 | ((o)->u64 = (uint64_t)(void *)(f) - (uint64_t)lj_vm_asm_begin) | ||
676 | #else | ||
677 | #define checklightudptr(L, p) (p) | ||
678 | #define setcont(o, f) setlightudV((o), (void *)(f)) | ||
679 | #endif | ||
680 | |||
681 | #define tvchecklive(L, o) \ | ||
682 | UNUSED(L), lua_assert(!tvisgcv(o) || \ | ||
683 | ((~itype(o) == gcval(o)->gch.gct) && !isdead(G(L), gcval(o)))) | ||
684 | |||
685 | static LJ_AINLINE void setgcV(lua_State *L, TValue *o, GCobj *v, uint32_t itype) | ||
686 | { | ||
687 | setgcref(o->gcr, v); setitype(o, itype); tvchecklive(L, o); | ||
688 | } | ||
689 | |||
690 | #define define_setV(name, type, tag) \ | ||
691 | static LJ_AINLINE void name(lua_State *L, TValue *o, type *v) \ | ||
692 | { \ | ||
693 | setgcV(L, o, obj2gco(v), tag); \ | ||
694 | } | ||
695 | define_setV(setstrV, GCstr, LJ_TSTR) | ||
696 | define_setV(setthreadV, lua_State, LJ_TTHREAD) | ||
697 | define_setV(setprotoV, GCproto, LJ_TPROTO) | ||
698 | define_setV(setfuncV, GCfunc, LJ_TFUNC) | ||
699 | define_setV(settabV, GCtab, LJ_TTAB) | ||
700 | define_setV(setudataV, GCudata, LJ_TUDATA) | ||
701 | |||
702 | #define setnumV(o, x) ((o)->n = (x)) | ||
703 | #define setnanV(o) ((o)->u64 = U64x(fff80000,00000000)) | ||
704 | #define setintV(o, i) ((o)->n = cast_num((int32_t)(i))) | ||
705 | |||
706 | /* Copy tagged values. */ | ||
707 | static LJ_AINLINE void copyTV(lua_State *L, TValue *o1, const TValue *o2) | ||
708 | { | ||
709 | *o1 = *o2; tvchecklive(L, o1); | ||
710 | } | ||
698 | 711 | ||
699 | /* -- Number to integer conversion ---------------------------------------- */ | 712 | /* -- Number to integer conversion ---------------------------------------- */ |
700 | 713 | ||
@@ -722,8 +735,4 @@ LJ_DATA const char *const lj_obj_itypename[~LJ_TNUMX+1]; | |||
722 | /* Compare two objects without calling metamethods. */ | 735 | /* Compare two objects without calling metamethods. */ |
723 | LJ_FUNC int lj_obj_equal(cTValue *o1, cTValue *o2); | 736 | LJ_FUNC int lj_obj_equal(cTValue *o1, cTValue *o2); |
724 | 737 | ||
725 | #ifdef LUA_USE_ASSERT | ||
726 | #include "lj_gc.h" | ||
727 | #endif | ||
728 | |||
729 | #endif | 738 | #endif |