Github User Fetcher 1.0.0
C Application with Server and GUI
Loading...
Searching...
No Matches
duk_bi_json.c File Reference
#include "duk_internal.h"

Go to the source code of this file.

Macros

#define DUK__JSON_DECSTR_BUFSIZE   128
 
#define DUK__JSON_DECSTR_CHUNKSIZE   64
 
#define DUK__JSON_ENCSTR_CHUNKSIZE   64
 
#define DUK__JSON_STRINGIFY_BUFSIZE   128
 
#define DUK__JSON_MAX_ESC_LEN   10 /* '\Udeadbeef' */
 
#define DUK__EMIT_1(js_ctx, ch)   duk__emit_1((js_ctx), (duk_uint_fast8_t) (ch))
 
#define DUK__EMIT_2(js_ctx, ch1, ch2)   duk__emit_2((js_ctx), (duk_uint_fast8_t) (ch1), (duk_uint_fast8_t) (ch2))
 
#define DUK__EMIT_HSTR(js_ctx, h)   duk__emit_hstring((js_ctx), (h))
 
#define DUK__EMIT_CSTR(js_ctx, p)   duk__emit_cstring((js_ctx), (p))
 
#define DUK__EMIT_STRIDX(js_ctx, i)   duk__emit_stridx((js_ctx), (i))
 
#define DUK__UNEMIT_1(js_ctx)   duk__unemit_1((js_ctx))
 
#define DUK__MKESC(nybbles, esc1, esc2)
 

Functions

DUK_LOCAL_DECL void duk__dec_syntax_error (duk_json_dec_ctx *js_ctx)
 
DUK_LOCAL_DECL void duk__dec_eat_white (duk_json_dec_ctx *js_ctx)
 
DUK_LOCAL_DECL duk_uint8_t duk__dec_peek (duk_json_dec_ctx *js_ctx)
 
DUK_LOCAL_DECL duk_uint8_t duk__dec_get (duk_json_dec_ctx *js_ctx)
 
DUK_LOCAL_DECL duk_uint8_t duk__dec_get_nonwhite (duk_json_dec_ctx *js_ctx)
 
DUK_LOCAL_DECL duk_uint_fast32_t duk__dec_decode_hex_escape (duk_json_dec_ctx *js_ctx, duk_small_uint_t n)
 
DUK_LOCAL_DECL void duk__dec_req_stridx (duk_json_dec_ctx *js_ctx, duk_small_uint_t stridx)
 
DUK_LOCAL_DECL void duk__dec_string (duk_json_dec_ctx *js_ctx)
 
DUK_LOCAL_DECL void duk__dec_plain_string (duk_json_dec_ctx *js_ctx)
 
DUK_LOCAL_DECL void duk__dec_pointer (duk_json_dec_ctx *js_ctx)
 
DUK_LOCAL_DECL void duk__dec_buffer (duk_json_dec_ctx *js_ctx)
 
DUK_LOCAL_DECL void duk__dec_number (duk_json_dec_ctx *js_ctx)
 
DUK_LOCAL_DECL void duk__dec_objarr_entry (duk_json_dec_ctx *js_ctx)
 
DUK_LOCAL_DECL void duk__dec_objarr_exit (duk_json_dec_ctx *js_ctx)
 
DUK_LOCAL_DECL void duk__dec_object (duk_json_dec_ctx *js_ctx)
 
DUK_LOCAL_DECL void duk__dec_array (duk_json_dec_ctx *js_ctx)
 
DUK_LOCAL_DECL void duk__dec_value (duk_json_dec_ctx *js_ctx)
 
DUK_LOCAL_DECL void duk__dec_reviver_walk (duk_json_dec_ctx *js_ctx)
 
DUK_LOCAL_DECL void duk__emit_1 (duk_json_enc_ctx *js_ctx, duk_uint_fast8_t ch)
 
DUK_LOCAL_DECL void duk__emit_2 (duk_json_enc_ctx *js_ctx, duk_uint_fast8_t ch1, duk_uint_fast8_t ch2)
 
DUK_LOCAL_DECL void duk__unemit_1 (duk_json_enc_ctx *js_ctx)
 
DUK_LOCAL_DECL void duk__emit_hstring (duk_json_enc_ctx *js_ctx, duk_hstring *h)
 
DUK_LOCAL_DECL void duk__emit_stridx (duk_json_enc_ctx *js_ctx, duk_small_uint_t stridx)
 
DUK_LOCAL_DECL duk_uint8_t * duk__emit_esc_auto_fast (duk_json_enc_ctx *js_ctx, duk_uint_fast32_t cp, duk_uint8_t *q)
 
DUK_LOCAL_DECL void duk__enc_key_autoquote (duk_json_enc_ctx *js_ctx, duk_hstring *k)
 
DUK_LOCAL_DECL void duk__enc_quote_string (duk_json_enc_ctx *js_ctx, duk_hstring *h_str)
 
DUK_LOCAL_DECL void duk__enc_objarr_entry (duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top)
 
DUK_LOCAL_DECL void duk__enc_objarr_exit (duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top)
 
DUK_LOCAL_DECL void duk__enc_object (duk_json_enc_ctx *js_ctx)
 
DUK_LOCAL_DECL void duk__enc_array (duk_json_enc_ctx *js_ctx)
 
DUK_LOCAL_DECL duk_bool_t duk__enc_value (duk_json_enc_ctx *js_ctx, duk_idx_t idx_holder)
 
DUK_LOCAL_DECL duk_bool_t duk__enc_allow_into_proplist (duk_tval *tv)
 
DUK_LOCAL_DECL void duk__enc_double (duk_json_enc_ctx *js_ctx)
 
DUK_LOCAL_DECL void duk__enc_buffer (duk_json_enc_ctx *js_ctx, duk_hbuffer *h)
 
DUK_LOCAL_DECL void duk__enc_pointer (duk_json_enc_ctx *js_ctx, void *ptr)
 
DUK_LOCAL_DECL void duk__enc_bufferobject (duk_json_enc_ctx *js_ctx, duk_hbufferobject *h_bufobj)
 
DUK_LOCAL_DECL void duk__enc_newline_indent (duk_json_enc_ctx *js_ctx, duk_int_t depth)
 
DUK_LOCAL duk_small_int_t duk__dec_string_escape (duk_json_dec_ctx *js_ctx, duk_uint8_t **ext_p)
 
DUK_LOCAL void duk__emit_cstring (duk_json_enc_ctx *js_ctx, const char *str)
 
DUK_LOCAL duk_uint8_t * duk__enc_buffer_data_hex (const duk_uint8_t *src, duk_size_t src_len, duk_uint8_t *dst)
 
DUK_LOCAL void duk__enc_buffer_data (duk_json_enc_ctx *js_ctx, duk_uint8_t *buf_data, duk_size_t buf_len)
 
DUK_INTERNAL void duk_bi_json_parse_helper (duk_context *ctx, duk_idx_t idx_value, duk_idx_t idx_reviver, duk_small_uint_t flags)
 
DUK_INTERNAL void duk_bi_json_stringify_helper (duk_context *ctx, duk_idx_t idx_value, duk_idx_t idx_replacer, duk_idx_t idx_space, duk_small_uint_t flags)
 
DUK_INTERNAL duk_ret_t duk_bi_json_object_parse (duk_context *ctx)
 
DUK_INTERNAL duk_ret_t duk_bi_json_object_stringify (duk_context *ctx)
 

Variables

DUK_LOCAL const duk_uint8_t duk__json_quotestr_lookup [256]
 
DUK_LOCAL const duk_uint8_t duk__json_decstr_lookup [256]
 
DUK_LOCAL const duk_uint8_t duk__json_eatwhite_lookup [256]
 
DUK_LOCAL const duk_uint8_t duk__json_decnumber_lookup [256]
 

Macro Definition Documentation

◆ DUK__EMIT_1

#define DUK__EMIT_1 ( js_ctx,
ch )   duk__emit_1((js_ctx), (duk_uint_fast8_t) (ch))

◆ DUK__EMIT_2

#define DUK__EMIT_2 ( js_ctx,
ch1,
ch2 )   duk__emit_2((js_ctx), (duk_uint_fast8_t) (ch1), (duk_uint_fast8_t) (ch2))

Definition at line 1045 of file duktape-1.5.2/src-separate/duk_bi_json.c.

Referenced by duk__enc_object().

◆ DUK__EMIT_CSTR

#define DUK__EMIT_CSTR ( js_ctx,
p )   duk__emit_cstring((js_ctx), (p))

Definition at line 1048 of file duktape-1.5.2/src-separate/duk_bi_json.c.

Referenced by duk__enc_pointer().

◆ DUK__EMIT_HSTR

#define DUK__EMIT_HSTR ( js_ctx,
h )   duk__emit_hstring((js_ctx), (h))

◆ DUK__EMIT_STRIDX

#define DUK__EMIT_STRIDX ( js_ctx,
i )   duk__emit_stridx((js_ctx), (i))

◆ DUK__JSON_DECSTR_BUFSIZE

#define DUK__JSON_DECSTR_BUFSIZE   128

Definition at line 23 of file duktape-1.5.2/src-separate/duk_bi_json.c.

Referenced by duk__dec_string().

◆ DUK__JSON_DECSTR_CHUNKSIZE

#define DUK__JSON_DECSTR_CHUNKSIZE   64

Definition at line 24 of file duktape-1.5.2/src-separate/duk_bi_json.c.

Referenced by duk__dec_string().

◆ DUK__JSON_ENCSTR_CHUNKSIZE

#define DUK__JSON_ENCSTR_CHUNKSIZE   64

Definition at line 25 of file duktape-1.5.2/src-separate/duk_bi_json.c.

Referenced by duk__enc_quote_string().

◆ DUK__JSON_MAX_ESC_LEN

#define DUK__JSON_MAX_ESC_LEN   10 /* '\Udeadbeef' */

Definition at line 27 of file duktape-1.5.2/src-separate/duk_bi_json.c.

◆ DUK__JSON_STRINGIFY_BUFSIZE

#define DUK__JSON_STRINGIFY_BUFSIZE   128

◆ DUK__MKESC

#define DUK__MKESC ( nybbles,
esc1,
esc2 )
Value:
(((duk_uint_fast32_t) (nybbles)) << 16) | \
(((duk_uint_fast32_t) (esc1)) << 8) | \
((duk_uint_fast32_t) (esc2))
duk_uint32_t duk_uint_fast32_t

Definition at line 1087 of file duktape-1.5.2/src-separate/duk_bi_json.c.

1087#define DUK__MKESC(nybbles,esc1,esc2) \
1088 (((duk_uint_fast32_t) (nybbles)) << 16) | \
1089 (((duk_uint_fast32_t) (esc1)) << 8) | \
1090 ((duk_uint_fast32_t) (esc2))

Referenced by duk__emit_esc_auto_fast().

◆ DUK__UNEMIT_1

#define DUK__UNEMIT_1 ( js_ctx)    duk__unemit_1((js_ctx))

Definition at line 1051 of file duktape-1.5.2/src-separate/duk_bi_json.c.

Referenced by duk__enc_array(), and duk__enc_object().

Function Documentation

◆ duk__dec_array()

DUK_LOCAL_DECL void duk__dec_array ( duk_json_dec_ctx * js_ctx)

Definition at line 811 of file duktape-1.5.2/src-separate/duk_bi_json.c.

811 {
812 duk_context *ctx = (duk_context *) js_ctx->thr;
813 duk_uarridx_t arr_idx;
814 duk_uint8_t x;
815
816 DUK_DDD(DUK_DDDPRINT("parse_array"));
817
818 duk__dec_objarr_entry(js_ctx);
819
820 duk_push_array(ctx);
821
822 /* Initial '[' has been checked and eaten by caller. */
823
824 arr_idx = 0;
825 for (;;) {
826 x = duk__dec_get_nonwhite(js_ctx);
827
828 DUK_DDD(DUK_DDDPRINT("parse_array: arr=%!T, x=%ld, arr_idx=%ld",
829 (duk_tval *) duk_get_tval(ctx, -1),
830 (long) x, (long) arr_idx));
831
832 /* handle comma and closing bracket */
833
834 if ((x == DUK_ASC_COMMA) && (arr_idx != 0)) {
835 /* accept comma, expect new value */
836 ;
837 } else if (x == DUK_ASC_RBRACKET) {
838 /* eat closing bracket */
839 break;
840 } else if (arr_idx == 0) {
841 /* accept anything, expect first value (EOF will be
842 * caught by duk__dec_value() below.
843 */
844 js_ctx->p--; /* backtrack (safe) */
845 } else {
846 /* catches EOF (NUL) and initial comma */
847 goto syntax_error;
848 }
849
850 /* parse value */
851
852 duk__dec_value(js_ctx);
853
854 /* [ ... arr val ] */
855
856 duk_xdef_prop_index_wec(ctx, -2, arr_idx);
857 arr_idx++;
858 }
859
860 /* Must set 'length' explicitly when using duk_xdef_prop_xxx() to
861 * set the values.
862 */
863
864 duk_set_length(ctx, -1, arr_idx);
865
866 /* [ ... arr ] */
867
868 DUK_DDD(DUK_DDDPRINT("parse_array: final array is %!T",
869 (duk_tval *) duk_get_tval(ctx, -1)));
870
871 duk__dec_objarr_exit(js_ctx);
872 return;
873
874 syntax_error:
875 duk__dec_syntax_error(js_ctx);
877}
#define duk_xdef_prop_index_wec(ctx, obj_index, arr_index)
DUK_INTERNAL_DECL void duk_set_length(duk_context *ctx, duk_idx_t index, duk_size_t length)
DUK_EXTERNAL duk_idx_t duk_push_array(duk_context *ctx)
DUK_INTERNAL_DECL duk_tval * duk_get_tval(duk_context *ctx, duk_idx_t index)
DUK_LOCAL_DECL duk_uint8_t duk__dec_get_nonwhite(duk_json_dec_ctx *js_ctx)
DUK_LOCAL_DECL void duk__dec_syntax_error(duk_json_dec_ctx *js_ctx)
DUK_LOCAL_DECL void duk__dec_objarr_exit(duk_json_dec_ctx *js_ctx)
DUK_LOCAL_DECL void duk__dec_objarr_entry(duk_json_dec_ctx *js_ctx)
DUK_LOCAL_DECL void duk__dec_value(duk_json_dec_ctx *js_ctx)

References duk__dec_get_nonwhite(), duk__dec_objarr_entry(), duk__dec_objarr_exit(), duk__dec_syntax_error(), duk__dec_value(), DUK_ASC_COMMA, DUK_ASC_RBRACKET, DUK_DDD, DUK_DDDPRINT, duk_get_tval(), duk_push_array(), duk_set_length(), DUK_UNREACHABLE, duk_xdef_prop_index_wec, duk_json_dec_ctx::p, and duk_json_dec_ctx::thr.

Referenced by duk__dec_value().

◆ duk__dec_buffer()

DUK_LOCAL_DECL void duk__dec_buffer ( duk_json_dec_ctx * js_ctx)

Definition at line 583 of file duktape-1.5.2/src-separate/duk_bi_json.c.

583 {
584 duk_hthread *thr = js_ctx->thr;
585 duk_context *ctx = (duk_context *) thr;
586 const duk_uint8_t *p;
587 duk_uint8_t *buf;
588 duk_size_t src_len;
590
591 /* Caller has already eaten the first character ('|') which we don't need. */
592
593 p = js_ctx->p;
594
595 /* XXX: Would be nice to share the fast path loop from duk_hex_decode()
596 * and avoid creating a temporary buffer. However, there are some
597 * differences which prevent trivial sharing:
598 *
599 * - Pipe char detection
600 * - EOF detection
601 * - Unknown length of input and output
602 *
603 * The best approach here would be a bufwriter and a reasonaly sized
604 * safe inner loop (e.g. 64 output bytes at a time).
605 */
606
607 for (;;) {
608 x = *p;
609
610 /* This loop intentionally does not ensure characters are valid
611 * ([0-9a-fA-F]) because the hex decode call below will do that.
612 */
613 if (x == DUK_ASC_PIPE) {
614 break;
615 } else if (x <= 0) {
616 /* NUL term or -1 (EOF), NUL check would suffice */
617 goto syntax_error;
618 }
619 p++;
620 }
621
622 src_len = (duk_size_t) (p - js_ctx->p);
623 buf = (duk_uint8_t *) duk_push_fixed_buffer(ctx, src_len);
624 DUK_ASSERT(buf != NULL);
625 DUK_MEMCPY((void *) buf, (const void *) js_ctx->p, src_len);
626 duk_hex_decode(ctx, -1);
627
628 js_ctx->p = p + 1; /* skip '|' */
629
630 /* [ ... buf ] */
631
632 return;
633
634 syntax_error:
635 duk__dec_syntax_error(js_ctx);
637}
DUK_EXTERNAL void duk_hex_decode(duk_context *ctx, duk_idx_t index)
#define duk_push_fixed_buffer(ctx, size)
#define NULL
Definition gmacros.h:924

References duk__dec_syntax_error(), DUK_ASC_PIPE, DUK_ASSERT, duk_hex_decode(), DUK_MEMCPY, duk_push_fixed_buffer, DUK_UNREACHABLE, NULL, duk_json_dec_ctx::p, and duk_json_dec_ctx::thr.

Referenced by duk__dec_value().

◆ duk__dec_decode_hex_escape()

DUK_LOCAL_DECL duk_uint_fast32_t duk__dec_decode_hex_escape ( duk_json_dec_ctx * js_ctx,
duk_small_uint_t n )

Definition at line 256 of file duktape-1.5.2/src-separate/duk_bi_json.c.

256 {
258 duk_uint_fast32_t res = 0;
259 duk_uint8_t x;
261
262 for (i = 0; i < n; i++) {
263 /* XXX: share helper from lexer; duk_lexer.c / hexval(). */
264
265 x = duk__dec_get(js_ctx);
266 DUK_DDD(DUK_DDDPRINT("decode_hex_escape: i=%ld, n=%ld, res=%ld, x=%ld",
267 (long) i, (long) n, (long) res, (long) x));
268
269 /* x == 0x00 (EOF) causes syntax_error */
270 DUK_ASSERT(duk_hex_dectab[0] == -1);
271 t = duk_hex_dectab[x & 0xff];
272 if (DUK_LIKELY(t >= 0)) {
273 res = (res * 16) + t;
274 } else {
275 /* catches EOF and invalid digits */
276 goto syntax_error;
277 }
278 }
279
280 DUK_DDD(DUK_DDDPRINT("final hex decoded value: %ld", (long) res));
281 return res;
282
283 syntax_error:
284 duk__dec_syntax_error(js_ctx);
286 return 0;
287}
unsigned int duk_small_uint_t
DUK_INTERNAL const duk_int8_t duk_hex_dectab[256]
DUK_LOCAL_DECL duk_uint8_t duk__dec_get(duk_json_dec_ctx *js_ctx)

References duk__dec_get(), duk__dec_syntax_error(), DUK_ASSERT, DUK_DDD, DUK_DDDPRINT, duk_hex_dectab, DUK_LIKELY, and DUK_UNREACHABLE.

Referenced by duk__dec_string_escape().

◆ duk__dec_eat_white()

DUK_LOCAL_DECL void duk__dec_eat_white ( duk_json_dec_ctx * js_ctx)

Definition at line 210 of file duktape-1.5.2/src-separate/duk_bi_json.c.

210 {
211 const duk_uint8_t *p;
212 duk_uint8_t t;
213
214 p = js_ctx->p;
215 for (;;) {
216 DUK_ASSERT(p <= js_ctx->p_end);
217 t = *p;
218
219#if defined(DUK_USE_JSON_EATWHITE_FASTPATH)
220 /* This fast path is pretty marginal in practice.
221 * XXX: candidate for removal.
222 */
223 DUK_ASSERT(duk__json_eatwhite_lookup[0x00] == 0x00); /* end-of-input breaks */
224 if (duk__json_eatwhite_lookup[t] == 0) {
225 break;
226 }
227#else /* DUK_USE_JSON_EATWHITE_FASTPATH */
228 if (!(t == 0x20 || t == 0x0a || t == 0x0d || t == 0x09)) {
229 /* NUL also comes here. Comparison order matters, 0x20
230 * is most common whitespace.
231 */
232 break;
233 }
234#endif /* DUK_USE_JSON_EATWHITE_FASTPATH */
235 p++;
236 }
237 js_ctx->p = p;
238}
DUK_LOCAL const duk_uint8_t duk__json_eatwhite_lookup[256]

References duk__json_eatwhite_lookup, DUK_ASSERT, and duk_json_dec_ctx::p.

Referenced by duk__dec_get_nonwhite(), and duk__dec_value().

◆ duk__dec_get()

DUK_LOCAL_DECL duk_uint8_t duk__dec_get ( duk_json_dec_ctx * js_ctx)

◆ duk__dec_get_nonwhite()

DUK_LOCAL_DECL duk_uint8_t duk__dec_get_nonwhite ( duk_json_dec_ctx * js_ctx)

Definition at line 250 of file duktape-1.5.2/src-separate/duk_bi_json.c.

250 {
251 duk__dec_eat_white(js_ctx);
252 return duk__dec_get(js_ctx);
253}
DUK_LOCAL_DECL void duk__dec_eat_white(duk_json_dec_ctx *js_ctx)

References duk__dec_eat_white(), and duk__dec_get().

Referenced by duk__dec_array(), duk__dec_object(), and duk__dec_value().

◆ duk__dec_number()

DUK_LOCAL_DECL void duk__dec_number ( duk_json_dec_ctx * js_ctx)

Definition at line 641 of file duktape-1.5.2/src-separate/duk_bi_json.c.

641 {
642 duk_context *ctx = (duk_context *) js_ctx->thr;
643 const duk_uint8_t *p_start;
644 const duk_uint8_t *p;
645 duk_uint8_t x;
646 duk_small_uint_t s2n_flags;
647
648 DUK_DDD(DUK_DDDPRINT("parse_number"));
649
650 p_start = js_ctx->p;
651
652 /* First pass parse is very lenient (e.g. allows '1.2.3') and extracts a
653 * string for strict number parsing.
654 */
655
656 p = js_ctx->p;
657 for (;;) {
658 x = *p;
659
660 DUK_DDD(DUK_DDDPRINT("parse_number: p_start=%p, p=%p, p_end=%p, x=%ld",
661 (const void *) p_start, (const void *) p,
662 (const void *) js_ctx->p_end, (long) x));
663
664#if defined(DUK_USE_JSON_DECNUMBER_FASTPATH)
665 /* This fast path is pretty marginal in practice.
666 * XXX: candidate for removal.
667 */
668 DUK_ASSERT(duk__json_decnumber_lookup[0x00] == 0x00); /* end-of-input breaks */
669 if (duk__json_decnumber_lookup[x] == 0) {
670 break;
671 }
672#else /* DUK_USE_JSON_DECNUMBER_FASTPATH */
673 if (!((x >= DUK_ASC_0 && x <= DUK_ASC_9) ||
674 (x == DUK_ASC_PERIOD || x == DUK_ASC_LC_E ||
675 x == DUK_ASC_UC_E || x == DUK_ASC_MINUS || x == DUK_ASC_PLUS))) {
676 /* Plus sign must be accepted for positive exponents
677 * (e.g. '1.5e+2'). This clause catches NULs.
678 */
679 break;
680 }
681#endif /* DUK_USE_JSON_DECNUMBER_FASTPATH */
682 p++; /* safe, because matched (NUL causes a break) */
683 }
684 js_ctx->p = p;
685
686 DUK_ASSERT(js_ctx->p > p_start);
687 duk_push_lstring(ctx, (const char *) p_start, (duk_size_t) (p - p_start));
688
689 s2n_flags = DUK_S2N_FLAG_ALLOW_EXP |
690 DUK_S2N_FLAG_ALLOW_MINUS | /* but don't allow leading plus */
692
693 DUK_DDD(DUK_DDDPRINT("parse_number: string before parsing: %!T",
694 (duk_tval *) duk_get_tval(ctx, -1)));
695 duk_numconv_parse(ctx, 10 /*radix*/, s2n_flags);
696 if (duk_is_nan(ctx, -1)) {
697 duk__dec_syntax_error(js_ctx);
698 }
699 DUK_ASSERT(duk_is_number(ctx, -1));
700 DUK_DDD(DUK_DDDPRINT("parse_number: final number: %!T",
701 (duk_tval *) duk_get_tval(ctx, -1)));
702
703 /* [ ... num ] */
704}
#define DUK_S2N_FLAG_ALLOW_FRAC
#define DUK_S2N_FLAG_ALLOW_MINUS
DUK_EXTERNAL const char * duk_push_lstring(duk_context *ctx, const char *str, duk_size_t len)
DUK_EXTERNAL duk_bool_t duk_is_number(duk_context *ctx, duk_idx_t index)
DUK_EXTERNAL duk_bool_t duk_is_nan(duk_context *ctx, duk_idx_t index)
DUK_INTERNAL_DECL void duk_numconv_parse(duk_context *ctx, duk_small_int_t radix, duk_small_uint_t flags)
#define DUK_S2N_FLAG_ALLOW_EXP
DUK_LOCAL const duk_uint8_t duk__json_decnumber_lookup[256]

References duk__dec_syntax_error(), duk__json_decnumber_lookup, DUK_ASC_0, DUK_ASC_9, DUK_ASC_LC_E, DUK_ASC_MINUS, DUK_ASC_PERIOD, DUK_ASC_PLUS, DUK_ASC_UC_E, DUK_ASSERT, DUK_DDD, DUK_DDDPRINT, duk_get_tval(), duk_is_nan(), duk_is_number(), duk_numconv_parse(), duk_push_lstring(), DUK_S2N_FLAG_ALLOW_EXP, DUK_S2N_FLAG_ALLOW_FRAC, DUK_S2N_FLAG_ALLOW_MINUS, duk_json_dec_ctx::p, duk_json_dec_ctx::p_end, and duk_json_dec_ctx::thr.

Referenced by duk__dec_value().

◆ duk__dec_objarr_entry()

DUK_LOCAL_DECL void duk__dec_objarr_entry ( duk_json_dec_ctx * js_ctx)

Definition at line 706 of file duktape-1.5.2/src-separate/duk_bi_json.c.

706 {
707 duk_context *ctx = (duk_context *) js_ctx->thr;
709
710 /* c recursion check */
711
712 DUK_ASSERT(js_ctx->recursion_depth >= 0);
713 DUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);
714 if (js_ctx->recursion_depth >= js_ctx->recursion_limit) {
716 }
717 js_ctx->recursion_depth++;
718}
#define DUK_ERROR_RANGE(thr, msg)
DUK_EXTERNAL void duk_require_stack(duk_context *ctx, duk_idx_t extra)
#define DUK_STR_JSONDEC_RECLIMIT
#define DUK_JSON_DEC_REQSTACK

References DUK_ASSERT, DUK_ERROR_RANGE, DUK_JSON_DEC_REQSTACK, duk_require_stack(), DUK_STR_JSONDEC_RECLIMIT, duk_json_dec_ctx::recursion_depth, duk_json_dec_ctx::recursion_limit, and duk_json_dec_ctx::thr.

Referenced by duk__dec_array(), and duk__dec_object().

◆ duk__dec_objarr_exit()

DUK_LOCAL_DECL void duk__dec_objarr_exit ( duk_json_dec_ctx * js_ctx)

Definition at line 720 of file duktape-1.5.2/src-separate/duk_bi_json.c.

720 {
721 /* c recursion check */
722
723 DUK_ASSERT(js_ctx->recursion_depth > 0);
724 DUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);
725 js_ctx->recursion_depth--;
726}

References DUK_ASSERT, duk_json_dec_ctx::recursion_depth, and duk_json_dec_ctx::recursion_limit.

Referenced by duk__dec_array(), and duk__dec_object().

◆ duk__dec_object()

DUK_LOCAL_DECL void duk__dec_object ( duk_json_dec_ctx * js_ctx)

Definition at line 728 of file duktape-1.5.2/src-separate/duk_bi_json.c.

728 {
729 duk_context *ctx = (duk_context *) js_ctx->thr;
730 duk_int_t key_count; /* XXX: a "first" flag would suffice */
731 duk_uint8_t x;
732
733 DUK_DDD(DUK_DDDPRINT("parse_object"));
734
735 duk__dec_objarr_entry(js_ctx);
736
737 duk_push_object(ctx);
738
739 /* Initial '{' has been checked and eaten by caller. */
740
741 key_count = 0;
742 for (;;) {
743 x = duk__dec_get_nonwhite(js_ctx);
744
745 DUK_DDD(DUK_DDDPRINT("parse_object: obj=%!T, x=%ld, key_count=%ld",
746 (duk_tval *) duk_get_tval(ctx, -1),
747 (long) x, (long) key_count));
748
749 /* handle comma and closing brace */
750
751 if (x == DUK_ASC_COMMA && key_count > 0) {
752 /* accept comma, expect new value */
753 x = duk__dec_get_nonwhite(js_ctx);
754 } else if (x == DUK_ASC_RCURLY) {
755 /* eat closing brace */
756 break;
757 } else if (key_count == 0) {
758 /* accept anything, expect first value (EOF will be
759 * caught by key parsing below.
760 */
761 ;
762 } else {
763 /* catches EOF (NUL) and initial comma */
764 goto syntax_error;
765 }
766
767 /* parse key and value */
768
769 if (x == DUK_ASC_DOUBLEQUOTE) {
770 duk__dec_string(js_ctx);
771#ifdef DUK_USE_JX
772 } else if (js_ctx->flag_ext_custom &&
774 duk__dec_plain_string(js_ctx);
775#endif
776 } else {
777 goto syntax_error;
778 }
779
780 /* [ ... obj key ] */
781
782 x = duk__dec_get_nonwhite(js_ctx);
783 if (x != DUK_ASC_COLON) {
784 goto syntax_error;
785 }
786
787 duk__dec_value(js_ctx);
788
789 /* [ ... obj key val ] */
790
791 duk_xdef_prop_wec(ctx, -3);
792
793 /* [ ... obj ] */
794
795 key_count++;
796 }
797
798 /* [ ... obj ] */
799
800 DUK_DDD(DUK_DDDPRINT("parse_object: final object is %!T",
801 (duk_tval *) duk_get_tval(ctx, -1)));
802
803 duk__dec_objarr_exit(js_ctx);
804 return;
805
806 syntax_error:
807 duk__dec_syntax_error(js_ctx);
809}
duk_int_fast32_t duk_int_t
#define duk_xdef_prop_wec(ctx, obj_index)
DUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_identifier_start(duk_codepoint_t cp)
DUK_EXTERNAL duk_idx_t duk_push_object(duk_context *ctx)
DUK_LOCAL_DECL void duk__dec_plain_string(duk_json_dec_ctx *js_ctx)
DUK_LOCAL_DECL void duk__dec_string(duk_json_dec_ctx *js_ctx)

References duk__dec_get_nonwhite(), duk__dec_objarr_entry(), duk__dec_objarr_exit(), duk__dec_plain_string(), duk__dec_string(), duk__dec_syntax_error(), duk__dec_value(), DUK_ASC_COLON, DUK_ASC_COMMA, DUK_ASC_DOUBLEQUOTE, DUK_ASC_RCURLY, DUK_DDD, DUK_DDDPRINT, duk_get_tval(), duk_push_object(), duk_unicode_is_identifier_start(), DUK_UNREACHABLE, duk_xdef_prop_wec, duk_json_dec_ctx::flag_ext_custom, and duk_json_dec_ctx::thr.

Referenced by duk__dec_value().

◆ duk__dec_peek()

DUK_LOCAL_DECL duk_uint8_t duk__dec_peek ( duk_json_dec_ctx * js_ctx)

Definition at line 240 of file duktape-1.5.2/src-separate/duk_bi_json.c.

240 {
241 DUK_ASSERT(js_ctx->p <= js_ctx->p_end);
242 return *js_ctx->p;
243}

References DUK_ASSERT, duk_json_dec_ctx::p, and duk_json_dec_ctx::p_end.

Referenced by duk__dec_value().

◆ duk__dec_plain_string()

DUK_LOCAL_DECL void duk__dec_plain_string ( duk_json_dec_ctx * js_ctx)

Definition at line 486 of file duktape-1.5.2/src-separate/duk_bi_json.c.

486 {
487 duk_hthread *thr = js_ctx->thr;
488 duk_context *ctx = (duk_context *) thr;
489 const duk_uint8_t *p;
491
492 /* Caller has already eaten the first char so backtrack one byte. */
493
494 js_ctx->p--; /* safe */
495 p = js_ctx->p;
496
497 /* Here again we parse bytes, and non-ASCII UTF-8 will cause end of
498 * parsing (which is correct except if there are non-shortest encodings).
499 * There is also no need to check explicitly for end of input buffer as
500 * the input is NUL padded and NUL will exit the parsing loop.
501 *
502 * Because no unescaping takes place, we can just scan to the end of the
503 * plain string and intern from the input buffer.
504 */
505
506 for (;;) {
507 x = *p;
508
509 /* There is no need to check the first character specially here
510 * (i.e. reject digits): the caller only accepts valid initial
511 * characters and won't call us if the first character is a digit.
512 * This also ensures that the plain string won't be empty.
513 */
514
516 break;
517 }
518 p++;
519 }
520
521 duk_push_lstring(ctx, (const char *) js_ctx->p, (duk_size_t) (p - js_ctx->p));
522 js_ctx->p = p;
523
524 /* [ ... str ] */
525}
DUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_identifier_part(duk_codepoint_t cp)

References duk_push_lstring(), duk_unicode_is_identifier_part(), duk_json_dec_ctx::p, and duk_json_dec_ctx::thr.

Referenced by duk__dec_object().

◆ duk__dec_pointer()

DUK_LOCAL_DECL void duk__dec_pointer ( duk_json_dec_ctx * js_ctx)

Definition at line 529 of file duktape-1.5.2/src-separate/duk_bi_json.c.

529 {
530 duk_hthread *thr = js_ctx->thr;
531 duk_context *ctx = (duk_context *) thr;
532 const duk_uint8_t *p;
534 void *voidptr;
535
536 /* Caller has already eaten the first character ('(') which we don't need. */
537
538 p = js_ctx->p;
539
540 for (;;) {
541 x = *p;
542
543 /* Assume that the native representation never contains a closing
544 * parenthesis.
545 */
546
547 if (x == DUK_ASC_RPAREN) {
548 break;
549 } else if (x <= 0) {
550 /* NUL term or -1 (EOF), NUL check would suffice */
551 goto syntax_error;
552 }
553 p++;
554 }
555
556 /* There is no need to NUL delimit the sscanf() call: trailing garbage is
557 * ignored and there is always a NUL terminator which will force an error
558 * if no error is encountered before it. It's possible that the scan
559 * would scan further than between [js_ctx->p,p[ though and we'd advance
560 * by less than the scanned value.
561 *
562 * Because pointers are platform specific, a failure to scan a pointer
563 * results in a null pointer which is a better placeholder than a missing
564 * value or an error.
565 */
566
567 voidptr = NULL;
568 (void) DUK_SSCANF((const char *) js_ctx->p, DUK_STR_FMT_PTR, &voidptr);
569 duk_push_pointer(ctx, voidptr);
570 js_ctx->p = p + 1; /* skip ')' */
571
572 /* [ ... ptr ] */
573
574 return;
575
576 syntax_error:
577 duk__dec_syntax_error(js_ctx);
579}
DUK_EXTERNAL void duk_push_pointer(duk_context *ctx, void *val)

References duk__dec_syntax_error(), DUK_ASC_RPAREN, duk_push_pointer(), DUK_SSCANF, DUK_STR_FMT_PTR, DUK_UNREACHABLE, NULL, duk_json_dec_ctx::p, and duk_json_dec_ctx::thr.

Referenced by duk__dec_value().

◆ duk__dec_req_stridx()

DUK_LOCAL_DECL void duk__dec_req_stridx ( duk_json_dec_ctx * js_ctx,
duk_small_uint_t stridx )

Definition at line 289 of file duktape-1.5.2/src-separate/duk_bi_json.c.

289 {
290 duk_hstring *h;
291 const duk_uint8_t *p;
292 duk_uint8_t x, y;
293
294 /* First character has already been eaten and checked by the caller.
295 * We can scan until a NUL in stridx string because no built-in strings
296 * have internal NULs.
297 */
298
299 DUK_ASSERT_DISABLE(stridx >= 0); /* unsigned */
301 h = DUK_HTHREAD_GET_STRING(js_ctx->thr, stridx);
302 DUK_ASSERT(h != NULL);
303
304 p = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h) + 1;
305 DUK_ASSERT(*(js_ctx->p - 1) == *(p - 1)); /* first character has been matched */
306
307 for (;;) {
308 x = *p;
309 if (x == 0) {
310 break;
311 }
312 y = duk__dec_get(js_ctx);
313 if (x != y) {
314 /* Catches EOF of JSON input. */
315 goto syntax_error;
316 }
317 p++;
318 }
319
320 return;
321
322 syntax_error:
323 duk__dec_syntax_error(js_ctx);
325}
#define DUK_HSTRING_GET_DATA(x)
#define DUK_ASSERT_DISABLE(x)
#define DUK_HTHREAD_GET_STRING(thr, idx)

References duk__dec_get(), duk__dec_syntax_error(), DUK_ASSERT, DUK_ASSERT_DISABLE, DUK_HEAP_NUM_STRINGS, DUK_HSTRING_GET_DATA, DUK_HTHREAD_GET_STRING, DUK_UNREACHABLE, NULL, duk_json_dec_ctx::p, and duk_json_dec_ctx::thr.

Referenced by duk__dec_value().

◆ duk__dec_reviver_walk()

DUK_LOCAL_DECL void duk__dec_reviver_walk ( duk_json_dec_ctx * js_ctx)

Definition at line 951 of file duktape-1.5.2/src-separate/duk_bi_json.c.

951 {
952 duk_context *ctx = (duk_context *) js_ctx->thr;
953 duk_hobject *h;
954 duk_uarridx_t i, arr_len;
955
956 DUK_DDD(DUK_DDDPRINT("walk: top=%ld, holder=%!T, name=%!T",
957 (long) duk_get_top(ctx),
958 (duk_tval *) duk_get_tval(ctx, -2),
959 (duk_tval *) duk_get_tval(ctx, -1)));
960
961 duk_dup_top(ctx);
962 duk_get_prop(ctx, -3); /* -> [ ... holder name val ] */
963
964 h = duk_get_hobject(ctx, -1);
965 if (h != NULL) {
967 arr_len = (duk_uarridx_t) duk_get_length(ctx, -1);
968 for (i = 0; i < arr_len; i++) {
969 /* [ ... holder name val ] */
970
971 DUK_DDD(DUK_DDDPRINT("walk: array, top=%ld, i=%ld, arr_len=%ld, holder=%!T, name=%!T, val=%!T",
972 (long) duk_get_top(ctx), (long) i, (long) arr_len,
973 (duk_tval *) duk_get_tval(ctx, -3), (duk_tval *) duk_get_tval(ctx, -2),
974 (duk_tval *) duk_get_tval(ctx, -1)));
975
976 /* XXX: push_uint_string / push_u32_string */
977 duk_dup_top(ctx);
978 duk_push_uint(ctx, (duk_uint_t) i);
979 duk_to_string(ctx, -1); /* -> [ ... holder name val val ToString(i) ] */
980 duk__dec_reviver_walk(js_ctx); /* -> [ ... holder name val new_elem ] */
981
982 if (duk_is_undefined(ctx, -1)) {
983 duk_pop(ctx);
984 duk_del_prop_index(ctx, -1, i);
985 } else {
986 /* XXX: duk_xdef_prop_index_wec() would be more appropriate
987 * here but it currently makes some assumptions that might
988 * not hold (e.g. that previous property is not an accessor).
989 */
990 duk_put_prop_index(ctx, -2, i);
991 }
992 }
993 } else {
994 /* [ ... holder name val ] */
995 duk_enum(ctx, -1, DUK_ENUM_OWN_PROPERTIES_ONLY /*flags*/);
996 while (duk_next(ctx, -1 /*enum_index*/, 0 /*get_value*/)) {
997 DUK_DDD(DUK_DDDPRINT("walk: object, top=%ld, holder=%!T, name=%!T, val=%!T, enum=%!iT, obj_key=%!T",
998 (long) duk_get_top(ctx), (duk_tval *) duk_get_tval(ctx, -5),
999 (duk_tval *) duk_get_tval(ctx, -4), (duk_tval *) duk_get_tval(ctx, -3),
1000 (duk_tval *) duk_get_tval(ctx, -2), (duk_tval *) duk_get_tval(ctx, -1)));
1001
1002 /* [ ... holder name val enum obj_key ] */
1003 duk_dup(ctx, -3);
1004 duk_dup(ctx, -2);
1005
1006 /* [ ... holder name val enum obj_key val obj_key ] */
1007 duk__dec_reviver_walk(js_ctx);
1008
1009 /* [ ... holder name val enum obj_key new_elem ] */
1010 if (duk_is_undefined(ctx, -1)) {
1011 duk_pop(ctx);
1012 duk_del_prop(ctx, -3);
1013 } else {
1014 /* XXX: duk_xdef_prop_index_wec() would be more appropriate
1015 * here but it currently makes some assumptions that might
1016 * not hold (e.g. that previous property is not an accessor).
1017 *
1018 * Using duk_put_prop() works incorrectly with '__proto__'
1019 * if the own property with that name has been deleted. This
1020 * does not happen normally, but a clever reviver can trigger
1021 * that, see complex reviver case in: test-bug-json-parse-__proto__.js.
1022 */
1023 duk_put_prop(ctx, -4);
1024 }
1025 }
1026 duk_pop(ctx); /* pop enum */
1027 }
1028 }
1029
1030 /* [ ... holder name val ] */
1031
1032 duk_dup(ctx, js_ctx->idx_reviver);
1033 duk_insert(ctx, -4); /* -> [ ... reviver holder name val ] */
1034 duk_call_method(ctx, 2); /* -> [ ... res ] */
1035
1036 DUK_DDD(DUK_DDDPRINT("walk: top=%ld, result=%!T",
1037 (long) duk_get_top(ctx), (duk_tval *) duk_get_tval(ctx, -1)));
1038}
duk_uint_fast32_t duk_uint_t
DUK_EXTERNAL void duk_enum(duk_context *ctx, duk_idx_t obj_index, duk_uint_t enum_flags)
DUK_EXTERNAL duk_bool_t duk_is_undefined(duk_context *ctx, duk_idx_t index)
DUK_EXTERNAL duk_bool_t duk_del_prop_index(duk_context *ctx, duk_idx_t obj_index, duk_uarridx_t arr_index)
DUK_EXTERNAL duk_bool_t duk_put_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx)
DUK_EXTERNAL duk_bool_t duk_next(duk_context *ctx, duk_idx_t enum_index, duk_bool_t get_value)
DUK_EXTERNAL duk_size_t duk_get_length(duk_context *ctx, duk_idx_t index)
#define DUK_HOBJECT_CLASS_ARRAY
DUK_EXTERNAL void duk_dup_top(duk_context *ctx)
DUK_EXTERNAL duk_bool_t duk_del_prop(duk_context *ctx, duk_idx_t obj_index)
DUK_EXTERNAL void duk_dup(duk_context *ctx, duk_idx_t from_index)
DUK_EXTERNAL void duk_insert(duk_context *ctx, duk_idx_t to_index)
DUK_EXTERNAL duk_idx_t duk_get_top(duk_context *ctx)
DUK_EXTERNAL void duk_push_uint(duk_context *ctx, duk_uint_t val)
DUK_EXTERNAL void duk_call_method(duk_context *ctx, duk_idx_t nargs)
DUK_EXTERNAL duk_bool_t duk_get_prop(duk_context *ctx, duk_idx_t obj_index)
DUK_EXTERNAL const char * duk_to_string(duk_context *ctx, duk_idx_t index)
DUK_EXTERNAL void duk_pop(duk_context *ctx)
DUK_INTERNAL_DECL duk_hobject * duk_get_hobject(duk_context *ctx, duk_idx_t index)
#define DUK_HOBJECT_GET_CLASS_NUMBER(h)
DUK_EXTERNAL duk_bool_t duk_put_prop(duk_context *ctx, duk_idx_t obj_idx)
#define DUK_ENUM_OWN_PROPERTIES_ONLY
DUK_LOCAL_DECL void duk__dec_reviver_walk(duk_json_dec_ctx *js_ctx)

References duk__dec_reviver_walk(), duk_call_method(), DUK_DDD, DUK_DDDPRINT, duk_del_prop(), duk_del_prop_index(), duk_dup(), duk_dup_top(), duk_enum(), DUK_ENUM_OWN_PROPERTIES_ONLY, duk_get_hobject(), duk_get_length(), duk_get_prop(), duk_get_top(), duk_get_tval(), DUK_HOBJECT_CLASS_ARRAY, DUK_HOBJECT_GET_CLASS_NUMBER, duk_insert(), duk_is_undefined(), duk_next(), duk_pop(), duk_push_uint(), duk_put_prop(), duk_put_prop_index(), duk_to_string(), duk_json_dec_ctx::idx_reviver, NULL, and duk_json_dec_ctx::thr.

Referenced by duk__dec_reviver_walk(), and duk_bi_json_parse_helper().

◆ duk__dec_string()

DUK_LOCAL_DECL void duk__dec_string ( duk_json_dec_ctx * js_ctx)

Definition at line 376 of file duktape-1.5.2/src-separate/duk_bi_json.c.

376 {
377 duk_hthread *thr = js_ctx->thr;
378 duk_context *ctx = (duk_context *) thr;
379 duk_bufwriter_ctx bw_alloc;
381 duk_uint8_t *q;
382
383 /* '"' was eaten by caller */
384
385 /* Note that we currently parse -bytes-, not codepoints.
386 * All non-ASCII extended UTF-8 will encode to bytes >= 0x80,
387 * so they'll simply pass through (valid UTF-8 or not).
388 */
389
390 bw = &bw_alloc;
392 q = DUK_BW_GET_PTR(js_ctx->thr, bw);
393
394#if defined(DUK_USE_JSON_DECSTRING_FASTPATH)
395 for (;;) {
396 duk_small_uint_t safe;
397 duk_uint8_t b, x;
398 const duk_uint8_t *p;
399
400 /* Select a safe loop count where no output checks are
401 * needed assuming we won't encounter escapes. Input
402 * bound checks are not necessary as a NUL (guaranteed)
403 * will cause a SyntaxError before we read out of bounds.
404 */
405
407
408 /* Ensure space for 1:1 output plus one escape. */
409 q = DUK_BW_ENSURE_RAW(js_ctx->thr, bw, safe + DUK_UNICODE_MAX_XUTF8_LENGTH, q);
410
411 p = js_ctx->p; /* temp copy, write back for next loop */
412 for (;;) {
413 if (safe == 0) {
414 js_ctx->p = p;
415 break;
416 }
417 safe--;
418
419 /* End of input (NUL) goes through slow path and causes SyntaxError. */
421
422 b = *p++;
424 if (DUK_LIKELY(x != 0)) {
425 /* Fast path, decode as is. */
426 *q++ = b;
427 } else if (b == DUK_ASC_DOUBLEQUOTE) {
428 js_ctx->p = p;
429 goto found_quote;
430 } else if (b == DUK_ASC_BACKSLASH) {
431 /* We've ensured space for one escaped input; then
432 * bail out and recheck (this makes escape handling
433 * quite slow but it's uncommon).
434 */
435 js_ctx->p = p;
436 if (duk__dec_string_escape(js_ctx, &q) != 0) {
437 goto syntax_error;
438 }
439 break;
440 } else {
441 js_ctx->p = p;
442 goto syntax_error;
443 }
444 }
445 }
446 found_quote:
447#else /* DUK_USE_JSON_DECSTRING_FASTPATH */
448 for (;;) {
449 duk_uint8_t x;
450
452
453 x = duk__dec_get(js_ctx);
454
455 if (x == DUK_ASC_DOUBLEQUOTE) {
456 break;
457 } else if (x == DUK_ASC_BACKSLASH) {
458 if (duk__dec_string_escape(js_ctx, &q) != 0) {
459 goto syntax_error;
460 }
461 } else if (x < 0x20) {
462 /* catches EOF (NUL) */
463 goto syntax_error;
464 } else {
465 *q++ = (duk_uint8_t) x;
466 }
467 }
468#endif /* DUK_USE_JSON_DECSTRING_FASTPATH */
469
470 DUK_BW_SETPTR_AND_COMPACT(js_ctx->thr, bw, q);
471 duk_to_string(ctx, -1);
472
473 /* [ ... str ] */
474
475 return;
476
477 syntax_error:
478 duk__dec_syntax_error(js_ctx);
480}
#define DUK_BW_SETPTR_AND_COMPACT(thr, bw_ctx, ptr)
#define DUK_BW_ENSURE_RAW(thr, bw_ctx, sz, ptr)
#define DUK_BW_INIT_PUSHBUF(thr, bw_ctx, sz)
#define DUK_BW_GET_PTR(thr, bw_ctx)
#define DUK_UNICODE_MAX_XUTF8_LENGTH
DUK_LOCAL const duk_uint8_t duk__json_decstr_lookup[256]
DUK_LOCAL duk_small_int_t duk__dec_string_escape(duk_json_dec_ctx *js_ctx, duk_uint8_t **ext_p)

References duk__dec_get(), duk__dec_string_escape(), duk__dec_syntax_error(), DUK__JSON_DECSTR_BUFSIZE, DUK__JSON_DECSTR_CHUNKSIZE, duk__json_decstr_lookup, DUK_ASC_BACKSLASH, DUK_ASC_DOUBLEQUOTE, DUK_ASSERT, DUK_BW_ENSURE_RAW, DUK_BW_GET_PTR, DUK_BW_INIT_PUSHBUF, DUK_BW_SETPTR_AND_COMPACT, DUK_LIKELY, duk_to_string(), DUK_UNICODE_MAX_XUTF8_LENGTH, DUK_UNREACHABLE, duk_json_dec_ctx::p, and duk_json_dec_ctx::thr.

Referenced by duk__dec_object(), and duk__dec_value().

◆ duk__dec_string_escape()

DUK_LOCAL duk_small_int_t duk__dec_string_escape ( duk_json_dec_ctx * js_ctx,
duk_uint8_t ** ext_p )

Definition at line 327 of file duktape-1.5.2/src-separate/duk_bi_json.c.

327 {
329
330 /* EOF (-1) will be cast to an unsigned value first
331 * and then re-cast for the switch. In any case, it
332 * will match the default case (syntax error).
333 */
334 cp = (duk_uint_fast32_t) duk__dec_get(js_ctx);
335 switch ((int) cp) {
336 case DUK_ASC_BACKSLASH: break;
337 case DUK_ASC_DOUBLEQUOTE: break;
338 case DUK_ASC_SLASH: break;
339 case DUK_ASC_LC_T: cp = 0x09; break;
340 case DUK_ASC_LC_N: cp = 0x0a; break;
341 case DUK_ASC_LC_R: cp = 0x0d; break;
342 case DUK_ASC_LC_F: cp = 0x0c; break;
343 case DUK_ASC_LC_B: cp = 0x08; break;
344 case DUK_ASC_LC_U: {
345 cp = duk__dec_decode_hex_escape(js_ctx, 4);
346 break;
347 }
348#ifdef DUK_USE_JX
349 case DUK_ASC_UC_U: {
350 if (js_ctx->flag_ext_custom) {
351 cp = duk__dec_decode_hex_escape(js_ctx, 8);
352 } else {
353 return 1; /* syntax error */
354 }
355 break;
356 }
357 case DUK_ASC_LC_X: {
358 if (js_ctx->flag_ext_custom) {
359 cp = duk__dec_decode_hex_escape(js_ctx, 2);
360 } else {
361 return 1; /* syntax error */
362 }
363 break;
364 }
365#endif /* DUK_USE_JX */
366 default:
367 /* catches EOF (0x00) */
368 return 1; /* syntax error */
369 }
370
371 DUK_RAW_WRITE_XUTF8(*ext_p, cp);
372
373 return 0;
374}
#define DUK_RAW_WRITE_XUTF8(ptr, val)
DUK_LOCAL_DECL duk_uint_fast32_t duk__dec_decode_hex_escape(duk_json_dec_ctx *js_ctx, duk_small_uint_t n)

References duk__dec_decode_hex_escape(), duk__dec_get(), DUK_ASC_BACKSLASH, DUK_ASC_DOUBLEQUOTE, DUK_ASC_LC_B, DUK_ASC_LC_F, DUK_ASC_LC_N, DUK_ASC_LC_R, DUK_ASC_LC_T, DUK_ASC_LC_U, DUK_ASC_LC_X, DUK_ASC_SLASH, DUK_ASC_UC_U, DUK_RAW_WRITE_XUTF8, and duk_json_dec_ctx::flag_ext_custom.

Referenced by duk__dec_string().

◆ duk__dec_syntax_error()

DUK_LOCAL_DECL void duk__dec_syntax_error ( duk_json_dec_ctx * js_ctx)

Definition at line 201 of file duktape-1.5.2/src-separate/duk_bi_json.c.

201 {
202 /* Shared handler to minimize parser size. Cause will be
203 * hidden, unfortunately, but we'll have an offset which
204 * is often quite enough.
205 */
207 (long) (js_ctx->p - js_ctx->p_start));
208}
#define DUK_STR_FMT_INVALID_JSON
#define DUK_ERROR_FMT1(thr, err, fmt, arg1)
#define DUK_ERR_SYNTAX_ERROR

References DUK_ERR_SYNTAX_ERROR, DUK_ERROR_FMT1, DUK_STR_FMT_INVALID_JSON, duk_json_dec_ctx::p, duk_json_dec_ctx::p_start, and duk_json_dec_ctx::thr.

Referenced by duk__dec_array(), duk__dec_buffer(), duk__dec_decode_hex_escape(), duk__dec_number(), duk__dec_object(), duk__dec_pointer(), duk__dec_req_stridx(), duk__dec_string(), duk__dec_value(), and duk_bi_json_parse_helper().

◆ duk__dec_value()

DUK_LOCAL_DECL void duk__dec_value ( duk_json_dec_ctx * js_ctx)

Definition at line 879 of file duktape-1.5.2/src-separate/duk_bi_json.c.

879 {
880 duk_context *ctx = (duk_context *) js_ctx->thr;
881 duk_uint8_t x;
882
883 x = duk__dec_get_nonwhite(js_ctx);
884
885 DUK_DDD(DUK_DDDPRINT("parse_value: initial x=%ld", (long) x));
886
887 /* Note: duk__dec_req_stridx() backtracks one char */
888
889 if (x == DUK_ASC_DOUBLEQUOTE) {
890 duk__dec_string(js_ctx);
891 } else if ((x >= DUK_ASC_0 && x <= DUK_ASC_9) || (x == DUK_ASC_MINUS)) {
892#ifdef DUK_USE_JX
893 if (js_ctx->flag_ext_custom && x == DUK_ASC_MINUS && duk__dec_peek(js_ctx) == DUK_ASC_UC_I) {
894 duk__dec_req_stridx(js_ctx, DUK_STRIDX_MINUS_INFINITY); /* "-Infinity", '-' has been eaten */
896 } else {
897#else
898 { /* unconditional block */
899#endif
900 /* We already ate 'x', so backup one byte. */
901 js_ctx->p--; /* safe */
902 duk__dec_number(js_ctx);
903 }
904 } else if (x == DUK_ASC_LC_T) {
906 duk_push_true(ctx);
907 } else if (x == DUK_ASC_LC_F) {
909 duk_push_false(ctx);
910 } else if (x == DUK_ASC_LC_N) {
912 duk_push_null(ctx);
913#ifdef DUK_USE_JX
914 } else if (js_ctx->flag_ext_custom && x == DUK_ASC_LC_U) {
917 } else if (js_ctx->flag_ext_custom && x == DUK_ASC_UC_N) {
919 duk_push_nan(ctx);
920 } else if (js_ctx->flag_ext_custom && x == DUK_ASC_UC_I) {
923 } else if (js_ctx->flag_ext_custom && x == DUK_ASC_LPAREN) {
924 duk__dec_pointer(js_ctx);
925 } else if (js_ctx->flag_ext_custom && x == DUK_ASC_PIPE) {
926 duk__dec_buffer(js_ctx);
927#endif
928 } else if (x == DUK_ASC_LCURLY) {
929 duk__dec_object(js_ctx);
930 } else if (x == DUK_ASC_LBRACKET) {
931 duk__dec_array(js_ctx);
932 } else {
933 /* catches EOF (NUL) */
934 goto syntax_error;
935 }
936
937 duk__dec_eat_white(js_ctx);
938
939 /* [ ... val ] */
940 return;
941
942 syntax_error:
943 duk__dec_syntax_error(js_ctx);
945}
DUK_EXTERNAL void duk_push_true(duk_context *ctx)
#define DUK_STRIDX_MINUS_INFINITY
#define DUK_STRIDX_LC_UNDEFINED
DUK_EXTERNAL void duk_push_null(duk_context *ctx)
DUK_EXTERNAL void duk_push_undefined(duk_context *ctx)
DUK_EXTERNAL void duk_push_number(duk_context *ctx, duk_double_t val)
DUK_EXTERNAL void duk_push_false(duk_context *ctx)
DUK_EXTERNAL void duk_push_nan(duk_context *ctx)
DUK_LOCAL_DECL void duk__dec_number(duk_json_dec_ctx *js_ctx)
DUK_LOCAL_DECL duk_uint8_t duk__dec_peek(duk_json_dec_ctx *js_ctx)
DUK_LOCAL_DECL void duk__dec_object(duk_json_dec_ctx *js_ctx)
DUK_LOCAL_DECL void duk__dec_pointer(duk_json_dec_ctx *js_ctx)
DUK_LOCAL_DECL void duk__dec_array(duk_json_dec_ctx *js_ctx)
DUK_LOCAL_DECL void duk__dec_buffer(duk_json_dec_ctx *js_ctx)
DUK_LOCAL_DECL void duk__dec_req_stridx(duk_json_dec_ctx *js_ctx, duk_small_uint_t stridx)

References duk__dec_array(), duk__dec_buffer(), duk__dec_eat_white(), duk__dec_get_nonwhite(), duk__dec_number(), duk__dec_object(), duk__dec_peek(), duk__dec_pointer(), duk__dec_req_stridx(), duk__dec_string(), duk__dec_syntax_error(), DUK_ASC_0, DUK_ASC_9, DUK_ASC_DOUBLEQUOTE, DUK_ASC_LBRACKET, DUK_ASC_LC_F, DUK_ASC_LC_N, DUK_ASC_LC_T, DUK_ASC_LC_U, DUK_ASC_LCURLY, DUK_ASC_LPAREN, DUK_ASC_MINUS, DUK_ASC_PIPE, DUK_ASC_UC_I, DUK_ASC_UC_N, DUK_DDD, DUK_DDDPRINT, DUK_DOUBLE_INFINITY, duk_push_false(), duk_push_nan(), duk_push_null(), duk_push_number(), duk_push_true(), duk_push_undefined(), DUK_STRIDX_FALSE, DUK_STRIDX_INFINITY, DUK_STRIDX_LC_NULL, DUK_STRIDX_LC_UNDEFINED, DUK_STRIDX_MINUS_INFINITY, DUK_STRIDX_NAN, DUK_STRIDX_TRUE, DUK_UNREACHABLE, duk_json_dec_ctx::flag_ext_custom, duk_json_dec_ctx::p, and duk_json_dec_ctx::thr.

Referenced by duk__dec_array(), duk__dec_object(), and duk_bi_json_parse_helper().

◆ duk__emit_1()

DUK_LOCAL_DECL void duk__emit_1 ( duk_json_enc_ctx * js_ctx,
duk_uint_fast8_t ch )

Definition at line 1053 of file duktape-1.5.2/src-separate/duk_bi_json.c.

1053 {
1054 DUK_BW_WRITE_ENSURE_U8(js_ctx->thr, &js_ctx->bw, ch);
1055}
#define DUK_BW_WRITE_ENSURE_U8(thr, bw_ctx, val)

References duk_json_enc_ctx::bw, DUK_BW_WRITE_ENSURE_U8, and duk_json_enc_ctx::thr.

◆ duk__emit_2()

DUK_LOCAL_DECL void duk__emit_2 ( duk_json_enc_ctx * js_ctx,
duk_uint_fast8_t ch1,
duk_uint_fast8_t ch2 )

Definition at line 1057 of file duktape-1.5.2/src-separate/duk_bi_json.c.

1057 {
1058 DUK_BW_WRITE_ENSURE_U8_2(js_ctx->thr, &js_ctx->bw, ch1, ch2);
1059}
#define DUK_BW_WRITE_ENSURE_U8_2(thr, bw_ctx, val1, val2)

References duk_json_enc_ctx::bw, DUK_BW_WRITE_ENSURE_U8_2, and duk_json_enc_ctx::thr.

◆ duk__emit_cstring()

DUK_LOCAL void duk__emit_cstring ( duk_json_enc_ctx * js_ctx,
const char * str )

Definition at line 1066 of file duktape-1.5.2/src-separate/duk_bi_json.c.

1066 {
1067 DUK_BW_WRITE_ENSURE_CSTRING(js_ctx->thr, &js_ctx->bw, str);
1068}
#define DUK_BW_WRITE_ENSURE_CSTRING(thr, bw_ctx, val)

References duk_json_enc_ctx::bw, DUK_BW_WRITE_ENSURE_CSTRING, and duk_json_enc_ctx::thr.

◆ duk__emit_esc_auto_fast()

DUK_LOCAL_DECL duk_uint8_t * duk__emit_esc_auto_fast ( duk_json_enc_ctx * js_ctx,
duk_uint_fast32_t cp,
duk_uint8_t * q )

Definition at line 1092 of file duktape-1.5.2/src-separate/duk_bi_json.c.

1092 {
1094 duk_small_uint_t dig;
1095
1096 DUK_UNREF(js_ctx);
1097
1098 /* Caller ensures space for at least DUK__JSON_MAX_ESC_LEN. */
1099
1100 /* Select appropriate escape format automatically, and set 'tmp' to a
1101 * value encoding both the escape format character and the nybble count:
1102 *
1103 * (nybble_count << 16) | (escape_char1) | (escape_char2)
1104 */
1105
1106#ifdef DUK_USE_JX
1107 if (DUK_LIKELY(cp < 0x100UL)) {
1108 if (DUK_UNLIKELY(js_ctx->flag_ext_custom)) {
1110 } else {
1112 }
1113 } else
1114#endif
1115 if (DUK_LIKELY(cp < 0x10000UL)) {
1117 } else {
1118#ifdef DUK_USE_JX
1119 if (DUK_LIKELY(js_ctx->flag_ext_custom)) {
1121 } else
1122#endif
1123 {
1124 /* In compatible mode and standard JSON mode, output
1125 * something useful for non-BMP characters. This won't
1126 * roundtrip but will still be more or less readable and
1127 * more useful than an error.
1128 */
1130 }
1131 }
1132
1133 *q++ = (duk_uint8_t) ((tmp >> 8) & 0xff);
1134 *q++ = (duk_uint8_t) (tmp & 0xff);
1135
1136 tmp = tmp >> 16;
1137 while (tmp > 0) {
1138 tmp--;
1139 dig = (duk_small_uint_t) ((cp >> (4 * tmp)) & 0x0f);
1140 *q++ = duk_lc_digits[dig];
1141 }
1142
1143 return q;
1144}
DUK_INTERNAL const duk_uint8_t duk_lc_digits[36]
#define DUK__MKESC(nybbles, esc1, esc2)

References DUK__MKESC, DUK_ASC_BACKSLASH, DUK_ASC_LC_U, DUK_ASC_LC_X, DUK_ASC_PLUS, DUK_ASC_UC_U, duk_lc_digits, DUK_LIKELY, DUK_UNLIKELY, DUK_UNREF, and duk_json_enc_ctx::flag_ext_custom.

Referenced by duk__enc_quote_string().

◆ duk__emit_hstring()

DUK_LOCAL_DECL void duk__emit_hstring ( duk_json_enc_ctx * js_ctx,
duk_hstring * h )

Definition at line 1061 of file duktape-1.5.2/src-separate/duk_bi_json.c.

1061 {
1062 DUK_BW_WRITE_ENSURE_HSTRING(js_ctx->thr, &js_ctx->bw, h);
1063}
#define DUK_BW_WRITE_ENSURE_HSTRING(thr, bw_ctx, val)

References duk_json_enc_ctx::bw, DUK_BW_WRITE_ENSURE_HSTRING, and duk_json_enc_ctx::thr.

◆ duk__emit_stridx()

DUK_LOCAL_DECL void duk__emit_stridx ( duk_json_enc_ctx * js_ctx,
duk_small_uint_t stridx )

Definition at line 1071 of file duktape-1.5.2/src-separate/duk_bi_json.c.

1071 {
1072 duk_hstring *h;
1073
1074 DUK_ASSERT_DISABLE(stridx >= 0); /* unsigned */
1076 h = DUK_HTHREAD_GET_STRING(js_ctx->thr, stridx);
1077 DUK_ASSERT(h != NULL);
1078
1079 DUK_BW_WRITE_ENSURE_HSTRING(js_ctx->thr, &js_ctx->bw, h);
1080}

References duk_json_enc_ctx::bw, DUK_ASSERT, DUK_ASSERT_DISABLE, DUK_BW_WRITE_ENSURE_HSTRING, DUK_HEAP_NUM_STRINGS, DUK_HTHREAD_GET_STRING, NULL, and duk_json_enc_ctx::thr.

◆ duk__enc_allow_into_proplist()

DUK_LOCAL_DECL duk_bool_t duk__enc_allow_into_proplist ( duk_tval * tv)

Definition at line 2187 of file duktape-1.5.2/src-separate/duk_bi_json.c.

2187 {
2188 duk_hobject *h;
2190
2191 DUK_ASSERT(tv != NULL);
2192 if (DUK_TVAL_IS_STRING(tv) || DUK_TVAL_IS_NUMBER(tv)) {
2193 return 1;
2194 } else if (DUK_TVAL_IS_OBJECT(tv)) {
2195 h = DUK_TVAL_GET_OBJECT(tv);
2196 DUK_ASSERT(h != NULL);
2199 return 1;
2200 }
2201 }
2202
2203 return 0;
2204}
#define DUK_TVAL_IS_NUMBER(tv)
#define DUK_TVAL_GET_OBJECT(tv)
#define DUK_TVAL_IS_OBJECT(tv)
#define DUK_HOBJECT_CLASS_NUMBER
#define DUK_TVAL_IS_STRING(tv)
#define DUK_HOBJECT_CLASS_STRING

References DUK_ASSERT, DUK_HOBJECT_CLASS_NUMBER, DUK_HOBJECT_CLASS_STRING, DUK_HOBJECT_GET_CLASS_NUMBER, DUK_TVAL_GET_OBJECT, DUK_TVAL_IS_NUMBER, DUK_TVAL_IS_OBJECT, DUK_TVAL_IS_STRING, and NULL.

Referenced by duk_bi_json_stringify_helper().

◆ duk__enc_array()

DUK_LOCAL_DECL void duk__enc_array ( duk_json_enc_ctx * js_ctx)

Definition at line 1863 of file duktape-1.5.2/src-separate/duk_bi_json.c.

1863 {
1864 duk_context *ctx = (duk_context *) js_ctx->thr;
1865 duk_idx_t entry_top;
1866 duk_idx_t idx_arr;
1867 duk_bool_t emitted;
1868 duk_uarridx_t i, arr_len;
1869
1870 DUK_DDD(DUK_DDDPRINT("duk__enc_array: array=%!T",
1871 (duk_tval *) duk_get_tval(ctx, -1)));
1872
1873 duk__enc_objarr_entry(js_ctx, &entry_top);
1874
1875 idx_arr = entry_top - 1;
1876
1877 /* Steps 8-10 have been merged to avoid a "partial" variable. */
1878
1880
1881 arr_len = (duk_uarridx_t) duk_get_length(ctx, idx_arr);
1882 emitted = 0;
1883 for (i = 0; i < arr_len; i++) {
1884 DUK_DDD(DUK_DDDPRINT("array entry loop: array=%!T, index=%ld, arr_len=%ld",
1885 (duk_tval *) duk_get_tval(ctx, idx_arr),
1886 (long) i, (long) arr_len));
1887
1888 if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {
1889 DUK_ASSERT(js_ctx->recursion_depth >= 1);
1891 }
1892
1893 /* XXX: duk_push_uint_string() */
1894 duk_push_uint(ctx, (duk_uint_t) i);
1895 duk_to_string(ctx, -1); /* -> [ ... key ] */
1896
1897 /* [ ... key ] */
1898
1899 if (DUK_UNLIKELY(duk__enc_value(js_ctx, idx_arr) == 0)) {
1900 /* Value would normally be omitted, replace with 'null'. */
1902 } else {
1903 ;
1904 }
1905
1906 /* [ ... ] */
1907
1908 DUK__EMIT_1(js_ctx, DUK_ASC_COMMA);
1909 emitted = 1;
1910 }
1911
1912 if (emitted) {
1913 DUK_ASSERT(*((duk_uint8_t *) DUK_BW_GET_PTR(js_ctx->thr, &js_ctx->bw) - 1) == DUK_ASC_COMMA);
1914 DUK__UNEMIT_1(js_ctx); /* eat trailing comma */
1915 if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {
1916 DUK_ASSERT(js_ctx->recursion_depth >= 1);
1917 duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1);
1918 }
1919 }
1921
1922 duk__enc_objarr_exit(js_ctx, &entry_top);
1923
1924 DUK_ASSERT_TOP(ctx, entry_top);
1925}
duk_small_int_t duk_bool_t
#define DUK_ASSERT_TOP(ctx, n)
DUK_LOCAL_DECL void duk__enc_objarr_entry(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top)
#define DUK__EMIT_STRIDX(js_ctx, i)
DUK_LOCAL_DECL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_int_t depth)
DUK_LOCAL_DECL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_holder)
DUK_LOCAL_DECL void duk__enc_objarr_exit(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top)
#define DUK__UNEMIT_1(js_ctx)
#define DUK__EMIT_1(js_ctx, ch)

References duk_json_enc_ctx::bw, DUK__EMIT_1, DUK__EMIT_STRIDX, duk__enc_newline_indent(), duk__enc_objarr_entry(), duk__enc_objarr_exit(), duk__enc_value(), DUK__UNEMIT_1, DUK_ASC_COMMA, DUK_ASC_LBRACKET, DUK_ASC_RBRACKET, DUK_ASSERT, DUK_ASSERT_TOP, DUK_BW_GET_PTR, DUK_DDD, DUK_DDDPRINT, duk_get_length(), duk_get_tval(), duk_push_uint(), DUK_STRIDX_LC_NULL, duk_to_string(), DUK_UNLIKELY, duk_json_enc_ctx::h_gap, NULL, duk_json_enc_ctx::recursion_depth, and duk_json_enc_ctx::thr.

Referenced by duk__enc_value().

◆ duk__enc_buffer()

DUK_LOCAL_DECL void duk__enc_buffer ( duk_json_enc_ctx * js_ctx,
duk_hbuffer * h )

Definition at line 1557 of file duktape-1.5.2/src-separate/duk_bi_json.c.

1557 {
1558 duk__enc_buffer_data(js_ctx,
1559 (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(js_ctx->thr->heap, h),
1561}
#define DUK_HBUFFER_GET_DATA_PTR(heap, x)
#define DUK_HBUFFER_GET_SIZE(x)
DUK_LOCAL void duk__enc_buffer_data(duk_json_enc_ctx *js_ctx, duk_uint8_t *buf_data, duk_size_t buf_len)

References duk__enc_buffer_data(), DUK_HBUFFER_GET_DATA_PTR, DUK_HBUFFER_GET_SIZE, duk_hthread::heap, and duk_json_enc_ctx::thr.

Referenced by duk__enc_value().

◆ duk__enc_buffer_data()

DUK_LOCAL void duk__enc_buffer_data ( duk_json_enc_ctx * js_ctx,
duk_uint8_t * buf_data,
duk_size_t buf_len )

Definition at line 1503 of file duktape-1.5.2/src-separate/duk_bi_json.c.

1503 {
1504 duk_hthread *thr;
1505 duk_uint8_t *q;
1506 duk_size_t space;
1507
1508 thr = js_ctx->thr;
1509
1510 DUK_ASSERT(js_ctx->flag_ext_custom || js_ctx->flag_ext_compatible); /* caller checks */
1512
1513 /* Buffer values are encoded in (lowercase) hex to make the
1514 * binary data readable. Base64 or similar would be more
1515 * compact but less readable, and the point of JX/JC
1516 * variants is to be as useful to a programmer as possible.
1517 */
1518
1519 /* The #ifdef clutter here needs to handle the three cases:
1520 * (1) JX+JC, (2) JX only, (3) JC only.
1521 */
1522
1523 /* Note: space must cater for both JX and JC. */
1524 space = 9 + buf_len * 2 + 2;
1525 DUK_ASSERT(DUK_HBUFFER_MAX_BYTELEN <= 0x7ffffffeUL);
1526 DUK_ASSERT((space - 2) / 2 >= buf_len); /* overflow not possible, buffer limits */
1527 q = DUK_BW_ENSURE_GETPTR(thr, &js_ctx->bw, space);
1528
1529#if defined(DUK_USE_JX) && defined(DUK_USE_JC)
1530 if (js_ctx->flag_ext_custom)
1531#endif
1532#if defined(DUK_USE_JX)
1533 {
1534 *q++ = DUK_ASC_PIPE;
1535 q = duk__enc_buffer_data_hex(buf_data, buf_len, q);
1536 *q++ = DUK_ASC_PIPE;
1537
1538 }
1539#endif
1540#if defined(DUK_USE_JX) && defined(DUK_USE_JC)
1541 else
1542#endif
1543#if defined(DUK_USE_JC)
1544 {
1546 DUK_MEMCPY((void *) q, (const void *) "{\"_buf\":\"", 9); /* len: 9 */
1547 q += 9;
1548 q = duk__enc_buffer_data_hex(buf_data, buf_len, q);
1549 *q++ = DUK_ASC_DOUBLEQUOTE;
1550 *q++ = DUK_ASC_RCURLY;
1551 }
1552#endif
1553
1554 DUK_BW_SET_PTR(thr, &js_ctx->bw, q);
1555}
#define DUK_BW_SET_PTR(thr, bw_ctx, ptr)
#define DUK_HBUFFER_MAX_BYTELEN
#define DUK_BW_ENSURE_GETPTR(thr, bw_ctx, sz)
DUK_LOCAL duk_uint8_t * duk__enc_buffer_data_hex(const duk_uint8_t *src, duk_size_t src_len, duk_uint8_t *dst)

References duk_json_enc_ctx::bw, duk__enc_buffer_data_hex(), DUK_ASC_DOUBLEQUOTE, DUK_ASC_PIPE, DUK_ASC_RCURLY, DUK_ASSERT, DUK_BW_ENSURE_GETPTR, DUK_BW_SET_PTR, DUK_HBUFFER_MAX_BYTELEN, DUK_MEMCPY, duk_json_enc_ctx::flag_ext_compatible, duk_json_enc_ctx::flag_ext_custom, duk_json_enc_ctx::flag_ext_custom_or_compatible, and duk_json_enc_ctx::thr.

Referenced by duk__enc_buffer(), and duk__enc_bufferobject().

◆ duk__enc_buffer_data_hex()

DUK_LOCAL duk_uint8_t * duk__enc_buffer_data_hex ( const duk_uint8_t * src,
duk_size_t src_len,
duk_uint8_t * dst )

Definition at line 1426 of file duktape-1.5.2/src-separate/duk_bi_json.c.

1426 {
1427 duk_uint8_t *q;
1428 duk_uint16_t *q16;
1430 duk_size_t i, len_safe;
1431#if !defined(DUK_USE_UNALIGNED_ACCESSES_POSSIBLE)
1432 duk_bool_t shift_dst;
1433#endif
1434
1435 /* Unlike in duk_hex_encode() 'dst' is not necessarily aligned by 2.
1436 * For platforms where unaligned accesses are not allowed, shift 'dst'
1437 * ahead by 1 byte to get alignment and then DUK_MEMMOVE() the result
1438 * in place. The faster encoding loop makes up the difference.
1439 * There's always space for one extra byte because a terminator always
1440 * follows the hex data and that's been accounted for by the caller.
1441 */
1442
1443#if defined(DUK_USE_UNALIGNED_ACCESSES_POSSIBLE)
1444 q16 = (duk_uint16_t *) (void *) dst;
1445#else
1446 shift_dst = (duk_bool_t) (((duk_size_t) dst) & 0x01U);
1447 if (shift_dst) {
1448 DUK_DD(DUK_DDPRINT("unaligned accesses not possible, dst not aligned -> step to dst + 1"));
1449 q16 = (duk_uint16_t *) (void *) (dst + 1);
1450 } else {
1451 DUK_DD(DUK_DDPRINT("unaligned accesses not possible, dst is aligned"));
1452 q16 = (duk_uint16_t *) (void *) dst;
1453 }
1454 DUK_ASSERT((((duk_size_t) q16) & 0x01U) == 0);
1455#endif
1456
1457 len_safe = src_len & ~0x03U;
1458 for (i = 0; i < len_safe; i += 4) {
1459 q16[0] = duk_hex_enctab[src[i]];
1460 q16[1] = duk_hex_enctab[src[i + 1]];
1461 q16[2] = duk_hex_enctab[src[i + 2]];
1462 q16[3] = duk_hex_enctab[src[i + 3]];
1463 q16 += 4;
1464 }
1465 q = (duk_uint8_t *) q16;
1466
1467#if !defined(DUK_USE_UNALIGNED_ACCESSES_POSSIBLE)
1468 if (shift_dst) {
1469 q--;
1470 DUK_MEMMOVE((void *) dst, (const void *) (dst + 1), 2 * len_safe);
1471 DUK_ASSERT(dst + 2 * len_safe == q);
1472 }
1473#endif
1474
1475 for (; i < src_len; i++) {
1476 x = src[i];
1477 *q++ = duk_lc_digits[x >> 4];
1478 *q++ = duk_lc_digits[x & 0x0f];
1479 }
1480
1481 return q;
1482}
DUK_INTERNAL const duk_uint16_t duk_hex_enctab[256]

References DUK_ASSERT, DUK_DD, DUK_DDPRINT, duk_hex_enctab, duk_lc_digits, and DUK_MEMMOVE.

Referenced by duk__enc_buffer_data().

◆ duk__enc_bufferobject()

DUK_LOCAL_DECL void duk__enc_bufferobject ( duk_json_enc_ctx * js_ctx,
duk_hbufferobject * h_bufobj )

Definition at line 1602 of file duktape-1.5.2/src-separate/duk_bi_json.c.

1602 {
1604
1605 if (h_bufobj->buf == NULL || !DUK_HBUFFEROBJECT_VALID_SLICE(h_bufobj)) {
1607 } else {
1608 /* Handle both full and partial slice (as long as covered). */
1609 duk__enc_buffer_data(js_ctx,
1610 (duk_uint8_t *) DUK_HBUFFEROBJECT_GET_SLICE_BASE(js_ctx->thr->heap, h_bufobj),
1611 (duk_size_t) h_bufobj->length);
1612 }
1613}
#define DUK_HBUFFEROBJECT_VALID_SLICE(h)
#define DUK_ASSERT_HBUFFEROBJECT_VALID(h)
#define DUK_HBUFFEROBJECT_GET_SLICE_BASE(heap, h)

References duk_hbufferobject::buf, DUK__EMIT_STRIDX, duk__enc_buffer_data(), DUK_ASSERT_HBUFFEROBJECT_VALID, DUK_HBUFFEROBJECT_GET_SLICE_BASE, DUK_HBUFFEROBJECT_VALID_SLICE, DUK_STRIDX_LC_NULL, duk_hthread::heap, duk_hbufferobject::length, NULL, and duk_json_enc_ctx::thr.

Referenced by duk__enc_value().

◆ duk__enc_double()

DUK_LOCAL_DECL void duk__enc_double ( duk_json_enc_ctx * js_ctx)

Definition at line 1334 of file duktape-1.5.2/src-separate/duk_bi_json.c.

1334 {
1335 duk_hthread *thr;
1336 duk_context *ctx;
1337 duk_tval *tv;
1338 duk_double_t d;
1341 duk_small_uint_t stridx;
1342 duk_small_uint_t n2s_flags;
1343 duk_hstring *h_str;
1344
1345 DUK_ASSERT(js_ctx != NULL);
1346 thr = js_ctx->thr;
1347 DUK_ASSERT(thr != NULL);
1348 ctx = (duk_context *) thr;
1349
1350 /* Caller must ensure 'tv' is indeed a double and not a fastint! */
1351 tv = DUK_GET_TVAL_NEGIDX(ctx, -1);
1353 d = DUK_TVAL_GET_DOUBLE(tv);
1354
1357 DUK_UNREF(s);
1358
1359 if (DUK_LIKELY(!(c == DUK_FP_INFINITE || c == DUK_FP_NAN))) {
1361
1362#if defined(DUK_USE_JX) || defined(DUK_USE_JC)
1363 /* Negative zero needs special handling in JX/JC because
1364 * it would otherwise serialize to '0', not '-0'.
1365 */
1366 if (DUK_UNLIKELY(c == DUK_FP_ZERO && s != 0 &&
1367 (js_ctx->flag_ext_custom_or_compatible))) {
1369 } else
1370#endif /* DUK_USE_JX || DUK_USE_JC */
1371 {
1372 n2s_flags = 0;
1373 /* [ ... number ] -> [ ... string ] */
1374 duk_numconv_stringify(ctx, 10 /*radix*/, 0 /*digits*/, n2s_flags);
1375 }
1376 h_str = duk_to_hstring(ctx, -1);
1377 DUK_ASSERT(h_str != NULL);
1378 DUK__EMIT_HSTR(js_ctx, h_str);
1379 return;
1380 }
1381
1382#if defined(DUK_USE_JX) || defined(DUK_USE_JC)
1383 if (!(js_ctx->flags & (DUK_JSON_FLAG_EXT_CUSTOM |
1385 stridx = DUK_STRIDX_LC_NULL;
1386 } else if (c == DUK_FP_NAN) {
1387 stridx = js_ctx->stridx_custom_nan;
1388 } else if (s == 0) {
1389 stridx = js_ctx->stridx_custom_posinf;
1390 } else {
1391 stridx = js_ctx->stridx_custom_neginf;
1392 }
1393#else
1394 stridx = DUK_STRIDX_LC_NULL;
1395#endif
1396 DUK__EMIT_STRIDX(js_ctx, stridx);
1397}
DUK_INTERNAL_DECL duk_hstring * duk_to_hstring(duk_context *ctx, duk_idx_t index)
DUK_INTERNAL_DECL void duk_numconv_stringify(duk_context *ctx, duk_small_int_t radix, duk_small_int_t digits, duk_small_uint_t flags)
DUK_INTERNAL_DECL void duk_push_hstring_stridx(duk_context *ctx, duk_small_int_t stridx)
#define DUK_JSON_FLAG_EXT_CUSTOM
#define DUK_TVAL_IS_DOUBLE(v)
#define DUK_GET_TVAL_NEGIDX(ctx, idx)
#define DUK_STRIDX_MINUS_ZERO
#define DUK_JSON_FLAG_EXT_COMPATIBLE
#define DUK_TVAL_GET_DOUBLE(tv)
#define DUK__EMIT_HSTR(js_ctx, h)
CURL_EXTERN CURLMcode curl_socket_t s
Definition multi.h:318

References DUK__EMIT_HSTR, DUK__EMIT_STRIDX, DUK_ASSERT, DUK_FP_INFINITE, DUK_FP_NAN, DUK_FP_ZERO, DUK_FPCLASSIFY, DUK_GET_TVAL_NEGIDX, DUK_ISFINITE, DUK_JSON_FLAG_EXT_COMPATIBLE, DUK_JSON_FLAG_EXT_CUSTOM, DUK_LIKELY, duk_numconv_stringify(), duk_push_hstring_stridx(), DUK_SIGNBIT, DUK_STRIDX_LC_NULL, DUK_STRIDX_MINUS_ZERO, duk_to_hstring(), DUK_TVAL_GET_DOUBLE, DUK_TVAL_IS_DOUBLE, DUK_UNLIKELY, DUK_UNREF, duk_json_enc_ctx::flag_ext_custom_or_compatible, duk_json_enc_ctx::flags, NULL, s, duk_json_enc_ctx::stridx_custom_nan, duk_json_enc_ctx::stridx_custom_neginf, duk_json_enc_ctx::stridx_custom_posinf, and duk_json_enc_ctx::thr.

Referenced by duk__enc_value().

◆ duk__enc_key_autoquote()

DUK_LOCAL_DECL void duk__enc_key_autoquote ( duk_json_enc_ctx * js_ctx,
duk_hstring * k )

Definition at line 1146 of file duktape-1.5.2/src-separate/duk_bi_json.c.

1146 {
1147 const duk_int8_t *p, *p_start, *p_end; /* Note: intentionally signed. */
1148 duk_size_t k_len;
1149 duk_codepoint_t cp;
1150
1151 DUK_ASSERT(k != NULL);
1152
1153 /* Accept ASCII strings which conform to identifier requirements
1154 * as being emitted without key quotes. Since we only accept ASCII
1155 * there's no need for actual decoding: 'p' is intentionally signed
1156 * so that bytes >= 0x80 extend to negative values and are rejected
1157 * as invalid identifier codepoints.
1158 */
1159
1160 if (js_ctx->flag_avoid_key_quotes) {
1161 k_len = DUK_HSTRING_GET_BYTELEN(k);
1162 p_start = (const duk_int8_t *) DUK_HSTRING_GET_DATA(k);
1163 p_end = p_start + k_len;
1164 p = p_start;
1165
1166 if (p == p_end) {
1167 /* Zero length string is not accepted without quotes */
1168 goto quote_normally;
1169 }
1170 cp = (duk_codepoint_t) (*p++);
1172 goto quote_normally;
1173 }
1174 while (p < p_end) {
1175 cp = (duk_codepoint_t) (*p++);
1177 goto quote_normally;
1178 }
1179 }
1180
1181 /* This seems faster than emitting bytes one at a time and
1182 * then potentially rewinding.
1183 */
1184 DUK__EMIT_HSTR(js_ctx, k);
1185 return;
1186 }
1187
1188 quote_normally:
1189 duk__enc_quote_string(js_ctx, k);
1190}
#define DUK_HSTRING_GET_BYTELEN(x)
DUK_LOCAL_DECL void duk__enc_quote_string(duk_json_enc_ctx *js_ctx, duk_hstring *h_str)

References DUK__EMIT_HSTR, duk__enc_quote_string(), DUK_ASSERT, DUK_HSTRING_GET_BYTELEN, DUK_HSTRING_GET_DATA, duk_unicode_is_identifier_part(), duk_unicode_is_identifier_start(), DUK_UNLIKELY, duk_json_enc_ctx::flag_avoid_key_quotes, and NULL.

Referenced by duk__enc_object().

◆ duk__enc_newline_indent()

DUK_LOCAL_DECL void duk__enc_newline_indent ( duk_json_enc_ctx * js_ctx,
duk_int_t depth )

Definition at line 1630 of file duktape-1.5.2/src-separate/duk_bi_json.c.

1630 {
1631 const duk_uint8_t *gap_data;
1632 duk_size_t gap_len;
1633 duk_size_t avail_bytes; /* bytes of indent available for copying */
1634 duk_size_t need_bytes; /* bytes of indent still needed */
1635 duk_uint8_t *p_start;
1636 duk_uint8_t *p;
1637
1638 DUK_ASSERT(js_ctx->h_gap != NULL);
1639 DUK_ASSERT(DUK_HSTRING_GET_BYTELEN(js_ctx->h_gap) > 0); /* caller guarantees */
1640
1641 DUK__EMIT_1(js_ctx, 0x0a);
1642 if (DUK_UNLIKELY(depth == 0)) {
1643 return;
1644 }
1645
1646 /* To handle deeper indents efficiently, make use of copies we've
1647 * already emitted. In effect we can emit a sequence of 1, 2, 4,
1648 * 8, etc copies, and then finish the last run. Byte counters
1649 * avoid multiply with gap_len on every loop.
1650 */
1651
1652 gap_data = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(js_ctx->h_gap);
1653 gap_len = (duk_size_t) DUK_HSTRING_GET_BYTELEN(js_ctx->h_gap);
1654 DUK_ASSERT(gap_len > 0);
1655
1656 need_bytes = gap_len * depth;
1657 p = DUK_BW_ENSURE_GETPTR(js_ctx->thr, &js_ctx->bw, need_bytes);
1658 p_start = p;
1659
1660 DUK_MEMCPY((void *) p, (const void *) gap_data, (size_t) gap_len);
1661 p += gap_len;
1662 avail_bytes = gap_len;
1663 DUK_ASSERT(need_bytes >= gap_len);
1664 need_bytes -= gap_len;
1665
1666 while (need_bytes >= avail_bytes) {
1667 DUK_MEMCPY((void *) p, (const void *) p_start, (size_t) avail_bytes);
1668 p += avail_bytes;
1669 need_bytes -= avail_bytes;
1670 avail_bytes <<= 1;
1671 }
1672
1673 DUK_ASSERT(need_bytes < avail_bytes); /* need_bytes may be zero */
1674 DUK_MEMCPY((void *) p, (const void *) p_start, (size_t) need_bytes);
1675 p += need_bytes;
1676 /*avail_bytes += need_bytes*/
1677
1678 DUK_BW_SET_PTR(js_ctx->thr, &js_ctx->bw, p);
1679}
guint depth

References duk_json_enc_ctx::bw, depth, DUK__EMIT_1, DUK_ASSERT, DUK_BW_ENSURE_GETPTR, DUK_BW_SET_PTR, DUK_HSTRING_GET_BYTELEN, DUK_HSTRING_GET_DATA, DUK_MEMCPY, DUK_UNLIKELY, duk_json_enc_ctx::h_gap, NULL, and duk_json_enc_ctx::thr.

Referenced by duk__enc_array(), and duk__enc_object().

◆ duk__enc_objarr_entry()

DUK_LOCAL_DECL void duk__enc_objarr_entry ( duk_json_enc_ctx * js_ctx,
duk_idx_t * entry_top )

Definition at line 1683 of file duktape-1.5.2/src-separate/duk_bi_json.c.

1683 {
1684 duk_context *ctx = (duk_context *) js_ctx->thr;
1685 duk_hobject *h_target;
1686 duk_uint_fast32_t i, n;
1687
1688 *entry_top = duk_get_top(ctx);
1689
1691
1692 /* Loop check using a hybrid approach: a fixed-size visited[] array
1693 * with overflow in a loop check object.
1694 */
1695
1696 h_target = duk_get_hobject(ctx, -1); /* object or array */
1697 DUK_ASSERT(h_target != NULL);
1698
1699 n = js_ctx->recursion_depth;
1702 }
1703 for (i = 0; i < n; i++) {
1704 if (DUK_UNLIKELY(js_ctx->visiting[i] == h_target)) {
1705 DUK_DD(DUK_DDPRINT("slow path loop detect"));
1707 }
1708 }
1710 js_ctx->visiting[js_ctx->recursion_depth] = h_target;
1711 } else {
1712 duk_push_sprintf(ctx, DUK_STR_FMT_PTR, (void *) h_target);
1713 duk_dup_top(ctx); /* -> [ ... voidp voidp ] */
1714 if (duk_has_prop(ctx, js_ctx->idx_loop)) {
1716 }
1717 duk_push_true(ctx); /* -> [ ... voidp true ] */
1718 duk_put_prop(ctx, js_ctx->idx_loop); /* -> [ ... ] */
1719 }
1720
1721 /* C recursion check. */
1722
1723 DUK_ASSERT(js_ctx->recursion_depth >= 0);
1724 DUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);
1725 if (js_ctx->recursion_depth >= js_ctx->recursion_limit) {
1727 }
1728 js_ctx->recursion_depth++;
1729
1730 DUK_DDD(DUK_DDDPRINT("shared entry finished: top=%ld, loop=%!T",
1731 (long) duk_get_top(ctx), (duk_tval *) duk_get_tval(ctx, js_ctx->idx_loop)));
1732}
#define DUK_JSON_ENC_LOOPARRAY
#define DUK_ERROR_TYPE(thr, msg)
#define DUK_JSON_ENC_REQSTACK
#define DUK_STR_JSONENC_RECLIMIT
DUK_EXTERNAL const char * duk_push_sprintf(duk_context *ctx, const char *fmt,...)
DUK_EXTERNAL duk_bool_t duk_has_prop(duk_context *ctx, duk_idx_t obj_index)
duk_hobject * visiting[DUK_JSON_ENC_LOOPARRAY]

References DUK_ASSERT, DUK_DD, DUK_DDD, DUK_DDDPRINT, DUK_DDPRINT, duk_dup_top(), DUK_ERROR_RANGE, DUK_ERROR_TYPE, duk_get_hobject(), duk_get_top(), duk_get_tval(), duk_has_prop(), DUK_JSON_ENC_LOOPARRAY, DUK_JSON_ENC_REQSTACK, duk_push_sprintf(), duk_push_true(), duk_put_prop(), duk_require_stack(), DUK_STR_CYCLIC_INPUT, DUK_STR_FMT_PTR, DUK_STR_JSONENC_RECLIMIT, DUK_UNLIKELY, duk_json_enc_ctx::idx_loop, NULL, duk_json_enc_ctx::recursion_depth, duk_json_enc_ctx::recursion_limit, duk_json_enc_ctx::thr, and duk_json_enc_ctx::visiting.

Referenced by duk__enc_array(), and duk__enc_object().

◆ duk__enc_objarr_exit()

DUK_LOCAL_DECL void duk__enc_objarr_exit ( duk_json_enc_ctx * js_ctx,
duk_idx_t * entry_top )

Definition at line 1735 of file duktape-1.5.2/src-separate/duk_bi_json.c.

1735 {
1736 duk_context *ctx = (duk_context *) js_ctx->thr;
1737 duk_hobject *h_target;
1738
1739 /* C recursion check. */
1740
1741 DUK_ASSERT(js_ctx->recursion_depth > 0);
1742 DUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);
1743 js_ctx->recursion_depth--;
1744
1745 /* Loop check. */
1746
1747 h_target = duk_get_hobject(ctx, *entry_top - 1); /* original target at entry_top - 1 */
1748 DUK_ASSERT(h_target != NULL);
1749
1751 /* Previous entry was inside visited[], nothing to do. */
1752 } else {
1753 duk_push_sprintf(ctx, DUK_STR_FMT_PTR, (void *) h_target);
1754 duk_del_prop(ctx, js_ctx->idx_loop); /* -> [ ... ] */
1755 }
1756
1757 /* Restore stack top after unbalanced code paths. */
1758 duk_set_top(ctx, *entry_top);
1759
1760 DUK_DDD(DUK_DDDPRINT("shared entry finished: top=%ld, loop=%!T",
1761 (long) duk_get_top(ctx), (duk_tval *) duk_get_tval(ctx, js_ctx->idx_loop)));
1762}
DUK_EXTERNAL void duk_set_top(duk_context *ctx, duk_idx_t index)

References DUK_ASSERT, DUK_DDD, DUK_DDDPRINT, duk_del_prop(), duk_get_hobject(), duk_get_top(), duk_get_tval(), DUK_JSON_ENC_LOOPARRAY, duk_push_sprintf(), duk_set_top(), DUK_STR_FMT_PTR, duk_json_enc_ctx::idx_loop, NULL, duk_json_enc_ctx::recursion_depth, duk_json_enc_ctx::recursion_limit, and duk_json_enc_ctx::thr.

Referenced by duk__enc_array(), and duk__enc_object().

◆ duk__enc_object()

DUK_LOCAL_DECL void duk__enc_object ( duk_json_enc_ctx * js_ctx)

Definition at line 1768 of file duktape-1.5.2/src-separate/duk_bi_json.c.

1768 {
1769 duk_context *ctx = (duk_context *) js_ctx->thr;
1770 duk_hstring *h_key;
1771 duk_idx_t entry_top;
1772 duk_idx_t idx_obj;
1773 duk_idx_t idx_keys;
1774 duk_bool_t emitted;
1775 duk_uarridx_t arr_len, i;
1776 duk_size_t prev_size;
1777
1778 DUK_DDD(DUK_DDDPRINT("duk__enc_object: obj=%!T", (duk_tval *) duk_get_tval(ctx, -1)));
1779
1780 duk__enc_objarr_entry(js_ctx, &entry_top);
1781
1782 idx_obj = entry_top - 1;
1783
1784 if (js_ctx->idx_proplist >= 0) {
1785 idx_keys = js_ctx->idx_proplist;
1786 } else {
1787 /* XXX: would be nice to enumerate an object at specified index */
1788 duk_dup(ctx, idx_obj);
1789 (void) duk_hobject_get_enumerated_keys(ctx, DUK_ENUM_OWN_PROPERTIES_ONLY /*flags*/); /* [ ... target ] -> [ ... target keys ] */
1790 idx_keys = duk_require_normalize_index(ctx, -1);
1791 /* leave stack unbalanced on purpose */
1792 }
1793
1794 DUK_DDD(DUK_DDDPRINT("idx_keys=%ld, h_keys=%!T",
1795 (long) idx_keys, (duk_tval *) duk_get_tval(ctx, idx_keys)));
1796
1797 /* Steps 8-10 have been merged to avoid a "partial" variable. */
1798
1799 DUK__EMIT_1(js_ctx, DUK_ASC_LCURLY);
1800
1801 /* XXX: keys is an internal object with all keys to be processed
1802 * in its (gapless) array part. Because nobody can touch the keys
1803 * object, we could iterate its array part directly (keeping in mind
1804 * that it can be reallocated).
1805 */
1806
1807 arr_len = (duk_uarridx_t) duk_get_length(ctx, idx_keys);
1808 emitted = 0;
1809 for (i = 0; i < arr_len; i++) {
1810 duk_get_prop_index(ctx, idx_keys, i); /* -> [ ... key ] */
1811
1812 DUK_DDD(DUK_DDDPRINT("object property loop: holder=%!T, key=%!T",
1813 (duk_tval *) duk_get_tval(ctx, idx_obj),
1814 (duk_tval *) duk_get_tval(ctx, -1)));
1815
1816 h_key = duk_get_hstring(ctx, -1);
1817 DUK_ASSERT(h_key != NULL);
1818
1819 prev_size = DUK_BW_GET_SIZE(js_ctx->thr, &js_ctx->bw);
1820 if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {
1822 duk__enc_key_autoquote(js_ctx, h_key);
1824 } else {
1825 duk__enc_key_autoquote(js_ctx, h_key);
1826 DUK__EMIT_1(js_ctx, DUK_ASC_COLON);
1827 }
1828
1829 /* [ ... key ] */
1830
1831 if (DUK_UNLIKELY(duk__enc_value(js_ctx, idx_obj) == 0)) {
1832 /* Value would yield 'undefined', so skip key altogether.
1833 * Side effects have already happened.
1834 */
1835 DUK_BW_SET_SIZE(js_ctx->thr, &js_ctx->bw, prev_size);
1836 } else {
1837 DUK__EMIT_1(js_ctx, DUK_ASC_COMMA);
1838 emitted = 1;
1839 }
1840
1841 /* [ ... ] */
1842 }
1843
1844 if (emitted) {
1845 DUK_ASSERT(*((duk_uint8_t *) DUK_BW_GET_PTR(js_ctx->thr, &js_ctx->bw) - 1) == DUK_ASC_COMMA);
1846 DUK__UNEMIT_1(js_ctx); /* eat trailing comma */
1847 if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {
1848 DUK_ASSERT(js_ctx->recursion_depth >= 1);
1849 duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1);
1850 }
1851 }
1852 DUK__EMIT_1(js_ctx, DUK_ASC_RCURLY);
1853
1854 duk__enc_objarr_exit(js_ctx, &entry_top);
1855
1856 DUK_ASSERT_TOP(ctx, entry_top);
1857}
DUK_EXTERNAL duk_idx_t duk_require_normalize_index(duk_context *ctx, duk_idx_t index)
#define DUK_BW_SET_SIZE(thr, bw_ctx, sz)
#define DUK_BW_GET_SIZE(thr, bw_ctx)
DUK_EXTERNAL duk_bool_t duk_get_prop_index(duk_context *ctx, duk_idx_t obj_index, duk_uarridx_t arr_index)
DUK_INTERNAL_DECL duk_ret_t duk_hobject_get_enumerated_keys(duk_context *ctx, duk_small_uint_t enum_flags)
DUK_INTERNAL_DECL duk_hstring * duk_get_hstring(duk_context *ctx, duk_idx_t index)
#define DUK__EMIT_2(js_ctx, ch1, ch2)
DUK_LOCAL_DECL void duk__enc_key_autoquote(duk_json_enc_ctx *js_ctx, duk_hstring *k)

References duk_json_enc_ctx::bw, DUK__EMIT_1, DUK__EMIT_2, duk__enc_key_autoquote(), duk__enc_newline_indent(), duk__enc_objarr_entry(), duk__enc_objarr_exit(), duk__enc_value(), DUK__UNEMIT_1, DUK_ASC_COLON, DUK_ASC_COMMA, DUK_ASC_LCURLY, DUK_ASC_RCURLY, DUK_ASC_SPACE, DUK_ASSERT, DUK_ASSERT_TOP, DUK_BW_GET_PTR, DUK_BW_GET_SIZE, DUK_BW_SET_SIZE, DUK_DDD, DUK_DDDPRINT, duk_dup(), DUK_ENUM_OWN_PROPERTIES_ONLY, duk_get_hstring(), duk_get_length(), duk_get_prop_index(), duk_get_tval(), duk_hobject_get_enumerated_keys(), duk_require_normalize_index(), DUK_UNLIKELY, duk_json_enc_ctx::h_gap, duk_json_enc_ctx::idx_proplist, NULL, duk_json_enc_ctx::recursion_depth, and duk_json_enc_ctx::thr.

Referenced by duk__enc_value().

◆ duk__enc_pointer()

DUK_LOCAL_DECL void duk__enc_pointer ( duk_json_enc_ctx * js_ctx,
void * ptr )

Definition at line 1565 of file duktape-1.5.2/src-separate/duk_bi_json.c.

1565 {
1566 char buf[64]; /* XXX: how to figure correct size? */
1567 const char *fmt;
1568
1569 DUK_ASSERT(js_ctx->flag_ext_custom || js_ctx->flag_ext_compatible); /* caller checks */
1571
1572 DUK_MEMZERO(buf, sizeof(buf));
1573
1574 /* The #ifdef clutter here needs to handle the three cases:
1575 * (1) JX+JC, (2) JX only, (3) JC only.
1576 */
1577#if defined(DUK_USE_JX) && defined(DUK_USE_JC)
1578 if (js_ctx->flag_ext_custom)
1579#endif
1580#if defined(DUK_USE_JX)
1581 {
1582 fmt = ptr ? "(%p)" : "(null)";
1583 }
1584#endif
1585#if defined(DUK_USE_JX) && defined(DUK_USE_JC)
1586 else
1587#endif
1588#if defined(DUK_USE_JC)
1589 {
1591 fmt = ptr ? "{\"_ptr\":\"%p\"}" : "{\"_ptr\":\"null\"}";
1592 }
1593#endif
1594
1595 /* When ptr == NULL, the format argument is unused. */
1596 DUK_SNPRINTF(buf, sizeof(buf) - 1, fmt, ptr); /* must not truncate */
1597 DUK__EMIT_CSTR(js_ctx, buf);
1598}
#define DUK_MEMZERO(p, n)
#define DUK__EMIT_CSTR(js_ctx, p)

References DUK__EMIT_CSTR, DUK_ASSERT, DUK_MEMZERO, DUK_SNPRINTF, duk_json_enc_ctx::flag_ext_compatible, duk_json_enc_ctx::flag_ext_custom, and duk_json_enc_ctx::flag_ext_custom_or_compatible.

Referenced by duk__enc_value().

◆ duk__enc_quote_string()

DUK_LOCAL_DECL void duk__enc_quote_string ( duk_json_enc_ctx * js_ctx,
duk_hstring * h_str )

Definition at line 1197 of file duktape-1.5.2/src-separate/duk_bi_json.c.

1197 {
1198 duk_hthread *thr = js_ctx->thr;
1199 const duk_uint8_t *p, *p_start, *p_end, *p_now, *p_tmp;
1200 duk_uint8_t *q;
1201 duk_ucodepoint_t cp; /* typed for duk_unicode_decode_xutf8() */
1202
1203 DUK_DDD(DUK_DDDPRINT("duk__enc_quote_string: h_str=%!O", (duk_heaphdr *) h_str));
1204
1205 DUK_ASSERT(h_str != NULL);
1206 p_start = DUK_HSTRING_GET_DATA(h_str);
1207 p_end = p_start + DUK_HSTRING_GET_BYTELEN(h_str);
1208 p = p_start;
1209
1211
1212 /* Encode string in small chunks, estimating the maximum expansion so that
1213 * there's no need to ensure space while processing the chunk.
1214 */
1215
1216 while (p < p_end) {
1217 duk_size_t left, now, space;
1218
1219 left = (duk_size_t) (p_end - p);
1222
1223 /* Maximum expansion per input byte is 6:
1224 * - invalid UTF-8 byte causes "\uXXXX" to be emitted (6/1 = 6).
1225 * - 2-byte UTF-8 encodes as "\uXXXX" (6/2 = 3).
1226 * - 4-byte UTF-8 encodes as "\Uxxxxxxxx" (10/4 = 2.5).
1227 */
1228 space = now * 6;
1229 q = DUK_BW_ENSURE_GETPTR(thr, &js_ctx->bw, space);
1230
1231 p_now = p + now;
1232
1233 while (p < p_now) {
1234#if defined(DUK_USE_JSON_QUOTESTRING_FASTPATH)
1235 duk_uint8_t b;
1236
1237 b = duk__json_quotestr_lookup[*p++];
1238 if (DUK_LIKELY(b < 0x80)) {
1239 /* Most input bytes go through here. */
1240 *q++ = b;
1241 } else if (b >= 0xa0) {
1242 *q++ = DUK_ASC_BACKSLASH;
1243 *q++ = (duk_uint8_t) (b - 0x80);
1244 } else if (b == 0x80) {
1245 cp = (duk_ucodepoint_t) (*(p - 1));
1246 q = duk__emit_esc_auto_fast(js_ctx, cp, q);
1247 } else if (b == 0x7f && js_ctx->flag_ascii_only) {
1248 /* 0x7F is special */
1249 DUK_ASSERT(b == 0x81);
1250 cp = (duk_ucodepoint_t) 0x7f;
1251 q = duk__emit_esc_auto_fast(js_ctx, cp, q);
1252 } else {
1253 DUK_ASSERT(b == 0x81);
1254 p--;
1255
1256 /* slow path is shared */
1257#else /* DUK_USE_JSON_QUOTESTRING_FASTPATH */
1258 cp = *p;
1259
1260 if (DUK_LIKELY(cp <= 0x7f)) {
1261 /* ascii fast path: avoid decoding utf-8 */
1262 p++;
1263 if (cp == 0x22 || cp == 0x5c) {
1264 /* double quote or backslash */
1265 *q++ = DUK_ASC_BACKSLASH;
1266 *q++ = (duk_uint8_t) cp;
1267 } else if (cp < 0x20) {
1268 duk_uint_fast8_t esc_char;
1269
1270 /* This approach is a bit shorter than a straight
1271 * if-else-ladder and also a bit faster.
1272 */
1273 if (cp < (sizeof(duk__json_quotestr_esc) / sizeof(duk_uint8_t)) &&
1274 (esc_char = duk__json_quotestr_esc[cp]) != 0) {
1275 *q++ = DUK_ASC_BACKSLASH;
1276 *q++ = (duk_uint8_t) esc_char;
1277 } else {
1278 q = duk__emit_esc_auto_fast(js_ctx, cp, q);
1279 }
1280 } else if (cp == 0x7f && js_ctx->flag_ascii_only) {
1281 q = duk__emit_esc_auto_fast(js_ctx, cp, q);
1282 } else {
1283 /* any other printable -> as is */
1284 *q++ = (duk_uint8_t) cp;
1285 }
1286 } else {
1287 /* slow path is shared */
1288#endif /* DUK_USE_JSON_QUOTESTRING_FASTPATH */
1289
1290 /* slow path decode */
1291
1292 /* If XUTF-8 decoding fails, treat the offending byte as a codepoint directly
1293 * and go forward one byte. This is of course very lossy, but allows some kind
1294 * of output to be produced even for internal strings which don't conform to
1295 * XUTF-8. All standard Ecmascript strings are always CESU-8, so this behavior
1296 * does not violate the Ecmascript specification. The behavior is applied to
1297 * all modes, including Ecmascript standard JSON. Because the current XUTF-8
1298 * decoding is not very strict, this behavior only really affects initial bytes
1299 * and truncated codepoints.
1300 *
1301 * Another alternative would be to scan forwards to start of next codepoint
1302 * (or end of input) and emit just one replacement codepoint.
1303 */
1304
1305 p_tmp = p;
1306 if (!duk_unicode_decode_xutf8(thr, &p, p_start, p_end, &cp)) {
1307 /* Decode failed. */
1308 cp = *p_tmp;
1309 p = p_tmp + 1;
1310 }
1311
1312#ifdef DUK_USE_NONSTD_JSON_ESC_U2028_U2029
1313 if (js_ctx->flag_ascii_only || cp == 0x2028 || cp == 0x2029) {
1314#else
1315 if (js_ctx->flag_ascii_only) {
1316#endif
1317 q = duk__emit_esc_auto_fast(js_ctx, cp, q);
1318 } else {
1319 /* as is */
1320 DUK_RAW_WRITE_XUTF8(q, cp);
1321 }
1322 }
1323 }
1324
1325 DUK_BW_SET_PTR(thr, &js_ctx->bw, q);
1326 }
1327
1329}
duk_uint8_t duk_uint_fast8_t
DUK_INTERNAL_DECL duk_small_int_t duk_unicode_decode_xutf8(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end, duk_ucodepoint_t *out_cp)
DUK_LOCAL const duk_uint8_t duk__json_quotestr_lookup[256]
DUK_LOCAL_DECL duk_uint8_t * duk__emit_esc_auto_fast(duk_json_enc_ctx *js_ctx, duk_uint_fast32_t cp, duk_uint8_t *q)
lu_byte left

References duk_json_enc_ctx::bw, DUK__EMIT_1, duk__emit_esc_auto_fast(), DUK__JSON_ENCSTR_CHUNKSIZE, duk__json_quotestr_lookup, DUK_ASC_BACKSLASH, DUK_ASC_DOUBLEQUOTE, DUK_ASSERT, DUK_BW_ENSURE_GETPTR, DUK_BW_SET_PTR, DUK_DDD, DUK_DDDPRINT, DUK_HSTRING_GET_BYTELEN, DUK_HSTRING_GET_DATA, DUK_LIKELY, DUK_RAW_WRITE_XUTF8, duk_unicode_decode_xutf8(), duk_json_enc_ctx::flag_ascii_only, left, NULL, and duk_json_enc_ctx::thr.

Referenced by duk__enc_key_autoquote(), and duk__enc_value().

◆ duk__enc_value()

DUK_LOCAL_DECL duk_bool_t duk__enc_value ( duk_json_enc_ctx * js_ctx,
duk_idx_t idx_holder )

Definition at line 1931 of file duktape-1.5.2/src-separate/duk_bi_json.c.

1931 {
1932 duk_context *ctx = (duk_context *) js_ctx->thr;
1933 duk_hthread *thr = (duk_hthread *) ctx;
1934 duk_hobject *h_tmp;
1935 duk_tval *tv;
1936 duk_tval *tv_holder;
1937 duk_tval *tv_key;
1939
1940 DUK_DDD(DUK_DDDPRINT("duk__enc_value: idx_holder=%ld, holder=%!T, key=%!T",
1941 (long) idx_holder, (duk_tval *) duk_get_tval(ctx, idx_holder),
1942 (duk_tval *) duk_get_tval(ctx, -1)));
1943
1944 DUK_UNREF(thr);
1945
1946 tv_holder = DUK_GET_TVAL_POSIDX(ctx, idx_holder);
1947 DUK_ASSERT(DUK_TVAL_IS_OBJECT(tv_holder));
1948 tv_key = DUK_GET_TVAL_NEGIDX(ctx, -1);
1950 (void) duk_hobject_getprop(thr, tv_holder, tv_key);
1951
1952 /* -> [ ... key val ] */
1953
1954 DUK_DDD(DUK_DDDPRINT("value=%!T", (duk_tval *) duk_get_tval(ctx, -1)));
1955
1956 h_tmp = duk_get_hobject_or_lfunc_coerce(ctx, -1);
1957 if (h_tmp != NULL) {
1959 h_tmp = duk_get_hobject_or_lfunc_coerce(ctx, -1); /* toJSON() can also be a lightfunc */
1960
1961 if (h_tmp != NULL && DUK_HOBJECT_IS_CALLABLE(h_tmp)) {
1962 DUK_DDD(DUK_DDDPRINT("value is object, has callable toJSON() -> call it"));
1963 /* XXX: duk_dup_unvalidated(ctx, -2) etc. */
1964 duk_dup(ctx, -2); /* -> [ ... key val toJSON val ] */
1965 duk_dup(ctx, -4); /* -> [ ... key val toJSON val key ] */
1966 duk_call_method(ctx, 1); /* -> [ ... key val val' ] */
1967 duk_remove(ctx, -2); /* -> [ ... key val' ] */
1968 } else {
1969 duk_pop(ctx); /* -> [ ... key val ] */
1970 }
1971 }
1972
1973 /* [ ... key val ] */
1974
1975 DUK_DDD(DUK_DDDPRINT("value=%!T", (duk_tval *) duk_get_tval(ctx, -1)));
1976
1977 if (js_ctx->h_replacer) {
1978 /* XXX: Here a "slice copy" would be useful. */
1979 DUK_DDD(DUK_DDDPRINT("replacer is set, call replacer"));
1980 duk_push_hobject(ctx, js_ctx->h_replacer); /* -> [ ... key val replacer ] */
1981 duk_dup(ctx, idx_holder); /* -> [ ... key val replacer holder ] */
1982 duk_dup(ctx, -4); /* -> [ ... key val replacer holder key ] */
1983 duk_dup(ctx, -4); /* -> [ ... key val replacer holder key val ] */
1984 duk_call_method(ctx, 2); /* -> [ ... key val val' ] */
1985 duk_remove(ctx, -2); /* -> [ ... key val' ] */
1986 }
1987
1988 /* [ ... key val ] */
1989
1990 DUK_DDD(DUK_DDDPRINT("value=%!T", (duk_tval *) duk_get_tval(ctx, -1)));
1991
1992 tv = DUK_GET_TVAL_NEGIDX(ctx, -1);
1993 if (DUK_TVAL_IS_OBJECT(tv)) {
1994 duk_hobject *h;
1995
1996 h = DUK_TVAL_GET_OBJECT(tv);
1997 DUK_ASSERT(h != NULL);
1998
2000#if defined(DUK_USE_JX) || defined(DUK_USE_JC)
2001 duk_hbufferobject *h_bufobj;
2002 h_bufobj = (duk_hbufferobject *) h;
2004
2005 /* Conceptually we'd extract the plain underlying buffer
2006 * or its slice and then do a type mask check below to
2007 * see if we should reject it. Do the mask check here
2008 * instead to avoid making a copy of the buffer slice.
2009 */
2010
2012 DUK_DDD(DUK_DDDPRINT("-> bufferobject (-> plain buffer) will result in undefined (type mask check)"));
2013 goto pop2_undef;
2014 }
2015 DUK_DDD(DUK_DDDPRINT("-> bufferobject won't result in undefined, encode directly"));
2016 duk__enc_bufferobject(js_ctx, h_bufobj);
2017 goto pop2_emitted;
2018#else
2019 DUK_DDD(DUK_DDDPRINT("no JX/JC support, bufferobject/buffer will always result in undefined"));
2020 goto pop2_undef;
2021#endif
2022 } else {
2024 switch ((int) c) {
2026 DUK_DDD(DUK_DDDPRINT("value is a Number object -> coerce with ToNumber()"));
2027 duk_to_number(ctx, -1);
2028 /* The coercion potentially invokes user .valueOf() and .toString()
2029 * but can't result in a function value because [[DefaultValue]] would
2030 * reject such a result: test-dev-json-stringify-coercion-1.js.
2031 */
2032 DUK_ASSERT(!duk_is_callable(ctx, -1));
2033 break;
2034 }
2036 DUK_DDD(DUK_DDDPRINT("value is a String object -> coerce with ToString()"));
2037 duk_to_string(ctx, -1);
2038 /* Same coercion behavior as for Number. */
2039 DUK_ASSERT(!duk_is_callable(ctx, -1));
2040 break;
2041 }
2042#if defined(DUK_USE_JX) || defined(DUK_USE_JC)
2044#endif
2046 DUK_DDD(DUK_DDDPRINT("value is a Boolean/Buffer/Pointer object -> get internal value"));
2048 duk_remove(ctx, -2);
2049 break;
2050 }
2051 default: {
2052 /* Normal object which doesn't get automatically coerced to a
2053 * primitive value. Functions are checked for specially. The
2054 * primitive value coercions for Number, String, Pointer, and
2055 * Boolean can't result in functions so suffices to check here.
2056 */
2057 DUK_ASSERT(h != NULL);
2058 if (DUK_HOBJECT_IS_CALLABLE(h)) {
2059#if defined(DUK_USE_JX) || defined(DUK_USE_JC)
2060 if (js_ctx->flags & (DUK_JSON_FLAG_EXT_CUSTOM |
2062 /* We only get here when doing non-standard JSON encoding */
2063 DUK_DDD(DUK_DDDPRINT("-> function allowed, serialize to custom format"));
2066 goto pop2_emitted;
2067 } else {
2068 DUK_DDD(DUK_DDDPRINT("-> will result in undefined (function)"));
2069 goto pop2_undef;
2070 }
2071#else /* DUK_USE_JX || DUK_USE_JC */
2072 DUK_DDD(DUK_DDDPRINT("-> will result in undefined (function)"));
2073 goto pop2_undef;
2074#endif /* DUK_USE_JX || DUK_USE_JC */
2075 }
2076 }
2077 } /* end switch */
2078 }
2079 }
2080
2081 /* [ ... key val ] */
2082
2083 DUK_DDD(DUK_DDDPRINT("value=%!T", (duk_tval *) duk_get_tval(ctx, -1)));
2084
2085 if (duk_check_type_mask(ctx, -1, js_ctx->mask_for_undefined)) {
2086 /* will result in undefined */
2087 DUK_DDD(DUK_DDDPRINT("-> will result in undefined (type mask check)"));
2088 goto pop2_undef;
2089 }
2090 tv = DUK_GET_TVAL_NEGIDX(ctx, -1);
2091
2092 switch (DUK_TVAL_GET_TAG(tv)) {
2093#if defined(DUK_USE_JX) || defined(DUK_USE_JC)
2094 /* When JX/JC not in use, the type mask above will avoid this case if needed. */
2095 case DUK_TAG_UNDEFINED: {
2097 break;
2098 }
2099#endif
2100 case DUK_TAG_NULL: {
2102 break;
2103 }
2104 case DUK_TAG_BOOLEAN: {
2107 break;
2108 }
2109#if defined(DUK_USE_JX) || defined(DUK_USE_JC)
2110 /* When JX/JC not in use, the type mask above will avoid this case if needed. */
2111 case DUK_TAG_POINTER: {
2113 break;
2114 }
2115#endif /* DUK_USE_JX || DUK_USE_JC */
2116 case DUK_TAG_STRING: {
2118 DUK_ASSERT(h != NULL);
2119
2120 duk__enc_quote_string(js_ctx, h);
2121 break;
2122 }
2123 case DUK_TAG_OBJECT: {
2125 DUK_ASSERT(h != NULL);
2126
2127 /* Function values are handled completely above (including
2128 * coercion results):
2129 */
2131
2133 duk__enc_array(js_ctx);
2134 } else {
2135 duk__enc_object(js_ctx);
2136 }
2137 break;
2138 }
2139#if defined(DUK_USE_JX) || defined(DUK_USE_JC)
2140 /* When JX/JC not in use, the type mask above will avoid this case if needed. */
2141 case DUK_TAG_BUFFER: {
2143 break;
2144 }
2145#endif /* DUK_USE_JX || DUK_USE_JC */
2146 case DUK_TAG_LIGHTFUNC: {
2147#if defined(DUK_USE_JX) || defined(DUK_USE_JC)
2148 /* We only get here when doing non-standard JSON encoding */
2151#else
2152 /* Standard JSON omits functions */
2154#endif
2155 break;
2156 }
2157#if defined(DUK_USE_FASTINT)
2158 case DUK_TAG_FASTINT:
2159 /* Number serialization has a significant impact relative to
2160 * other fast path code, so careful fast path for fastints.
2161 */
2162 duk__enc_fastint_tval(js_ctx, tv);
2163 break;
2164#endif
2165 default: {
2166 /* number */
2169 /* XXX: A fast path for usual integers would be useful when
2170 * fastint support is not enabled.
2171 */
2172 duk__enc_double(js_ctx);
2173 break;
2174 }
2175 }
2176
2177 pop2_emitted:
2178 duk_pop_2(ctx); /* [ ... key val ] -> [ ... ] */
2179 return 1; /* emitted */
2180
2181 pop2_undef:
2182 duk_pop_2(ctx); /* [ ... key val ] -> [ ... ] */
2183 return 0; /* not emitted */
2184}
#define DUK_HOBJECT_CLASS_BOOLEAN
DUK_EXTERNAL void duk_pop_2(duk_context *ctx)
DUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx(duk_context *ctx, duk_idx_t obj_index, duk_small_int_t stridx)
#define DUK_HOBJECT_CLASS_POINTER
DUK_EXTERNAL duk_bool_t duk_check_type_mask(duk_context *ctx, duk_idx_t index, duk_uint_t mask)
#define DUK_TVAL_GET_BUFFER(tv)
#define DUK_TVAL_GET_TAG(tv)
DUK_EXTERNAL void duk_remove(duk_context *ctx, duk_idx_t index)
#define DUK_TVAL_IS_UNUSED(tv)
DUK_INTERNAL_DECL duk_hobject * duk_get_hobject_or_lfunc_coerce(duk_context *ctx, duk_idx_t index)
#define DUK_HOBJECT_IS_CALLABLE(h)
DUK_EXTERNAL duk_double_t duk_to_number(duk_context *ctx, duk_idx_t index)
#define DUK_TVAL_GET_STRING(tv)
DUK_INTERNAL_DECL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key)
#define DUK_HOBJECT_IS_BUFFEROBJECT(h)
#define DUK_TVAL_GET_POINTER(tv)
#define DUK_TVAL_GET_BOOLEAN(tv)
#define DUK_GET_TVAL_POSIDX(ctx, idx)
DUK_INTERNAL_DECL void duk_push_hobject(duk_context *ctx, duk_hobject *h)
#define DUK_TYPE_MASK_BUFFER
#define duk_is_callable(ctx, index)
DUK_LOCAL_DECL void duk__enc_array(duk_json_enc_ctx *js_ctx)
DUK_LOCAL_DECL void duk__enc_buffer(duk_json_enc_ctx *js_ctx, duk_hbuffer *h)
DUK_LOCAL_DECL void duk__enc_bufferobject(duk_json_enc_ctx *js_ctx, duk_hbufferobject *h_bufobj)
DUK_LOCAL_DECL void duk__enc_pointer(duk_json_enc_ctx *js_ctx, void *ptr)
DUK_LOCAL_DECL void duk__enc_double(duk_json_enc_ctx *js_ctx)
DUK_LOCAL_DECL void duk__enc_object(duk_json_enc_ctx *js_ctx)

References DUK__EMIT_STRIDX, duk__enc_array(), duk__enc_buffer(), duk__enc_bufferobject(), duk__enc_double(), duk__enc_object(), duk__enc_pointer(), duk__enc_quote_string(), DUK_ASSERT, DUK_ASSERT_HBUFFEROBJECT_VALID, duk_call_method(), duk_check_type_mask(), DUK_DDD, DUK_DDDPRINT, duk_dup(), duk_get_hobject_or_lfunc_coerce(), duk_get_prop_stridx(), duk_get_tval(), DUK_GET_TVAL_NEGIDX, DUK_GET_TVAL_POSIDX, DUK_HOBJECT_CLASS_ARRAY, DUK_HOBJECT_CLASS_BOOLEAN, DUK_HOBJECT_CLASS_NUMBER, DUK_HOBJECT_CLASS_POINTER, DUK_HOBJECT_CLASS_STRING, DUK_HOBJECT_GET_CLASS_NUMBER, duk_hobject_getprop(), DUK_HOBJECT_IS_BUFFEROBJECT, DUK_HOBJECT_IS_CALLABLE, duk_is_callable, DUK_JSON_FLAG_EXT_COMPATIBLE, DUK_JSON_FLAG_EXT_CUSTOM, duk_pop(), duk_pop_2(), duk_push_hobject(), duk_remove(), DUK_STRIDX_FALSE, DUK_STRIDX_INT_VALUE, DUK_STRIDX_LC_NULL, DUK_STRIDX_TO_JSON, DUK_STRIDX_TRUE, DUK_TAG_BOOLEAN, DUK_TAG_BUFFER, DUK_TAG_LIGHTFUNC, DUK_TAG_NULL, DUK_TAG_OBJECT, DUK_TAG_POINTER, DUK_TAG_STRING, DUK_TAG_UNDEFINED, duk_to_number(), duk_to_string(), DUK_TVAL_GET_BOOLEAN, DUK_TVAL_GET_BUFFER, DUK_TVAL_GET_OBJECT, DUK_TVAL_GET_POINTER, DUK_TVAL_GET_STRING, DUK_TVAL_GET_TAG, DUK_TVAL_IS_NUMBER, DUK_TVAL_IS_OBJECT, DUK_TVAL_IS_STRING, DUK_TVAL_IS_UNUSED, DUK_TYPE_MASK_BUFFER, DUK_UNREACHABLE, DUK_UNREF, duk_json_enc_ctx::flag_ext_compatible, duk_json_enc_ctx::flag_ext_custom, duk_json_enc_ctx::flags, duk_json_enc_ctx::h_replacer, duk_json_enc_ctx::mask_for_undefined, NULL, duk_json_enc_ctx::stridx_custom_function, duk_json_enc_ctx::stridx_custom_undefined, and duk_json_enc_ctx::thr.

Referenced by duk__enc_array(), duk__enc_object(), and duk_bi_json_stringify_helper().

◆ duk__unemit_1()

DUK_LOCAL_DECL void duk__unemit_1 ( duk_json_enc_ctx * js_ctx)

Definition at line 1082 of file duktape-1.5.2/src-separate/duk_bi_json.c.

1082 {
1083 DUK_ASSERT(DUK_BW_GET_SIZE(js_ctx->thr, &js_ctx->bw) >= 1);
1084 DUK_BW_ADD_PTR(js_ctx->thr, &js_ctx->bw, -1);
1085}
#define DUK_BW_ADD_PTR(thr, bw_ctx, delta)

References duk_json_enc_ctx::bw, DUK_ASSERT, DUK_BW_ADD_PTR, DUK_BW_GET_SIZE, and duk_json_enc_ctx::thr.

◆ duk_bi_json_object_parse()

DUK_INTERNAL duk_ret_t duk_bi_json_object_parse ( duk_context * ctx)

Definition at line 3122 of file duktape-1.5.2/src-separate/duk_bi_json.c.

3122 {
3124 0 /*idx_value*/,
3125 1 /*idx_replacer*/,
3126 0 /*flags*/);
3127 return 1;
3128}
DUK_INTERNAL void duk_bi_json_parse_helper(duk_context *ctx, duk_idx_t idx_value, duk_idx_t idx_reviver, duk_small_uint_t flags)

References duk_bi_json_parse_helper().

◆ duk_bi_json_object_stringify()

DUK_INTERNAL duk_ret_t duk_bi_json_object_stringify ( duk_context * ctx)

Definition at line 3130 of file duktape-1.5.2/src-separate/duk_bi_json.c.

3130 {
3132 0 /*idx_value*/,
3133 1 /*idx_replacer*/,
3134 2 /*idx_space*/,
3135 0 /*flags*/);
3136 return 1;
3137}
DUK_INTERNAL void duk_bi_json_stringify_helper(duk_context *ctx, duk_idx_t idx_value, duk_idx_t idx_replacer, duk_idx_t idx_space, duk_small_uint_t flags)

References duk_bi_json_stringify_helper().

◆ duk_bi_json_parse_helper()

DUK_INTERNAL void duk_bi_json_parse_helper ( duk_context * ctx,
duk_idx_t idx_value,
duk_idx_t idx_reviver,
duk_small_uint_t flags )

Definition at line 2682 of file duktape-1.5.2/src-separate/duk_bi_json.c.

2685 {
2686 duk_hthread *thr = (duk_hthread *) ctx;
2687 duk_json_dec_ctx js_ctx_alloc;
2688 duk_json_dec_ctx *js_ctx = &js_ctx_alloc;
2689 duk_hstring *h_text;
2690#ifdef DUK_USE_ASSERTIONS
2691 duk_idx_t entry_top = duk_get_top(ctx);
2692#endif
2693
2694 /* negative top-relative indices not allowed now */
2695 DUK_ASSERT(idx_value == DUK_INVALID_INDEX || idx_value >= 0);
2696 DUK_ASSERT(idx_reviver == DUK_INVALID_INDEX || idx_reviver >= 0);
2697
2698 DUK_DDD(DUK_DDDPRINT("JSON parse start: text=%!T, reviver=%!T, flags=0x%08lx, stack_top=%ld",
2699 (duk_tval *) duk_get_tval(ctx, idx_value),
2700 (duk_tval *) duk_get_tval(ctx, idx_reviver),
2701 (unsigned long) flags,
2702 (long) duk_get_top(ctx)));
2703
2704 DUK_MEMZERO(&js_ctx_alloc, sizeof(js_ctx_alloc));
2705 js_ctx->thr = thr;
2706#ifdef DUK_USE_EXPLICIT_NULL_INIT
2707 /* nothing now */
2708#endif
2710 DUK_ASSERT(js_ctx->recursion_depth == 0);
2711
2712 /* Flag handling currently assumes that flags are consistent. This is OK
2713 * because the call sites are now strictly controlled.
2714 */
2715
2716 js_ctx->flags = flags;
2717#if defined(DUK_USE_JX)
2718 js_ctx->flag_ext_custom = flags & DUK_JSON_FLAG_EXT_CUSTOM;
2719#endif
2720#if defined(DUK_USE_JC)
2722#endif
2723#if defined(DUK_USE_JX) || defined(DUK_USE_JC)
2725#endif
2726
2727 h_text = duk_to_hstring(ctx, idx_value); /* coerce in-place */
2728 DUK_ASSERT(h_text != NULL);
2729
2730 /* JSON parsing code is allowed to read [p_start,p_end]: p_end is
2731 * valid and points to the string NUL terminator (which is always
2732 * guaranteed for duk_hstrings.
2733 */
2734 js_ctx->p_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_text);
2735 js_ctx->p = js_ctx->p_start;
2736 js_ctx->p_end = ((const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_text)) +
2738 DUK_ASSERT(*(js_ctx->p_end) == 0x00);
2739
2740 duk__dec_value(js_ctx); /* -> [ ... value ] */
2741
2742 /* Trailing whitespace has been eaten by duk__dec_value(), so if
2743 * we're not at end of input here, it's a SyntaxError.
2744 */
2745
2746 if (js_ctx->p != js_ctx->p_end) {
2747 duk__dec_syntax_error(js_ctx);
2748 }
2749
2750 if (duk_is_callable(ctx, idx_reviver)) {
2751 DUK_DDD(DUK_DDDPRINT("applying reviver: %!T",
2752 (duk_tval *) duk_get_tval(ctx, idx_reviver)));
2753
2754 js_ctx->idx_reviver = idx_reviver;
2755
2756 duk_push_object(ctx);
2757 duk_dup(ctx, -2); /* -> [ ... val root val ] */
2758 duk_put_prop_stridx(ctx, -2, DUK_STRIDX_EMPTY_STRING); /* default attrs ok */
2759 duk_push_hstring_stridx(ctx, DUK_STRIDX_EMPTY_STRING); /* -> [ ... val root "" ] */
2760
2761 DUK_DDD(DUK_DDDPRINT("start reviver walk, root=%!T, name=%!T",
2762 (duk_tval *) duk_get_tval(ctx, -2),
2763 (duk_tval *) duk_get_tval(ctx, -1)));
2764
2765 duk__dec_reviver_walk(js_ctx); /* [ ... val root "" ] -> [ ... val val' ] */
2766 duk_remove(ctx, -2); /* -> [ ... val' ] */
2767 } else {
2768 DUK_DDD(DUK_DDDPRINT("reviver does not exist or is not callable: %!T",
2769 (duk_tval *) duk_get_tval(ctx, idx_reviver)));
2770 }
2771
2772 /* Final result is at stack top. */
2773
2774 DUK_DDD(DUK_DDDPRINT("JSON parse end: text=%!T, reviver=%!T, flags=0x%08lx, result=%!T, stack_top=%ld",
2775 (duk_tval *) duk_get_tval(ctx, idx_value),
2776 (duk_tval *) duk_get_tval(ctx, idx_reviver),
2777 (unsigned long) flags,
2778 (duk_tval *) duk_get_tval(ctx, -1),
2779 (long) duk_get_top(ctx)));
2780
2781 DUK_ASSERT(duk_get_top(ctx) == entry_top + 1);
2782}
DUK_INTERNAL_DECL duk_bool_t duk_put_prop_stridx(duk_context *ctx, duk_idx_t obj_index, duk_small_int_t stridx)
#define DUK_STRIDX_EMPTY_STRING

References duk__dec_reviver_walk(), duk__dec_syntax_error(), duk__dec_value(), DUK_ASSERT, DUK_DDD, DUK_DDDPRINT, duk_dup(), duk_get_top(), duk_get_tval(), DUK_HSTRING_GET_BYTELEN, DUK_HSTRING_GET_DATA, DUK_INVALID_INDEX, duk_is_callable, DUK_JSON_FLAG_EXT_COMPATIBLE, DUK_JSON_FLAG_EXT_CUSTOM, DUK_MEMZERO, duk_push_hstring_stridx(), duk_push_object(), duk_put_prop_stridx(), duk_remove(), DUK_STRIDX_EMPTY_STRING, duk_to_hstring(), DUK_USE_JSON_DEC_RECLIMIT, duk_json_dec_ctx::flag_ext_compatible, duk_json_dec_ctx::flag_ext_custom, duk_json_dec_ctx::flag_ext_custom_or_compatible, duk_json_dec_ctx::flags, duk_json_dec_ctx::idx_reviver, NULL, duk_json_dec_ctx::p, duk_json_dec_ctx::p_end, duk_json_dec_ctx::p_start, duk_json_dec_ctx::recursion_depth, duk_json_dec_ctx::recursion_limit, and duk_json_dec_ctx::thr.

Referenced by duk_bi_json_object_parse().

◆ duk_bi_json_stringify_helper()

DUK_INTERNAL void duk_bi_json_stringify_helper ( duk_context * ctx,
duk_idx_t idx_value,
duk_idx_t idx_replacer,
duk_idx_t idx_space,
duk_small_uint_t flags )

Definition at line 2785 of file duktape-1.5.2/src-separate/duk_bi_json.c.

2789 {
2790 duk_hthread *thr = (duk_hthread *) ctx;
2791 duk_json_enc_ctx js_ctx_alloc;
2792 duk_json_enc_ctx *js_ctx = &js_ctx_alloc;
2793 duk_hobject *h;
2794 duk_idx_t idx_holder;
2795 duk_idx_t entry_top;
2796
2797 /* negative top-relative indices not allowed now */
2798 DUK_ASSERT(idx_value == DUK_INVALID_INDEX || idx_value >= 0);
2799 DUK_ASSERT(idx_replacer == DUK_INVALID_INDEX || idx_replacer >= 0);
2800 DUK_ASSERT(idx_space == DUK_INVALID_INDEX || idx_space >= 0);
2801
2802 DUK_DDD(DUK_DDDPRINT("JSON stringify start: value=%!T, replacer=%!T, space=%!T, flags=0x%08lx, stack_top=%ld",
2803 (duk_tval *) duk_get_tval(ctx, idx_value),
2804 (duk_tval *) duk_get_tval(ctx, idx_replacer),
2805 (duk_tval *) duk_get_tval(ctx, idx_space),
2806 (unsigned long) flags,
2807 (long) duk_get_top(ctx)));
2808
2809 entry_top = duk_get_top(ctx);
2810
2811 /*
2812 * Context init
2813 */
2814
2815 DUK_MEMZERO(&js_ctx_alloc, sizeof(js_ctx_alloc));
2816 js_ctx->thr = thr;
2817#ifdef DUK_USE_EXPLICIT_NULL_INIT
2818 js_ctx->h_replacer = NULL;
2819 js_ctx->h_gap = NULL;
2820#endif
2821 js_ctx->idx_proplist = -1;
2822
2823 /* Flag handling currently assumes that flags are consistent. This is OK
2824 * because the call sites are now strictly controlled.
2825 */
2826
2827 js_ctx->flags = flags;
2828 js_ctx->flag_ascii_only = flags & DUK_JSON_FLAG_ASCII_ONLY;
2830#ifdef DUK_USE_JX
2831 js_ctx->flag_ext_custom = flags & DUK_JSON_FLAG_EXT_CUSTOM;
2832#endif
2833#ifdef DUK_USE_JC
2835#endif
2836#if defined(DUK_USE_JX) || defined(DUK_USE_JC)
2838#endif
2839
2840 /* The #ifdef clutter here handles the JX/JC enable/disable
2841 * combinations properly.
2842 */
2843#if defined(DUK_USE_JX) || defined(DUK_USE_JC)
2844 js_ctx->stridx_custom_undefined = DUK_STRIDX_LC_NULL; /* standard JSON; array gaps */
2845#if defined(DUK_USE_JX)
2846 if (flags & DUK_JSON_FLAG_EXT_CUSTOM) {
2851 js_ctx->stridx_custom_function =
2855 }
2856#endif /* DUK_USE_JX */
2857#if defined(DUK_USE_JX) && defined(DUK_USE_JC)
2858 else
2859#endif /* DUK_USE_JX && DUK_USE_JC */
2860#if defined(DUK_USE_JC)
2861 if (js_ctx->flags & DUK_JSON_FLAG_EXT_COMPATIBLE) {
2867 }
2868#endif /* DUK_USE_JC */
2869#endif /* DUK_USE_JX || DUK_USE_JC */
2870
2871#if defined(DUK_USE_JX) || defined(DUK_USE_JC)
2872 if (js_ctx->flags & (DUK_JSON_FLAG_EXT_CUSTOM |
2874 DUK_ASSERT(js_ctx->mask_for_undefined == 0); /* already zero */
2875 }
2876 else
2877#endif /* DUK_USE_JX || DUK_USE_JC */
2878 {
2883 }
2884
2886
2887 js_ctx->idx_loop = duk_push_object_internal(ctx);
2888 DUK_ASSERT(js_ctx->idx_loop >= 0);
2889
2890 /* [ ... buf loop ] */
2891
2892 /*
2893 * Process replacer/proplist (2nd argument to JSON.stringify)
2894 */
2895
2896 h = duk_get_hobject(ctx, idx_replacer);
2897 if (h != NULL) {
2898 if (DUK_HOBJECT_IS_CALLABLE(h)) {
2899 js_ctx->h_replacer = h;
2901 /* Here the specification requires correct array index enumeration
2902 * which is a bit tricky for sparse arrays (it is handled by the
2903 * enum setup code). We now enumerate ancestors too, although the
2904 * specification is not very clear on whether that is required.
2905 */
2906
2907 duk_uarridx_t plist_idx = 0;
2908 duk_small_uint_t enum_flags;
2909
2910 js_ctx->idx_proplist = duk_push_array(ctx); /* XXX: array internal? */
2911
2912 enum_flags = DUK_ENUM_ARRAY_INDICES_ONLY |
2913 DUK_ENUM_SORT_ARRAY_INDICES; /* expensive flag */
2914 duk_enum(ctx, idx_replacer, enum_flags);
2915 while (duk_next(ctx, -1 /*enum_index*/, 1 /*get_value*/)) {
2916 /* [ ... proplist enum_obj key val ] */
2918 /* XXX: duplicates should be eliminated here */
2919 DUK_DDD(DUK_DDDPRINT("proplist enum: key=%!T, val=%!T --> accept",
2920 (duk_tval *) duk_get_tval(ctx, -2),
2921 (duk_tval *) duk_get_tval(ctx, -1)));
2922 duk_to_string(ctx, -1); /* extra coercion of strings is OK */
2923 duk_put_prop_index(ctx, -4, plist_idx); /* -> [ ... proplist enum_obj key ] */
2924 plist_idx++;
2925 duk_pop(ctx);
2926 } else {
2927 DUK_DDD(DUK_DDDPRINT("proplist enum: key=%!T, val=%!T --> reject",
2928 (duk_tval *) duk_get_tval(ctx, -2),
2929 (duk_tval *) duk_get_tval(ctx, -1)));
2930 duk_pop_2(ctx);
2931 }
2932 }
2933 duk_pop(ctx); /* pop enum */
2934
2935 /* [ ... proplist ] */
2936 }
2937 }
2938
2939 /* [ ... buf loop (proplist) ] */
2940
2941 /*
2942 * Process space (3rd argument to JSON.stringify)
2943 */
2944
2945 h = duk_get_hobject(ctx, idx_space);
2946 if (h != NULL) {
2948 if (c == DUK_HOBJECT_CLASS_NUMBER) {
2949 duk_to_number(ctx, idx_space);
2950 } else if (c == DUK_HOBJECT_CLASS_STRING) {
2951 duk_to_string(ctx, idx_space);
2952 }
2953 }
2954
2955 if (duk_is_number(ctx, idx_space)) {
2956 duk_small_int_t nspace;
2957 /* spaces[] must be static to allow initializer with old compilers like BCC */
2958 static const char spaces[10] = {
2962 }; /* XXX: helper */
2963
2964 /* ToInteger() coercion; NaN -> 0, infinities are clamped to 0 and 10 */
2965 nspace = (duk_small_int_t) duk_to_int_clamped(ctx, idx_space, 0 /*minval*/, 10 /*maxval*/);
2966 DUK_ASSERT(nspace >= 0 && nspace <= 10);
2967
2968 duk_push_lstring(ctx, spaces, (duk_size_t) nspace);
2969 js_ctx->h_gap = duk_get_hstring(ctx, -1);
2970 DUK_ASSERT(js_ctx->h_gap != NULL);
2971 } else if (duk_is_string(ctx, idx_space)) {
2972 /* XXX: substring in-place at idx_place? */
2973 duk_dup(ctx, idx_space);
2974 duk_substring(ctx, -1, 0, 10); /* clamp to 10 chars */
2975 js_ctx->h_gap = duk_get_hstring(ctx, -1);
2976 DUK_ASSERT(js_ctx->h_gap != NULL);
2977 } else {
2978 /* nop */
2979 }
2980
2981 if (js_ctx->h_gap != NULL) {
2982 /* if gap is empty, behave as if not given at all */
2983 if (DUK_HSTRING_GET_CHARLEN(js_ctx->h_gap) == 0) {
2984 js_ctx->h_gap = NULL;
2985 }
2986 }
2987
2988 /* [ ... buf loop (proplist) (gap) ] */
2989
2990 /*
2991 * Fast path: assume no mutation, iterate object property tables
2992 * directly; bail out if that assumption doesn't hold.
2993 */
2994
2995#if defined(DUK_USE_JSON_STRINGIFY_FASTPATH)
2996 if (js_ctx->h_replacer == NULL && /* replacer is a mutation risk */
2997 js_ctx->idx_proplist == -1) { /* proplist is very rare */
2998 duk_int_t pcall_rc;
2999#ifdef DUK_USE_MARK_AND_SWEEP
3000 duk_small_uint_t prev_mark_and_sweep_base_flags;
3001#endif
3002
3003 DUK_DD(DUK_DDPRINT("try JSON.stringify() fast path"));
3004
3005 /* Use recursion_limit to ensure we don't overwrite js_ctx->visiting[]
3006 * array so we don't need two counter checks in the fast path. The
3007 * slow path has a much larger recursion limit which we'll use if
3008 * necessary.
3009 */
3012 DUK_ASSERT(js_ctx->recursion_depth == 0);
3013
3014 /* Execute the fast path in a protected call. If any error is thrown,
3015 * fall back to the slow path. This includes e.g. recursion limit
3016 * because the fast path has a smaller recursion limit (and simpler,
3017 * limited loop detection).
3018 */
3019
3020 duk_push_pointer(ctx, (void *) js_ctx);
3021 duk_dup(ctx, idx_value);
3022
3023#if defined(DUK_USE_MARK_AND_SWEEP)
3024 /* Must prevent finalizers which may have arbitrary side effects. */
3025 prev_mark_and_sweep_base_flags = thr->heap->mark_and_sweep_base_flags;
3027 DUK_MS_FLAG_NO_FINALIZERS | /* avoid attempts to add/remove object keys */
3028 DUK_MS_FLAG_NO_OBJECT_COMPACTION; /* avoid attempt to compact any objects */
3029#endif
3030
3031 pcall_rc = duk_safe_call(ctx, duk__json_stringify_fast, 2 /*nargs*/, 0 /*nret*/);
3032
3033#if defined(DUK_USE_MARK_AND_SWEEP)
3034 thr->heap->mark_and_sweep_base_flags = prev_mark_and_sweep_base_flags;
3035#endif
3036 if (pcall_rc == DUK_EXEC_SUCCESS) {
3037 DUK_DD(DUK_DDPRINT("fast path successful"));
3038 DUK_BW_PUSH_AS_STRING(thr, &js_ctx->bw);
3039 goto replace_finished;
3040 }
3041
3042 /* We come here for actual aborts (like encountering .toJSON())
3043 * but also for recursion/loop errors. Bufwriter size can be
3044 * kept because we'll probably need at least as much as we've
3045 * allocated so far.
3046 */
3047 DUK_D(DUK_DPRINT("fast path failed, serialize using slow path instead"));
3048 DUK_BW_RESET_SIZE(thr, &js_ctx->bw);
3049 js_ctx->recursion_depth = 0;
3050 }
3051#endif
3052
3053 /*
3054 * Create wrapper object and serialize
3055 */
3056
3057 idx_holder = duk_push_object(ctx);
3058 duk_dup(ctx, idx_value);
3060
3061 DUK_DDD(DUK_DDDPRINT("before: flags=0x%08lx, loop=%!T, replacer=%!O, "
3062 "proplist=%!T, gap=%!O, holder=%!T",
3063 (unsigned long) js_ctx->flags,
3064 (duk_tval *) duk_get_tval(ctx, js_ctx->idx_loop),
3065 (duk_heaphdr *) js_ctx->h_replacer,
3066 (duk_tval *) (js_ctx->idx_proplist >= 0 ? duk_get_tval(ctx, js_ctx->idx_proplist) : NULL),
3067 (duk_heaphdr *) js_ctx->h_gap,
3068 (duk_tval *) duk_get_tval(ctx, -1)));
3069
3070 /* serialize the wrapper with empty string key */
3071
3073
3074 /* [ ... buf loop (proplist) (gap) holder "" ] */
3075
3077 DUK_ASSERT(js_ctx->recursion_depth == 0);
3078
3079 if (DUK_UNLIKELY(duk__enc_value(js_ctx, idx_holder) == 0)) { /* [ ... holder key ] -> [ ... holder ] */
3080 /* Result is undefined. */
3081 duk_push_undefined(ctx);
3082 } else {
3083 /* Convert buffer to result string. */
3084 DUK_BW_PUSH_AS_STRING(thr, &js_ctx->bw);
3085 }
3086
3087 DUK_DDD(DUK_DDDPRINT("after: flags=0x%08lx, loop=%!T, replacer=%!O, "
3088 "proplist=%!T, gap=%!O, holder=%!T",
3089 (unsigned long) js_ctx->flags,
3090 (duk_tval *) duk_get_tval(ctx, js_ctx->idx_loop),
3091 (duk_heaphdr *) js_ctx->h_replacer,
3092 (duk_tval *) (js_ctx->idx_proplist >= 0 ? duk_get_tval(ctx, js_ctx->idx_proplist) : NULL),
3093 (duk_heaphdr *) js_ctx->h_gap,
3094 (duk_tval *) duk_get_tval(ctx, idx_holder)));
3095
3096 /* The stack has a variable shape here, so force it to the
3097 * desired one explicitly.
3098 */
3099
3100#if defined(DUK_USE_JSON_STRINGIFY_FASTPATH)
3101 replace_finished:
3102#endif
3103 duk_replace(ctx, entry_top);
3104 duk_set_top(ctx, entry_top + 1);
3105
3106 DUK_DDD(DUK_DDDPRINT("JSON stringify end: value=%!T, replacer=%!T, space=%!T, "
3107 "flags=0x%08lx, result=%!T, stack_top=%ld",
3108 (duk_tval *) duk_get_tval(ctx, idx_value),
3109 (duk_tval *) duk_get_tval(ctx, idx_replacer),
3110 (duk_tval *) duk_get_tval(ctx, idx_space),
3111 (unsigned long) flags,
3112 (duk_tval *) duk_get_tval(ctx, -1),
3113 (long) duk_get_top(ctx)));
3114
3115 DUK_ASSERT(duk_get_top(ctx) == entry_top + 1);
3116}
#define DUK_MS_FLAG_NO_OBJECT_COMPACTION
DUK_INTERNAL_DECL duk_int_t duk_to_int_clamped(duk_context *ctx, duk_idx_t index, duk_int_t minval, duk_int_t maxval)
#define DUK_STRIDX_JSON_EXT_UNDEFINED
#define DUK_JSON_FLAG_AVOID_KEY_QUOTES
#define DUK_HSTRING_GET_CHARLEN(x)
#define DUK_BW_RESET_SIZE(thr, bw_ctx)
#define DUK_MS_FLAG_NO_FINALIZERS
DUK_EXTERNAL void duk_replace(duk_context *ctx, duk_idx_t to_index)
#define DUK_STRIDX_JSON_EXT_FUNCTION2
DUK_EXTERNAL duk_int_t duk_safe_call(duk_context *ctx, duk_safe_call_function func, duk_idx_t nargs, duk_idx_t nrets)
#define DUK_STRIDX_JSON_EXT_NEGINF
DUK_EXTERNAL void duk_substring(duk_context *ctx, duk_idx_t index, duk_size_t start_offset, duk_size_t end_offset)
#define DUK_STRIDX_JSON_EXT_NAN
DUK_INTERNAL_DECL duk_idx_t duk_push_object_internal(duk_context *ctx)
#define DUK_BW_PUSH_AS_STRING(thr, bw_ctx)
DUK_EXTERNAL duk_bool_t duk_is_string(duk_context *ctx, duk_idx_t index)
#define DUK_JSON_FLAG_ASCII_ONLY
#define DUK_STRIDX_JSON_EXT_POSINF
#define DUK_STRIDX_JSON_EXT_FUNCTION1
#define DUK_ENUM_ARRAY_INDICES_ONLY
#define DUK_ENUM_SORT_ARRAY_INDICES
#define DUK_TYPE_MASK_LIGHTFUNC
#define DUK_TYPE_MASK_POINTER
#define DUK_TYPE_MASK_UNDEFINED
DUK_LOCAL_DECL duk_bool_t duk__enc_allow_into_proplist(duk_tval *tv)
duk_small_uint_t mark_and_sweep_base_flags

References duk_json_enc_ctx::bw, duk__enc_allow_into_proplist(), duk__enc_value(), DUK__JSON_STRINGIFY_BUFSIZE, DUK_ASC_SPACE, DUK_ASSERT, DUK_BW_INIT_PUSHBUF, DUK_BW_PUSH_AS_STRING, DUK_BW_RESET_SIZE, DUK_D, DUK_DD, DUK_DDD, DUK_DDDPRINT, DUK_DDPRINT, DUK_DPRINT, duk_dup(), duk_enum(), DUK_ENUM_ARRAY_INDICES_ONLY, DUK_ENUM_SORT_ARRAY_INDICES, DUK_EXEC_SUCCESS, duk_get_hobject(), duk_get_hstring(), duk_get_top(), duk_get_tval(), DUK_HOBJECT_CLASS_ARRAY, DUK_HOBJECT_CLASS_NUMBER, DUK_HOBJECT_CLASS_STRING, DUK_HOBJECT_GET_CLASS_NUMBER, DUK_HOBJECT_IS_CALLABLE, DUK_HSTRING_GET_CHARLEN, DUK_INVALID_INDEX, duk_is_number(), duk_is_string(), DUK_JSON_ENC_LOOPARRAY, DUK_JSON_FLAG_ASCII_ONLY, DUK_JSON_FLAG_AVOID_KEY_QUOTES, DUK_JSON_FLAG_EXT_COMPATIBLE, DUK_JSON_FLAG_EXT_CUSTOM, DUK_MEMZERO, DUK_MS_FLAG_NO_FINALIZERS, DUK_MS_FLAG_NO_OBJECT_COMPACTION, duk_next(), duk_pop(), duk_pop_2(), duk_push_array(), duk_push_hstring_stridx(), duk_push_lstring(), duk_push_object(), duk_push_object_internal(), duk_push_pointer(), duk_push_undefined(), duk_put_prop_index(), duk_put_prop_stridx(), duk_replace(), duk_safe_call(), duk_set_top(), DUK_STRIDX_EMPTY_STRING, DUK_STRIDX_INFINITY, DUK_STRIDX_JSON_EXT_FUNCTION1, DUK_STRIDX_JSON_EXT_FUNCTION2, DUK_STRIDX_JSON_EXT_NAN, DUK_STRIDX_JSON_EXT_NEGINF, DUK_STRIDX_JSON_EXT_POSINF, DUK_STRIDX_JSON_EXT_UNDEFINED, DUK_STRIDX_LC_NULL, DUK_STRIDX_LC_UNDEFINED, DUK_STRIDX_MINUS_INFINITY, DUK_STRIDX_NAN, duk_substring(), duk_to_int_clamped(), duk_to_number(), duk_to_string(), DUK_TYPE_MASK_BUFFER, DUK_TYPE_MASK_LIGHTFUNC, DUK_TYPE_MASK_POINTER, DUK_TYPE_MASK_UNDEFINED, DUK_UNLIKELY, DUK_USE_JSON_ENC_RECLIMIT, duk_json_enc_ctx::flag_ascii_only, duk_json_enc_ctx::flag_avoid_key_quotes, duk_json_enc_ctx::flag_ext_compatible, duk_json_enc_ctx::flag_ext_custom, duk_json_enc_ctx::flag_ext_custom_or_compatible, duk_json_enc_ctx::flags, duk_json_enc_ctx::h_gap, duk_json_enc_ctx::h_replacer, duk_hthread::heap, duk_json_enc_ctx::idx_loop, duk_json_enc_ctx::idx_proplist, duk_heap::mark_and_sweep_base_flags, duk_json_enc_ctx::mask_for_undefined, NULL, duk_json_enc_ctx::recursion_depth, duk_json_enc_ctx::recursion_limit, duk_json_enc_ctx::stridx_custom_function, duk_json_enc_ctx::stridx_custom_nan, duk_json_enc_ctx::stridx_custom_neginf, duk_json_enc_ctx::stridx_custom_posinf, duk_json_enc_ctx::stridx_custom_undefined, and duk_json_enc_ctx::thr.

Referenced by duk_bi_json_object_stringify().

Variable Documentation

◆ duk__json_decnumber_lookup

DUK_LOCAL const duk_uint8_t duk__json_decnumber_lookup[256]
Initial value:
= {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

Definition at line 165 of file duktape-1.5.2/src-separate/duk_bi_json.c.

165 {
166 /* 0x00: finish (not part of number)
167 * 0x01: continue
168 */
169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
170 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
171 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00,
172 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
173 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
174 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
175 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
176 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
177 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
179 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
180 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
181 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
183 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
184 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
185};

Referenced by duk__dec_number().

◆ duk__json_decstr_lookup

DUK_LOCAL const duk_uint8_t duk__json_decstr_lookup[256]
Initial value:
= {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x20, 0x21, 0x00, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x00, 0x5d, 0x5e, 0x5f,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
}

Definition at line 117 of file duktape-1.5.2/src-separate/duk_bi_json.c.

117 {
118 /* 0x00: slow path
119 * other: as is
120 */
121 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
122 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
123 0x20, 0x21, 0x00, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
124 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
125 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
126 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x00, 0x5d, 0x5e, 0x5f,
127 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
128 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
129 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
130 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
131 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
132 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
133 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
134 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
135 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
136 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
137};

Referenced by duk__dec_string().

◆ duk__json_eatwhite_lookup

DUK_LOCAL const duk_uint8_t duk__json_eatwhite_lookup[256]
Initial value:
= {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

Definition at line 141 of file duktape-1.5.2/src-separate/duk_bi_json.c.

141 {
142 /* 0x00: finish (non-white)
143 * 0x01: continue
144 */
145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00,
146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
147 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
148 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
149 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
157 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
159 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
160 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
161};

Referenced by duk__dec_eat_white().

◆ duk__json_quotestr_lookup

DUK_LOCAL const duk_uint8_t duk__json_quotestr_lookup[256]
Initial value:
= {
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xe2, 0xf4, 0xee, 0x80, 0xe6, 0xf2, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x20, 0x21, 0xa2, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0xdc, 0x5d, 0x5e, 0x5f,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x81,
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81
}

Definition at line 83 of file duktape-1.5.2/src-separate/duk_bi_json.c.

83 {
84 /* 0x00 ... 0x7f: as is
85 * 0x80: escape generically
86 * 0x81: slow path
87 * 0xa0 ... 0xff: backslash + one char
88 */
89
90 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xe2, 0xf4, 0xee, 0x80, 0xe6, 0xf2, 0x80, 0x80,
91 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
92 0x20, 0x21, 0xa2, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
93 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
94 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
95 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0xdc, 0x5d, 0x5e, 0x5f,
96 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
97 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x81,
98 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
99 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
100 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
101 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
102 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
103 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
104 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
105 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81
106};

Referenced by duk__enc_quote_string().