diff options
Diffstat (limited to 'src/lj_serialize.c')
-rw-r--r-- | src/lj_serialize.c | 65 |
1 files changed, 62 insertions, 3 deletions
diff --git a/src/lj_serialize.c b/src/lj_serialize.c index d84ebcb8..70ff4796 100644 --- a/src/lj_serialize.c +++ b/src/lj_serialize.c | |||
@@ -18,6 +18,9 @@ | |||
18 | #include "lj_ctype.h" | 18 | #include "lj_ctype.h" |
19 | #include "lj_cdata.h" | 19 | #include "lj_cdata.h" |
20 | #endif | 20 | #endif |
21 | #if LJ_HASJIT | ||
22 | #include "lj_ir.h" | ||
23 | #endif | ||
21 | #include "lj_serialize.h" | 24 | #include "lj_serialize.h" |
22 | 25 | ||
23 | /* Tags for internal serialization format. */ | 26 | /* Tags for internal serialization format. */ |
@@ -400,6 +403,9 @@ eob: | |||
400 | return NULL; | 403 | return NULL; |
401 | } | 404 | } |
402 | 405 | ||
406 | /* -- External serialization API ------------------------------------------ */ | ||
407 | |||
408 | /* Encode to buffer. */ | ||
403 | SBufExt * LJ_FASTCALL lj_serialize_put(SBufExt *sbx, cTValue *o) | 409 | SBufExt * LJ_FASTCALL lj_serialize_put(SBufExt *sbx, cTValue *o) |
404 | { | 410 | { |
405 | sbx->depth = LJ_SERIALIZE_DEPTH; | 411 | sbx->depth = LJ_SERIALIZE_DEPTH; |
@@ -407,10 +413,63 @@ SBufExt * LJ_FASTCALL lj_serialize_put(SBufExt *sbx, cTValue *o) | |||
407 | return sbx; | 413 | return sbx; |
408 | } | 414 | } |
409 | 415 | ||
410 | SBufExt * LJ_FASTCALL lj_serialize_get(SBufExt *sbx, TValue *o) | 416 | /* Decode from buffer. */ |
417 | char * LJ_FASTCALL lj_serialize_get(SBufExt *sbx, TValue *o) | ||
411 | { | 418 | { |
412 | sbx->r = serialize_get(sbx->r, sbx, o); | 419 | return serialize_get(sbx->r, sbx, o); |
413 | return sbx; | 420 | } |
421 | |||
422 | /* Stand-alone encoding, borrowing from global temporary buffer. */ | ||
423 | GCstr * LJ_FASTCALL lj_serialize_encode(lua_State *L, cTValue *o) | ||
424 | { | ||
425 | SBufExt sbx; | ||
426 | char *w; | ||
427 | memset(&sbx, 0, sizeof(SBufExt)); | ||
428 | lj_bufx_set_borrow(L, &sbx, &G(L)->tmpbuf); | ||
429 | sbx.depth = LJ_SERIALIZE_DEPTH; | ||
430 | w = serialize_put(sbx.w, &sbx, o); | ||
431 | return lj_str_new(L, sbx.b, (size_t)(w - sbx.b)); | ||
432 | } | ||
433 | |||
434 | /* Stand-alone decoding, copy-on-write from string. */ | ||
435 | void lj_serialize_decode(lua_State *L, TValue *o, GCstr *str) | ||
436 | { | ||
437 | SBufExt sbx; | ||
438 | char *r; | ||
439 | memset(&sbx, 0, sizeof(SBufExt)); | ||
440 | lj_bufx_set_cow(L, &sbx, strdata(str), str->len); | ||
441 | /* No need to set sbx.cowref here. */ | ||
442 | r = lj_serialize_get(&sbx, o); | ||
443 | if (r != sbx.w) lj_err_caller(L, LJ_ERR_BUFFER_LEFTOV); | ||
444 | } | ||
445 | |||
446 | #if LJ_HASJIT | ||
447 | /* Peek into buffer to find the result IRType for specialization purposes. */ | ||
448 | LJ_FUNC MSize LJ_FASTCALL lj_serialize_peektype(SBufExt *sbx) | ||
449 | { | ||
450 | uint32_t tp; | ||
451 | if (serialize_ru124(sbx->r, sbx->w, &tp)) { | ||
452 | /* This must match the handling of all tags in the decoder above. */ | ||
453 | switch (tp) { | ||
454 | case SER_TAG_NIL: return IRT_NIL; | ||
455 | case SER_TAG_FALSE: return IRT_FALSE; | ||
456 | case SER_TAG_TRUE: return IRT_TRUE; | ||
457 | case SER_TAG_NULL: case SER_TAG_LIGHTUD32: case SER_TAG_LIGHTUD64: | ||
458 | return IRT_LIGHTUD; | ||
459 | case SER_TAG_INT: return LJ_DUALNUM ? IRT_INT : IRT_NUM; | ||
460 | case SER_TAG_NUM: return IRT_NUM; | ||
461 | case SER_TAG_TAB: case SER_TAG_TAB+1: case SER_TAG_TAB+2: | ||
462 | case SER_TAG_TAB+3: case SER_TAG_TAB+4: case SER_TAG_TAB+5: | ||
463 | return IRT_TAB; | ||
464 | case SER_TAG_INT64: case SER_TAG_UINT64: case SER_TAG_COMPLEX: | ||
465 | return IRT_CDATA; | ||
466 | case SER_TAG_DICT: | ||
467 | default: | ||
468 | return IRT_STR; | ||
469 | } | ||
470 | } | ||
471 | return IRT_NIL; /* Will fail on actual decode. */ | ||
414 | } | 472 | } |
473 | #endif | ||
415 | 474 | ||
416 | #endif | 475 | #endif |