aboutsummaryrefslogtreecommitdiff
path: root/src/lj_serialize.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lj_serialize.c77
1 files changed, 70 insertions, 7 deletions
diff --git a/src/lj_serialize.c b/src/lj_serialize.c
index 49a25a7c..d84ebcb8 100644
--- a/src/lj_serialize.c
+++ b/src/lj_serialize.c
@@ -32,7 +32,7 @@ enum {
32 SER_TAG_NUM, 32 SER_TAG_NUM,
33 SER_TAG_TAB, /* 0x08 */ 33 SER_TAG_TAB, /* 0x08 */
34 SER_TAG_0x0e = SER_TAG_TAB+6, 34 SER_TAG_0x0e = SER_TAG_TAB+6,
35 SER_TAG_0x0f, 35 SER_TAG_DICT,
36 SER_TAG_INT64, /* 0x10 */ 36 SER_TAG_INT64, /* 0x10 */
37 SER_TAG_UINT64, 37 SER_TAG_UINT64,
38 SER_TAG_COMPLEX, 38 SER_TAG_COMPLEX,
@@ -120,6 +120,26 @@ static LJ_AINLINE char *serialize_ru124(char *r, char *w, uint32_t *pv)
120 return NULL; 120 return NULL;
121} 121}
122 122
123/* Prepare string dictionary for use (once). */
124void LJ_FASTCALL lj_serialize_dict_prep(lua_State *L, GCtab *dict)
125{
126 if (!dict->hmask) { /* No hash part means not prepared, yet. */
127 MSize i, len = lj_tab_len(dict);
128 if (!len) return;
129 lj_tab_resize(L, dict, dict->asize, hsize2hbits(len));
130 for (i = 1; i <= len && i < dict->asize; i++) {
131 cTValue *o = arrayslot(dict, i);
132 if (tvisstr(o)) {
133 if (!lj_tab_getstr(dict, strV(o))) { /* Ignore dups. */
134 lj_tab_newkey(L, dict, o)->u64 = (uint64_t)(i-1);
135 }
136 } else if (!tvisfalse(o)) {
137 lj_err_caller(L, LJ_ERR_BUFFER_BADOPT);
138 }
139 }
140 }
141}
142
123/* -- Internal serializer ------------------------------------------------- */ 143/* -- Internal serializer ------------------------------------------------- */
124 144
125/* Put serialized object into buffer. */ 145/* Put serialized object into buffer. */
@@ -174,12 +194,45 @@ static char *serialize_put(char *w, SBufExt *sbx, cTValue *o)
174 } 194 }
175 if (nhash) { /* Write hash entries. */ 195 if (nhash) { /* Write hash entries. */
176 const Node *node = noderef(t->node) + t->hmask; 196 const Node *node = noderef(t->node) + t->hmask;
177 for (;; node--) 197 GCtab *dict = tabref(sbx->dict);
178 if (!tvisnil(&node->val)) { 198 if (LJ_UNLIKELY(dict)) {
179 w = serialize_put(w, sbx, &node->key); 199 for (;; node--)
180 w = serialize_put(w, sbx, &node->val); 200 if (!tvisnil(&node->val)) {
181 if (--nhash == 0) break; 201 if (LJ_LIKELY(tvisstr(&node->key))) {
182 } 202 /* Inlined lj_tab_getstr is 30% faster. */
203 const GCstr *str = strV(&node->key);
204 Node *n = hashstr(dict, str);
205 do {
206 if (tvisstr(&n->key) && strV(&n->key) == str) {
207 uint32_t idx = n->val.u32.lo;
208 w = serialize_more(w, sbx, 1+5);
209 *w++ = SER_TAG_DICT;
210 w = serialize_wu124(w, idx);
211 break;
212 }
213 n = nextnode(n);
214 if (!n) {
215 MSize len = str->len;
216 w = serialize_more(w, sbx, 5+len);
217 w = serialize_wu124(w, SER_TAG_STR + len);
218 w = lj_buf_wmem(w, strdata(str), len);
219 break;
220 }
221 } while (1);
222 } else {
223 w = serialize_put(w, sbx, &node->key);
224 }
225 w = serialize_put(w, sbx, &node->val);
226 if (--nhash == 0) break;
227 }
228 } else {
229 for (;; node--)
230 if (!tvisnil(&node->val)) {
231 w = serialize_put(w, sbx, &node->key);
232 w = serialize_put(w, sbx, &node->val);
233 if (--nhash == 0) break;
234 }
235 }
183 } 236 }
184 sbx->depth++; 237 sbx->depth++;
185#if LJ_HASFFI 238#if LJ_HASFFI
@@ -266,6 +319,16 @@ static char *serialize_get(char *r, SBufExt *sbx, TValue *o)
266 if (!tvisnum(o)) setnanV(o); 319 if (!tvisnum(o)) setnanV(o);
267 } else if (tp <= SER_TAG_TRUE) { 320 } else if (tp <= SER_TAG_TRUE) {
268 setpriV(o, ~tp); 321 setpriV(o, ~tp);
322 } else if (tp == SER_TAG_DICT) {
323 GCtab *dict;
324 uint32_t idx;
325 r = serialize_ru124(r, w, &idx);
326 idx++;
327 dict = tabref(sbx->dict);
328 if (dict && idx < dict->asize && tvisstr(arrayslot(dict, idx)))
329 copyTV(sbufL(sbx), o, arrayslot(dict, idx));
330 else
331 lj_err_callerv(sbufL(sbx), LJ_ERR_BUFFER_BADDICTX, idx);
269 } else if (tp >= SER_TAG_TAB && tp < SER_TAG_TAB+6) { 332 } else if (tp >= SER_TAG_TAB && tp < SER_TAG_TAB+6) {
270 uint32_t narray = 0, nhash = 0; 333 uint32_t narray = 0, nhash = 0;
271 GCtab *t; 334 GCtab *t;