diff options
Diffstat (limited to 'src/lj_cdata.c')
-rw-r--r-- | src/lj_cdata.c | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/src/lj_cdata.c b/src/lj_cdata.c index 49b1aa50..68e16d76 100644 --- a/src/lj_cdata.c +++ b/src/lj_cdata.c | |||
@@ -9,7 +9,6 @@ | |||
9 | 9 | ||
10 | #include "lj_gc.h" | 10 | #include "lj_gc.h" |
11 | #include "lj_err.h" | 11 | #include "lj_err.h" |
12 | #include "lj_str.h" | ||
13 | #include "lj_tab.h" | 12 | #include "lj_tab.h" |
14 | #include "lj_ctype.h" | 13 | #include "lj_ctype.h" |
15 | #include "lj_cconv.h" | 14 | #include "lj_cconv.h" |
@@ -27,12 +26,12 @@ GCcdata *lj_cdata_newref(CTState *cts, const void *p, CTypeID id) | |||
27 | } | 26 | } |
28 | 27 | ||
29 | /* Allocate variable-sized or specially aligned C data object. */ | 28 | /* Allocate variable-sized or specially aligned C data object. */ |
30 | GCcdata *lj_cdata_newv(CTState *cts, CTypeID id, CTSize sz, CTSize align) | 29 | GCcdata *lj_cdata_newv(lua_State *L, CTypeID id, CTSize sz, CTSize align) |
31 | { | 30 | { |
32 | global_State *g; | 31 | global_State *g; |
33 | MSize extra = sizeof(GCcdataVar) + sizeof(GCcdata) + | 32 | MSize extra = sizeof(GCcdataVar) + sizeof(GCcdata) + |
34 | (align > CT_MEMALIGN ? (1u<<align) - (1u<<CT_MEMALIGN) : 0); | 33 | (align > CT_MEMALIGN ? (1u<<align) - (1u<<CT_MEMALIGN) : 0); |
35 | char *p = lj_mem_newt(cts->L, extra + sz, char); | 34 | char *p = lj_mem_newt(L, extra + sz, char); |
36 | uintptr_t adata = (uintptr_t)p + sizeof(GCcdataVar) + sizeof(GCcdata); | 35 | uintptr_t adata = (uintptr_t)p + sizeof(GCcdataVar) + sizeof(GCcdata); |
37 | uintptr_t almask = (1u << align) - 1u; | 36 | uintptr_t almask = (1u << align) - 1u; |
38 | GCcdata *cd = (GCcdata *)(((adata + almask) & ~almask) - sizeof(GCcdata)); | 37 | GCcdata *cd = (GCcdata *)(((adata + almask) & ~almask) - sizeof(GCcdata)); |
@@ -40,7 +39,7 @@ GCcdata *lj_cdata_newv(CTState *cts, CTypeID id, CTSize sz, CTSize align) | |||
40 | cdatav(cd)->offset = (uint16_t)((char *)cd - p); | 39 | cdatav(cd)->offset = (uint16_t)((char *)cd - p); |
41 | cdatav(cd)->extra = extra; | 40 | cdatav(cd)->extra = extra; |
42 | cdatav(cd)->len = sz; | 41 | cdatav(cd)->len = sz; |
43 | g = cts->g; | 42 | g = G(L); |
44 | setgcrefr(cd->nextgc, g->gc.root); | 43 | setgcrefr(cd->nextgc, g->gc.root); |
45 | setgcref(g->gc.root, obj2gco(cd)); | 44 | setgcref(g->gc.root, obj2gco(cd)); |
46 | newwhite(g, obj2gco(cd)); | 45 | newwhite(g, obj2gco(cd)); |
@@ -50,6 +49,15 @@ GCcdata *lj_cdata_newv(CTState *cts, CTypeID id, CTSize sz, CTSize align) | |||
50 | return cd; | 49 | return cd; |
51 | } | 50 | } |
52 | 51 | ||
52 | /* Allocate arbitrary C data object. */ | ||
53 | GCcdata *lj_cdata_newx(CTState *cts, CTypeID id, CTSize sz, CTInfo info) | ||
54 | { | ||
55 | if (!(info & CTF_VLA) && ctype_align(info) <= CT_MEMALIGN) | ||
56 | return lj_cdata_new(cts, id, sz); | ||
57 | else | ||
58 | return lj_cdata_newv(cts->L, id, sz, ctype_align(info)); | ||
59 | } | ||
60 | |||
53 | /* Free a C data object. */ | 61 | /* Free a C data object. */ |
54 | void LJ_FASTCALL lj_cdata_free(global_State *g, GCcdata *cd) | 62 | void LJ_FASTCALL lj_cdata_free(global_State *g, GCcdata *cd) |
55 | { | 63 | { |
@@ -76,21 +84,22 @@ void LJ_FASTCALL lj_cdata_free(global_State *g, GCcdata *cd) | |||
76 | } | 84 | } |
77 | } | 85 | } |
78 | 86 | ||
79 | TValue * LJ_FASTCALL lj_cdata_setfin(lua_State *L, GCcdata *cd) | 87 | void lj_cdata_setfin(lua_State *L, GCcdata *cd, GCobj *obj, uint32_t it) |
80 | { | 88 | { |
81 | global_State *g = G(L); | 89 | GCtab *t = ctype_ctsG(G(L))->finalizer; |
82 | GCtab *t = ctype_ctsG(g)->finalizer; | ||
83 | if (gcref(t->metatable)) { | 90 | if (gcref(t->metatable)) { |
84 | /* Add cdata to finalizer table, if still enabled. */ | 91 | /* Add cdata to finalizer table, if still enabled. */ |
85 | TValue *tv, tmp; | 92 | TValue *tv, tmp; |
86 | setcdataV(L, &tmp, cd); | 93 | setcdataV(L, &tmp, cd); |
87 | lj_gc_anybarriert(L, t); | 94 | lj_gc_anybarriert(L, t); |
88 | tv = lj_tab_set(L, t, &tmp); | 95 | tv = lj_tab_set(L, t, &tmp); |
89 | cd->marked |= LJ_GC_CDATA_FIN; | 96 | if (it == LJ_TNIL) { |
90 | return tv; | 97 | setnilV(tv); |
91 | } else { | 98 | cd->marked &= ~LJ_GC_CDATA_FIN; |
92 | /* Otherwise return dummy TValue. */ | 99 | } else { |
93 | return &g->tmptv; | 100 | setgcV(L, tv, obj, it); |
101 | cd->marked |= LJ_GC_CDATA_FIN; | ||
102 | } | ||
94 | } | 103 | } |
95 | } | 104 | } |
96 | 105 | ||
@@ -123,7 +132,12 @@ collect_attrib: | |||
123 | idx = (ptrdiff_t)intV(key); | 132 | idx = (ptrdiff_t)intV(key); |
124 | goto integer_key; | 133 | goto integer_key; |
125 | } else if (tvisnum(key)) { /* Numeric key. */ | 134 | } else if (tvisnum(key)) { /* Numeric key. */ |
126 | idx = LJ_64 ? (ptrdiff_t)numV(key) : (ptrdiff_t)lj_num2int(numV(key)); | 135 | #ifdef _MSC_VER |
136 | /* Workaround for MSVC bug. */ | ||
137 | volatile | ||
138 | #endif | ||
139 | lua_Number n = numV(key); | ||
140 | idx = LJ_64 ? (ptrdiff_t)n : (ptrdiff_t)lj_num2int(n); | ||
127 | integer_key: | 141 | integer_key: |
128 | if (ctype_ispointer(ct->info)) { | 142 | if (ctype_ispointer(ct->info)) { |
129 | CTSize sz = lj_ctype_size(cts, ctype_cid(ct->info)); /* Element size. */ | 143 | CTSize sz = lj_ctype_size(cts, ctype_cid(ct->info)); /* Element size. */ |