diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-02-26 10:35:03 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-02-26 10:35:03 -0300 |
commit | 2952bc5fc9cdc05ed061539cb7be26899513f004 (patch) | |
tree | ac3b1438843797e816ed04fac102c0820ea174ea /lobject.h | |
parent | 38d3bc89093010fa9c460b61a1965d9077b5378f (diff) | |
download | lua-2952bc5fc9cdc05ed061539cb7be26899513f004.tar.gz lua-2952bc5fc9cdc05ed061539cb7be26899513f004.tar.bz2 lua-2952bc5fc9cdc05ed061539cb7be26899513f004.zip |
special compact representation for userdata with no user values
(a common case)
Diffstat (limited to 'lobject.h')
-rw-r--r-- | lobject.h | 37 |
1 files changed, 28 insertions, 9 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lobject.h,v 2.138 2018/02/25 12:48:16 roberto Exp roberto $ | 2 | ** $Id: lobject.h,v 2.139 2018/02/25 12:52:32 roberto Exp roberto $ |
3 | ** Type definitions for Lua objects | 3 | ** Type definitions for Lua objects |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -70,7 +70,7 @@ typedef struct TValue { | |||
70 | #define rttype(o) ((o)->tt_) | 70 | #define rttype(o) ((o)->tt_) |
71 | 71 | ||
72 | /* tag with no variants (bits 0-3) */ | 72 | /* tag with no variants (bits 0-3) */ |
73 | #define novariant(x) ((x) & 0x0F) | 73 | #define novariant(t) ((t) & 0x0F) |
74 | 74 | ||
75 | /* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */ | 75 | /* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */ |
76 | #define ttyperaw(t) ((t) & 0x3F) | 76 | #define ttyperaw(t) ((t) & 0x3F) |
@@ -379,7 +379,7 @@ typedef union UTString { | |||
379 | */ | 379 | */ |
380 | 380 | ||
381 | #define ttislightuserdata(o) checktag((o), LUA_TLIGHTUSERDATA) | 381 | #define ttislightuserdata(o) checktag((o), LUA_TLIGHTUSERDATA) |
382 | #define ttisfulluserdata(o) checktag((o), ctb(LUA_TUSERDATA)) | 382 | #define ttisfulluserdata(o) checktype((o), LUA_TUSERDATA) |
383 | 383 | ||
384 | #define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p) | 384 | #define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p) |
385 | #define uvalue(o) check_exp(ttisfulluserdata(o), gco2u(val_(o).gc)) | 385 | #define uvalue(o) check_exp(ttisfulluserdata(o), gco2u(val_(o).gc)) |
@@ -403,7 +403,8 @@ typedef union UValue { | |||
403 | 403 | ||
404 | 404 | ||
405 | /* | 405 | /* |
406 | ** Header for userdata; memory area follows the end of this structure. | 406 | ** Header for userdata with user values; |
407 | ** memory area follows the end of this structure. | ||
407 | */ | 408 | */ |
408 | typedef struct Udata { | 409 | typedef struct Udata { |
409 | CommonHeader; | 410 | CommonHeader; |
@@ -415,15 +416,33 @@ typedef struct Udata { | |||
415 | } Udata; | 416 | } Udata; |
416 | 417 | ||
417 | 418 | ||
418 | /* computes the offset of the memory area of a userdata */ | ||
419 | #define udatamemoffset(nuv) (sizeof(Udata) + (sizeof(UValue) * ((nuv) - 1))) | ||
420 | |||
421 | /* | 419 | /* |
422 | ** Get the address of the memory block inside 'Udata'. | 420 | ** Header for userdata with no user values. These userdata do not need |
421 | ** to be gray during GC, and therefore do not need a 'gclist' field. | ||
422 | ** To simplify, the code always use 'Udata' for both kinds of userdata, | ||
423 | ** making sure it never accesses 'gclist' on userdata with no user values. | ||
424 | ** This structure here is used only to compute the correct size for | ||
425 | ** this representation. (The 'bindata' field in its end ensures correct | ||
426 | ** alignment for binary data following this header.) | ||
423 | */ | 427 | */ |
428 | typedef struct Udata0 { | ||
429 | CommonHeader; | ||
430 | unsigned short nuvalue; /* number of user values */ | ||
431 | size_t len; /* number of bytes */ | ||
432 | struct Table *metatable; | ||
433 | union {LUAI_MAXALIGN;} bindata; | ||
434 | } Udata0; | ||
435 | |||
436 | |||
437 | /* compute the offset of the memory area of a userdata */ | ||
438 | #define udatamemoffset(nuv) \ | ||
439 | ((nuv) == 0 ? offsetof(Udata0, bindata) \ | ||
440 | : offsetof(Udata, uv) + (sizeof(UValue) * (nuv))) | ||
441 | |||
442 | /* get the address of the memory block inside 'Udata' */ | ||
424 | #define getudatamem(u) (cast_charp(u) + udatamemoffset((u)->nuvalue)) | 443 | #define getudatamem(u) (cast_charp(u) + udatamemoffset((u)->nuvalue)) |
425 | 444 | ||
426 | /* computes the size of a userdata */ | 445 | /* compute the size of a userdata */ |
427 | #define sizeudata(nuv,nb) (udatamemoffset(nuv) + (nb)) | 446 | #define sizeudata(nuv,nb) (udatamemoffset(nuv) + (nb)) |
428 | 447 | ||
429 | /* }================================================================== */ | 448 | /* }================================================================== */ |