diff options
| -rw-r--r-- | src/lj_api.c | 30 | ||||
| -rw-r--r-- | src/lj_udata.c | 27 | ||||
| -rw-r--r-- | src/lj_udata.h | 3 |
3 files changed, 32 insertions, 28 deletions
diff --git a/src/lj_api.c b/src/lj_api.c index 8b00436d..18a7ecbc 100644 --- a/src/lj_api.c +++ b/src/lj_api.c | |||
| @@ -707,36 +707,10 @@ LUA_API void lua_pushboolean(lua_State *L, int b) | |||
| 707 | incr_top(L); | 707 | incr_top(L); |
| 708 | } | 708 | } |
| 709 | 709 | ||
| 710 | #if LJ_64 | ||
| 711 | static void *lightud_intern(lua_State *L, void *p) | ||
| 712 | { | ||
| 713 | global_State *g = G(L); | ||
| 714 | uint64_t u = (uint64_t)p; | ||
| 715 | uint32_t up = lightudup(u); | ||
| 716 | uint32_t *segmap = mref(g->gc.lightudseg, uint32_t); | ||
| 717 | MSize segnum = g->gc.lightudnum; | ||
| 718 | if (segmap) { | ||
| 719 | MSize seg; | ||
| 720 | for (seg = 0; seg <= segnum; seg++) | ||
| 721 | if (segmap[seg] == up) /* Fast path. */ | ||
| 722 | return (void *)(((uint64_t)seg << LJ_LIGHTUD_BITS_LO) | lightudlo(u)); | ||
| 723 | segnum++; | ||
| 724 | } | ||
| 725 | if (!((segnum-1) & segnum) && segnum != 1) { | ||
| 726 | if (segnum >= (1 << LJ_LIGHTUD_BITS_SEG)) lj_err_msg(L, LJ_ERR_BADLU); | ||
| 727 | lj_mem_reallocvec(L, segmap, segnum, segnum ? 2*segnum : 2u, uint32_t); | ||
| 728 | setmref(g->gc.lightudseg, segmap); | ||
| 729 | } | ||
| 730 | g->gc.lightudnum = segnum; | ||
| 731 | segmap[segnum] = up; | ||
| 732 | return (void *)(((uint64_t)segnum << LJ_LIGHTUD_BITS_LO) | lightudlo(u)); | ||
| 733 | } | ||
| 734 | #endif | ||
| 735 | |||
| 736 | LUA_API void lua_pushlightuserdata(lua_State *L, void *p) | 710 | LUA_API void lua_pushlightuserdata(lua_State *L, void *p) |
| 737 | { | 711 | { |
| 738 | #if LJ_64 | 712 | #if LJ_64 |
| 739 | p = lightud_intern(L, p); | 713 | p = lj_lightud_intern(L, p); |
| 740 | #endif | 714 | #endif |
| 741 | setrawlightudV(L->top, p); | 715 | setrawlightudV(L->top, p); |
| 742 | incr_top(L); | 716 | incr_top(L); |
| @@ -1179,7 +1153,7 @@ static TValue *cpcall(lua_State *L, lua_CFunction func, void *ud) | |||
| 1179 | setfuncV(L, top++, fn); | 1153 | setfuncV(L, top++, fn); |
| 1180 | if (LJ_FR2) setnilV(top++); | 1154 | if (LJ_FR2) setnilV(top++); |
| 1181 | #if LJ_64 | 1155 | #if LJ_64 |
| 1182 | ud = lightud_intern(L, ud); | 1156 | ud = lj_lightud_intern(L, ud); |
| 1183 | #endif | 1157 | #endif |
| 1184 | setrawlightudV(top++, ud); | 1158 | setrawlightudV(top++, ud); |
| 1185 | cframe_nres(L->cframe) = 1+0; /* Zero results. */ | 1159 | cframe_nres(L->cframe) = 1+0; /* Zero results. */ |
diff --git a/src/lj_udata.c b/src/lj_udata.c index ec3478c8..b2ea8031 100644 --- a/src/lj_udata.c +++ b/src/lj_udata.c | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | 8 | ||
| 9 | #include "lj_obj.h" | 9 | #include "lj_obj.h" |
| 10 | #include "lj_gc.h" | 10 | #include "lj_gc.h" |
| 11 | #include "lj_err.h" | ||
| 11 | #include "lj_udata.h" | 12 | #include "lj_udata.h" |
| 12 | 13 | ||
| 13 | GCudata *lj_udata_new(lua_State *L, MSize sz, GCtab *env) | 14 | GCudata *lj_udata_new(lua_State *L, MSize sz, GCtab *env) |
| @@ -32,3 +33,29 @@ void LJ_FASTCALL lj_udata_free(global_State *g, GCudata *ud) | |||
| 32 | lj_mem_free(g, ud, sizeudata(ud)); | 33 | lj_mem_free(g, ud, sizeudata(ud)); |
| 33 | } | 34 | } |
| 34 | 35 | ||
| 36 | #if LJ_64 | ||
| 37 | void *lj_lightud_intern(lua_State *L, void *p) | ||
| 38 | { | ||
| 39 | global_State *g = G(L); | ||
| 40 | uint64_t u = (uint64_t)p; | ||
| 41 | uint32_t up = lightudup(u); | ||
| 42 | uint32_t *segmap = mref(g->gc.lightudseg, uint32_t); | ||
| 43 | MSize segnum = g->gc.lightudnum; | ||
| 44 | if (segmap) { | ||
| 45 | MSize seg; | ||
| 46 | for (seg = 0; seg <= segnum; seg++) | ||
| 47 | if (segmap[seg] == up) /* Fast path. */ | ||
| 48 | return (void *)(((uint64_t)seg << LJ_LIGHTUD_BITS_LO) | lightudlo(u)); | ||
| 49 | segnum++; | ||
| 50 | } | ||
| 51 | if (!((segnum-1) & segnum) && segnum != 1) { | ||
| 52 | if (segnum >= (1 << LJ_LIGHTUD_BITS_SEG)) lj_err_msg(L, LJ_ERR_BADLU); | ||
| 53 | lj_mem_reallocvec(L, segmap, segnum, segnum ? 2*segnum : 2u, uint32_t); | ||
| 54 | setmref(g->gc.lightudseg, segmap); | ||
| 55 | } | ||
| 56 | g->gc.lightudnum = segnum; | ||
| 57 | segmap[segnum] = up; | ||
| 58 | return (void *)(((uint64_t)segnum << LJ_LIGHTUD_BITS_LO) | lightudlo(u)); | ||
| 59 | } | ||
| 60 | #endif | ||
| 61 | |||
diff --git a/src/lj_udata.h b/src/lj_udata.h index 1873b694..78522ecc 100644 --- a/src/lj_udata.h +++ b/src/lj_udata.h | |||
| @@ -10,5 +10,8 @@ | |||
| 10 | 10 | ||
| 11 | LJ_FUNC GCudata *lj_udata_new(lua_State *L, MSize sz, GCtab *env); | 11 | LJ_FUNC GCudata *lj_udata_new(lua_State *L, MSize sz, GCtab *env); |
| 12 | LJ_FUNC void LJ_FASTCALL lj_udata_free(global_State *g, GCudata *ud); | 12 | LJ_FUNC void LJ_FASTCALL lj_udata_free(global_State *g, GCudata *ud); |
| 13 | #if LJ_64 | ||
| 14 | LJ_FUNC void * LJ_FASTCALL lj_lightud_intern(lua_State *L, void *p); | ||
| 15 | #endif | ||
| 13 | 16 | ||
| 14 | #endif | 17 | #endif |
