aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2020-12-07 23:35:47 +0100
committerMarcel Holtmann <marcel@holtmann.org>2020-12-07 23:35:47 +0100
commit1000d5f3389357b0bb738b8832f62226a2bf5ae1 (patch)
tree2a2bae67c425f88554c50746e4ae1fd216e4a24b
parent6f2ba9396ead9909c9f427651ee005834fbd05a8 (diff)
downloadpacrunner-1000d5f3389357b0bb738b8832f62226a2bf5ae1.tar.gz
duktape: Import v2.6.0
-rw-r--r--duktape/duk_config.h12
-rw-r--r--duktape/duktape.c676
-rw-r--r--duktape/duktape.h14
3 files changed, 426 insertions, 276 deletions
diff --git a/duktape/duk_config.h b/duktape/duk_config.h
index 130168a..c7cebde 100644
--- a/duktape/duk_config.h
+++ b/duktape/duk_config.h
@@ -1,9 +1,9 @@
/*
* duk_config.h configuration header generated by genconfig.py.
*
- * Git commit: 6001888049cb42656f8649db020e804bcdeca6a7
- * Git describe: v2.5.0
- * Git branch: master
+ * Git commit: fffa346eff06a8764b02c31d4336f63a773a95c3
+ * Git describe: v2.6.0
+ * Git branch: v2-maintenance
*
* Supported platforms:
* - Mac OSX, iPhone, Darwin
@@ -964,9 +964,7 @@
#elif defined(DUK_F_PPC64)
/* --- PowerPC 64-bit --- */
#define DUK_USE_ARCH_STRING "ppc64"
-#if !defined(DUK_USE_BYTEORDER)
-#define DUK_USE_BYTEORDER 3
-#endif
+/* No forced byteorder (both little and big endian are possible). */
#undef DUK_USE_PACKED_TVAL
#define DUK_F_PACKED_TVAL_PROVIDED
#elif defined(DUK_F_SPARC32)
@@ -2917,6 +2915,8 @@ typedef struct duk_hthread duk_context;
#define DUK_USE_CACHE_CATCHER
#define DUK_USE_CALLSTACK_LIMIT 10000
#define DUK_USE_CBOR_BUILTIN
+#define DUK_USE_CBOR_DEC_RECLIMIT 1000
+#define DUK_USE_CBOR_ENC_RECLIMIT 1000
#define DUK_USE_CBOR_SUPPORT
#define DUK_USE_COMPILER_RECLIMIT 2500
#define DUK_USE_COROUTINE_SUPPORT
diff --git a/duktape/duktape.c b/duktape/duktape.c
index 366883c..cd2f791 100644
--- a/duktape/duktape.c
+++ b/duktape/duktape.c
@@ -1,8 +1,8 @@
/*
- * Single source autogenerated distributable for Duktape 2.5.0.
+ * Single source autogenerated distributable for Duktape 2.6.0.
*
- * Git commit 6001888049cb42656f8649db020e804bcdeca6a7 (v2.5.0).
- * Git branch master.
+ * Git commit fffa346eff06a8764b02c31d4336f63a773a95c3 (v2.6.0).
+ * Git branch v2-maintenance.
*
* See Duktape AUTHORS.rst and LICENSE.txt for copyright and
* licensing information.
@@ -525,7 +525,8 @@ typedef union duk_double_union duk_double_union;
} while (0)
#define DUK__DBLUNION_NORMALIZE_NAN_CHECK_NOTFULL(u) do { \
- if (DUK__DBLUNION_IS_NAN_NOTFULL((u))) { \
+ /* Check must be full. */ \
+ if (DUK__DBLUNION_IS_NAN_FULL((u))) { \
DUK__DBLUNION_SET_NAN_NOTFULL((u)); \
} \
} while (0)
@@ -537,12 +538,11 @@ typedef union duk_double_union duk_double_union;
*/
#if defined(DUK_USE_PACKED_TVAL)
-#if defined(DUK_USE_FULL_TVAL)
#define DUK_DBLUNION_NORMALIZE_NAN_CHECK(u) DUK__DBLUNION_NORMALIZE_NAN_CHECK_FULL((u))
#define DUK_DBLUNION_IS_NAN(u) DUK__DBLUNION_IS_NAN_FULL((u))
#define DUK_DBLUNION_IS_NORMALIZED_NAN(u) DUK__DBLUNION_IS_NORMALIZED_NAN_FULL((u))
#define DUK_DBLUNION_SET_NAN(d) DUK__DBLUNION_SET_NAN_FULL((d))
-#else
+#if 0
#define DUK_DBLUNION_NORMALIZE_NAN_CHECK(u) DUK__DBLUNION_NORMALIZE_NAN_CHECK_NOTFULL((u))
#define DUK_DBLUNION_IS_NAN(u) DUK__DBLUNION_IS_NAN_NOTFULL((u))
#define DUK_DBLUNION_IS_NORMALIZED_NAN(u) DUK__DBLUNION_IS_NORMALIZED_NAN_NOTFULL((u))
@@ -3141,10 +3141,12 @@ DUK_INTERNAL_DECL duk_bool_t duk_float_equals(duk_float_t x, duk_float_t y);
/* JSON */
#define DUK_STR_FMT_PTR "%p"
#define DUK_STR_FMT_INVALID_JSON "invalid json (at offset %ld)"
-#define DUK_STR_JSONDEC_RECLIMIT "json decode recursion limit"
-#define DUK_STR_JSONENC_RECLIMIT "json encode recursion limit"
#define DUK_STR_CYCLIC_INPUT "cyclic input"
+/* Generic codec */
+#define DUK_STR_DEC_RECLIMIT "decode recursion limit"
+#define DUK_STR_ENC_RECLIMIT "encode recursion limit"
+
/* Object property access */
#define DUK_STR_INVALID_BASE "invalid base value"
#define DUK_STR_STRICT_CALLER_READ "cannot read strict 'caller'"
@@ -11289,14 +11291,14 @@ DUK_INTERNAL const duk_uint8_t duk_builtins_data[4281] = {
137,194,70,46,142,68,165,19,236,1,64,174,187,161,95,37,134,204,23,225,35,
23,71,34,82,137,246,128,160,89,93,208,167,147,195,201,194,70,46,142,68,165,
19,238,1,64,182,187,161,71,105,20,19,177,139,163,145,41,68,16,7,6,15,82,70,
-72,115,96,0,0,0,0,0,2,234,32,91,60,165,195,201,194,8,134,149,216,162,0,192,
-41,225,8,2,48,177,36,1,149,13,196,15,0,200,209,97,199,128,99,32,176,195,
-192,113,57,143,0,167,133,32,230,80,28,202,139,175,238,2,48,189,192,20,1,
-119,80,87,193,186,129,89,56,72,197,209,200,193,185,35,23,71,109,13,219,36,
-98,232,237,156,13,26,208,211,14,102,19,87,137,91,95,128,0,10,96,24,92,0,0,
-83,2,53,56,0,0,165,3,28,204,160,160,226,100,226,200,211,76,241,240,0,1,102,
-8,22,75,64,137,73,20,230,105,133,7,19,39,22,70,154,103,143,128,0,11,48,20,
-28,76,156,113,75,34,78,62,0,0,45,3,103,31,0,0,22,65,44,57,137,62,33,179,
+72,115,96,0,0,0,0,0,15,106,32,91,60,165,195,201,194,8,134,149,216,162,0,
+192,41,225,8,2,48,177,36,1,149,13,196,15,0,200,209,97,199,128,99,32,176,
+195,192,113,57,143,0,167,133,32,230,80,28,202,139,175,238,2,48,189,192,20,
+1,119,80,87,193,186,129,89,56,72,197,209,200,193,185,35,23,71,109,13,219,
+36,98,232,237,156,13,26,208,211,14,102,19,87,137,91,95,128,0,10,96,24,92,0,
+0,83,2,53,56,0,0,165,3,28,204,160,160,226,100,226,200,211,76,241,240,0,1,
+102,8,22,75,64,137,73,20,230,105,133,7,19,39,22,70,154,103,143,128,0,11,48,
+20,28,76,156,113,75,34,78,62,0,0,45,3,103,31,0,0,22,65,44,57,137,62,33,179,
216,162,152,192,131,18,124,162,27,61,138,41,108,32,196,159,16,217,232,235,
81,76,104,73,137,62,81,13,158,142,181,20,184,16,98,79,136,108,244,244,168,
166,56,36,196,159,40,134,207,79,74,138,93,10,49,39,194,173,192,158,158,149,
@@ -11489,7 +11491,7 @@ DUK_INTERNAL const duk_uint8_t duk_builtins_data[4281] = {
137,194,70,46,142,68,165,19,236,1,64,174,187,161,95,37,134,204,23,225,35,
23,71,34,82,137,246,128,160,89,93,208,167,147,195,201,194,70,46,142,68,165,
19,238,1,64,182,187,161,71,105,20,19,177,139,163,145,41,68,16,7,6,15,82,70,
-72,115,96,32,106,2,128,0,0,0,0,91,60,165,195,201,194,8,134,149,216,162,0,
+72,115,96,32,106,15,0,0,0,0,0,91,60,165,195,201,194,8,134,149,216,162,0,
192,41,225,8,2,48,177,36,1,149,13,196,15,0,200,209,97,199,128,99,32,176,
195,192,113,57,143,0,167,133,32,230,80,28,202,139,175,238,2,48,189,192,20,
1,119,80,87,193,186,129,89,56,72,197,209,200,193,185,35,23,71,109,13,219,
@@ -11689,14 +11691,14 @@ DUK_INTERNAL const duk_uint8_t duk_builtins_data[4281] = {
137,194,70,46,142,68,165,19,236,1,64,174,187,161,95,37,134,204,23,225,35,
23,71,34,82,137,246,128,160,89,93,208,167,147,195,201,194,70,46,142,68,165,
19,238,1,64,182,187,161,71,105,20,19,177,139,163,145,41,68,16,7,6,15,82,70,
-72,115,96,0,2,234,32,0,0,0,0,91,60,165,195,201,194,8,134,149,216,162,0,192,
-41,225,8,2,48,177,36,1,149,13,196,15,0,200,209,97,199,128,99,32,176,195,
-192,113,57,143,0,167,133,32,230,80,28,202,139,175,238,2,48,189,192,20,1,
-119,80,87,193,186,129,89,56,72,197,209,200,193,185,35,23,71,109,13,219,36,
-98,232,237,156,13,26,208,211,14,102,19,87,137,91,95,128,0,10,96,24,92,0,0,
-83,2,53,56,0,0,165,3,28,204,160,160,226,100,226,200,211,76,241,240,0,1,102,
-8,22,75,64,137,73,20,230,105,133,7,19,39,22,70,154,103,143,128,0,11,48,20,
-28,76,156,113,75,34,78,62,0,0,45,3,103,31,0,0,22,65,44,57,137,62,33,179,
+72,115,96,0,15,106,32,0,0,0,0,91,60,165,195,201,194,8,134,149,216,162,0,
+192,41,225,8,2,48,177,36,1,149,13,196,15,0,200,209,97,199,128,99,32,176,
+195,192,113,57,143,0,167,133,32,230,80,28,202,139,175,238,2,48,189,192,20,
+1,119,80,87,193,186,129,89,56,72,197,209,200,193,185,35,23,71,109,13,219,
+36,98,232,237,156,13,26,208,211,14,102,19,87,137,91,95,128,0,10,96,24,92,0,
+0,83,2,53,56,0,0,165,3,28,204,160,160,226,100,226,200,211,76,241,240,0,1,
+102,8,22,75,64,137,73,20,230,105,133,7,19,39,22,70,154,103,143,128,0,11,48,
+20,28,76,156,113,75,34,78,62,0,0,45,3,103,31,0,0,22,65,44,57,137,62,33,179,
216,162,152,192,131,18,124,162,27,61,138,41,108,32,196,159,16,217,232,235,
81,76,104,73,137,62,81,13,158,142,181,20,184,16,98,79,136,108,244,244,168,
166,56,36,196,159,40,134,207,79,74,138,93,10,49,39,194,173,192,158,158,149,
@@ -16443,6 +16445,7 @@ struct duk_internal_thread_state {
duk_ljstate lj;
duk_bool_t creating_error;
duk_hthread *curr_thread;
+ duk_uint8_t thread_state;
duk_int_t call_recursion_depth;
};
@@ -16541,6 +16544,7 @@ DUK_EXTERNAL void duk_suspend(duk_hthread *thr, duk_thread_state *state) {
duk_memcpy((void *) &snapshot->lj, (const void *) lj, sizeof(duk_ljstate));
snapshot->creating_error = heap->creating_error;
snapshot->curr_thread = heap->curr_thread;
+ snapshot->thread_state = thr->state;
snapshot->call_recursion_depth = heap->call_recursion_depth;
lj->jmpbuf_ptr = NULL;
@@ -16550,6 +16554,8 @@ DUK_EXTERNAL void duk_suspend(duk_hthread *thr, duk_thread_state *state) {
heap->creating_error = 0;
heap->curr_thread = NULL;
heap->call_recursion_depth = 0;
+
+ thr->state = DUK_HTHREAD_STATE_INACTIVE;
}
DUK_EXTERNAL void duk_resume(duk_hthread *thr, const duk_thread_state *state) {
@@ -16566,6 +16572,8 @@ DUK_EXTERNAL void duk_resume(duk_hthread *thr, const duk_thread_state *state) {
DUK_ASSERT(thr->heap->pf_prevent_count == 0);
DUK_ASSERT(thr->heap->creating_error == 0);
+ thr->state = snapshot->thread_state;
+
heap = thr->heap;
duk_memcpy((void *) &heap->lj, (const void *) &snapshot->lj, sizeof(duk_ljstate));
@@ -30090,6 +30098,8 @@ typedef struct {
duk_uint8_t *buf_end;
duk_size_t len;
duk_idx_t idx_buf;
+ duk_uint_t recursion_depth;
+ duk_uint_t recursion_limit;
} duk_cbor_encode_context;
typedef struct {
@@ -30097,6 +30107,8 @@ typedef struct {
const duk_uint8_t *buf;
duk_size_t off;
duk_size_t len;
+ duk_uint_t recursion_depth;
+ duk_uint_t recursion_limit;
} duk_cbor_decode_context;
DUK_LOCAL void duk__cbor_encode_value(duk_cbor_encode_context *enc_ctx);
@@ -30120,6 +30132,34 @@ DUK_LOCAL void duk__cbor_encode_error(duk_cbor_encode_context *enc_ctx) {
(void) duk_type_error(enc_ctx->thr, "cbor encode error");
}
+DUK_LOCAL void duk__cbor_encode_req_stack(duk_cbor_encode_context *enc_ctx) {
+ duk_require_stack(enc_ctx->thr, 4);
+}
+
+DUK_LOCAL void duk__cbor_encode_objarr_entry(duk_cbor_encode_context *enc_ctx) {
+ duk_hthread *thr = enc_ctx->thr;
+
+ /* Native stack check in object/array recursion. */
+ duk_native_stack_check(thr);
+
+ /* When working with deeply recursive structures, this is important
+ * to ensure there's no effective depth limit.
+ */
+ duk__cbor_encode_req_stack(enc_ctx);
+
+ DUK_ASSERT(enc_ctx->recursion_depth <= enc_ctx->recursion_limit);
+ if (enc_ctx->recursion_depth >= enc_ctx->recursion_limit) {
+ DUK_ERROR_RANGE(thr, DUK_STR_ENC_RECLIMIT);
+ DUK_WO_NORETURN(return;);
+ }
+ enc_ctx->recursion_depth++;
+}
+
+DUK_LOCAL void duk__cbor_encode_objarr_exit(duk_cbor_encode_context *enc_ctx) {
+ DUK_ASSERT(enc_ctx->recursion_depth > 0);
+ enc_ctx->recursion_depth--;
+}
+
/* Check that a size_t is in uint32 range to avoid out-of-range casts. */
DUK_LOCAL void duk__cbor_encode_sizet_uint32_check(duk_cbor_encode_context *enc_ctx, duk_size_t len) {
if (DUK_UNLIKELY(sizeof(duk_size_t) > sizeof(duk_uint32_t) && len > (duk_size_t) DUK_UINT32_MAX)) {
@@ -30522,6 +30562,8 @@ DUK_LOCAL void duk__cbor_encode_object(duk_cbor_encode_context *enc_ctx) {
/* Caller must ensure space. */
DUK_ASSERT(duk__cbor_get_reserve(enc_ctx) >= 1 + 8);
+ duk__cbor_encode_objarr_entry(enc_ctx);
+
/* XXX: Support for specific built-ins like Date and RegExp. */
if (duk_is_array(enc_ctx->thr, -1)) {
/* Shortest encoding for arrays >= 256 in length is actually
@@ -30546,7 +30588,7 @@ DUK_LOCAL void duk__cbor_encode_object(duk_cbor_encode_context *enc_ctx) {
duk__cbor_encode_uint32(enc_ctx, (duk_uint32_t) len, 0x40U);
duk__cbor_encode_ensure(enc_ctx, len);
p = enc_ctx->ptr;
- duk_memcpy((void *) p, (const void *) buf, len);
+ duk_memcpy_unsafe((void *) p, (const void *) buf, len);
p += len;
enc_ctx->ptr = p;
} else {
@@ -30585,6 +30627,8 @@ DUK_LOCAL void duk__cbor_encode_object(duk_cbor_encode_context *enc_ctx) {
enc_ctx->ptr = p;
}
}
+
+ duk__cbor_encode_objarr_exit(enc_ctx);
}
DUK_LOCAL void duk__cbor_encode_buffer(duk_cbor_encode_context *enc_ctx) {
@@ -30601,7 +30645,7 @@ DUK_LOCAL void duk__cbor_encode_buffer(duk_cbor_encode_context *enc_ctx) {
duk__cbor_encode_uint32(enc_ctx, (duk_uint32_t) len, 0x40U);
duk__cbor_encode_ensure(enc_ctx, len);
p = enc_ctx->ptr;
- duk_memcpy((void *) p, (const void *) buf, len);
+ duk_memcpy_unsafe((void *) p, (const void *) buf, len);
p += len;
enc_ctx->ptr = p;
}
@@ -30648,11 +30692,6 @@ DUK_LOCAL void duk__cbor_encode_value(duk_cbor_encode_context *enc_ctx) {
* This can be improved by registering custom tags with IANA.
*/
- /* When working with deeply recursive structures, this is important
- * to ensure there's no effective depth limit.
- */
- duk_require_stack(enc_ctx->thr, 4);
-
/* Reserve space for up to 64-bit types (1 initial byte + 8
* followup bytes). This allows encoding of integers, floats,
* string/buffer length fields, etc without separate checks
@@ -30720,12 +30759,33 @@ DUK_LOCAL void duk__cbor_encode_value(duk_cbor_encode_context *enc_ctx) {
* Decoding
*/
-DUK_LOCAL void duk__cbor_req_stack(duk_cbor_decode_context *dec_ctx) {
+DUK_LOCAL void duk__cbor_decode_error(duk_cbor_decode_context *dec_ctx) {
+ (void) duk_type_error(dec_ctx->thr, "cbor decode error");
+}
+
+DUK_LOCAL void duk__cbor_decode_req_stack(duk_cbor_decode_context *dec_ctx) {
duk_require_stack(dec_ctx->thr, 4);
}
-DUK_LOCAL void duk__cbor_decode_error(duk_cbor_decode_context *dec_ctx) {
- (void) duk_type_error(dec_ctx->thr, "cbor decode error");
+DUK_LOCAL void duk__cbor_decode_objarr_entry(duk_cbor_decode_context *dec_ctx) {
+ duk_hthread *thr = dec_ctx->thr;
+
+ /* Native stack check in object/array recursion. */
+ duk_native_stack_check(thr);
+
+ duk__cbor_decode_req_stack(dec_ctx);
+
+ DUK_ASSERT(dec_ctx->recursion_depth <= dec_ctx->recursion_limit);
+ if (dec_ctx->recursion_depth >= dec_ctx->recursion_limit) {
+ DUK_ERROR_RANGE(thr, DUK_STR_DEC_RECLIMIT);
+ DUK_WO_NORETURN(return;);
+ }
+ dec_ctx->recursion_depth++;
+}
+
+DUK_LOCAL void duk__cbor_decode_objarr_exit(duk_cbor_decode_context *dec_ctx) {
+ DUK_ASSERT(dec_ctx->recursion_depth > 0);
+ dec_ctx->recursion_depth--;
}
DUK_LOCAL duk_uint8_t duk__cbor_decode_readbyte(duk_cbor_decode_context *dec_ctx) {
@@ -31004,9 +31064,7 @@ DUK_LOCAL void duk__cbor_decode_join_buffers(duk_cbor_decode_context *dec_ctx, d
buf_data = (duk_uint8_t *) duk_require_buffer(dec_ctx->thr, idx, &buf_size);
if (p != NULL) {
- if (buf_size > 0U) {
- duk_memcpy((void *) p, (const void *) buf_data, buf_size);
- }
+ duk_memcpy_unsafe((void *) p, (const void *) buf_data, buf_size);
p += buf_size;
} else {
total_size += buf_size;
@@ -31171,7 +31229,7 @@ DUK_LOCAL void duk__cbor_decode_string(duk_cbor_decode_context *dec_ctx, duk_uin
DUK_LOCAL duk_bool_t duk__cbor_decode_array(duk_cbor_decode_context *dec_ctx, duk_uint8_t ib, duk_uint8_t ai) {
duk_uint32_t idx, len;
- duk__cbor_req_stack(dec_ctx);
+ duk__cbor_decode_objarr_entry(dec_ctx);
/* Support arrays up to 0xfffffffeU in length. 0xffffffff is
* used as an indefinite length marker.
@@ -31181,7 +31239,7 @@ DUK_LOCAL duk_bool_t duk__cbor_decode_array(duk_cbor_decode_context *dec_ctx, du
} else {
len = duk__cbor_decode_aival_uint32(dec_ctx, ib);
if (len == 0xffffffffUL) {
- return 0;
+ goto failure;
}
}
@@ -31193,7 +31251,7 @@ DUK_LOCAL duk_bool_t duk__cbor_decode_array(duk_cbor_decode_context *dec_ctx, du
}
if (idx == len) {
if (ai == 0x1fU) {
- return 0;
+ goto failure;
}
break;
}
@@ -31201,24 +31259,32 @@ DUK_LOCAL duk_bool_t duk__cbor_decode_array(duk_cbor_decode_context *dec_ctx, du
duk_put_prop_index(dec_ctx->thr, -2, (duk_uarridx_t) idx);
idx++;
if (idx == 0U) {
- return 0; /* wrapped */
+ goto failure; /* wrapped */
}
}
+#if 0
+ success:
+#endif
+ duk__cbor_decode_objarr_exit(dec_ctx);
return 1;
+
+ failure:
+ /* No need to unwind recursion checks, caller will throw. */
+ return 0;
}
DUK_LOCAL duk_bool_t duk__cbor_decode_map(duk_cbor_decode_context *dec_ctx, duk_uint8_t ib, duk_uint8_t ai) {
duk_uint32_t count;
- duk__cbor_req_stack(dec_ctx);
+ duk__cbor_decode_objarr_entry(dec_ctx);
if (ai == 0x1fU) {
count = 0xffffffffUL;
} else {
count = duk__cbor_decode_aival_uint32(dec_ctx, ib);
if (count == 0xffffffffUL) {
- return 0;
+ goto failure;
}
}
@@ -31249,7 +31315,15 @@ DUK_LOCAL duk_bool_t duk__cbor_decode_map(duk_cbor_decode_context *dec_ctx, duk_
duk_put_prop(dec_ctx->thr, -3);
}
+#if 0
+ success:
+#endif
+ duk__cbor_decode_objarr_exit(dec_ctx);
return 1;
+
+ failure:
+ /* No need to unwind recursion checks, caller will throw. */
+ return 0;
}
DUK_LOCAL duk_double_t duk__cbor_decode_float(duk_cbor_decode_context *dec_ctx) {
@@ -31626,8 +31700,13 @@ DUK_LOCAL void duk__cbor_encode(duk_hthread *thr, duk_idx_t idx, duk_uint_t enco
enc_ctx.buf = buf;
enc_ctx.buf_end = buf + enc_ctx.len;
+ enc_ctx.recursion_depth = 0;
+ enc_ctx.recursion_limit = DUK_USE_CBOR_ENC_RECLIMIT;
+
duk_dup(thr, idx);
+ duk__cbor_encode_req_stack(&enc_ctx);
duk__cbor_encode_value(&enc_ctx);
+ DUK_ASSERT(enc_ctx.recursion_depth == 0);
duk_resize_buffer(enc_ctx.thr, enc_ctx.idx_buf, (duk_size_t) (enc_ctx.ptr - enc_ctx.buf));
duk_replace(thr, idx);
}
@@ -31649,8 +31728,12 @@ DUK_LOCAL void duk__cbor_decode(duk_hthread *thr, duk_idx_t idx, duk_uint_t deco
dec_ctx.off = 0;
/* dec_ctx.len: set above */
- duk__cbor_req_stack(&dec_ctx);
+ dec_ctx.recursion_depth = 0;
+ dec_ctx.recursion_limit = DUK_USE_CBOR_DEC_RECLIMIT;
+
+ duk__cbor_decode_req_stack(&dec_ctx);
duk__cbor_decode_value(&dec_ctx);
+ DUK_ASSERT(dec_ctx.recursion_depth == 0);
if (dec_ctx.off != dec_ctx.len) {
(void) duk_type_error(thr, "trailing garbage");
}
@@ -36373,28 +36456,28 @@ DUK_INTERNAL duk_ret_t duk_bi_global_object_unescape(duk_hthread *thr) {
#define DUK__JSON_STRINGIFY_BUFSIZE 128
#define DUK__JSON_MAX_ESC_LEN 10 /* '\Udeadbeef' */
-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 void duk__json_dec_syntax_error(duk_json_dec_ctx *js_ctx);
+DUK_LOCAL_DECL void duk__json_dec_eat_white(duk_json_dec_ctx *js_ctx);
#if defined(DUK_USE_JX)
-DUK_LOCAL_DECL duk_uint8_t duk__dec_peek(duk_json_dec_ctx *js_ctx);
+DUK_LOCAL_DECL duk_uint8_t duk__json_dec_peek(duk_json_dec_ctx *js_ctx);
#endif
-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 duk_uint8_t duk__json_dec_get(duk_json_dec_ctx *js_ctx);
+DUK_LOCAL_DECL duk_uint8_t duk__json_dec_get_nonwhite(duk_json_dec_ctx *js_ctx);
+DUK_LOCAL_DECL duk_uint_fast32_t duk__json_dec_decode_hex_escape(duk_json_dec_ctx *js_ctx, duk_small_uint_t n);
+DUK_LOCAL_DECL void duk__json_dec_req_stridx(duk_json_dec_ctx *js_ctx, duk_small_uint_t stridx);
+DUK_LOCAL_DECL void duk__json_dec_string(duk_json_dec_ctx *js_ctx);
#if defined(DUK_USE_JX)
-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);
-#endif
-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__json_dec_plain_string(duk_json_dec_ctx *js_ctx);
+DUK_LOCAL_DECL void duk__json_dec_pointer(duk_json_dec_ctx *js_ctx);
+DUK_LOCAL_DECL void duk__json_dec_buffer(duk_json_dec_ctx *js_ctx);
+#endif
+DUK_LOCAL_DECL void duk__json_dec_number(duk_json_dec_ctx *js_ctx);
+DUK_LOCAL_DECL void duk__json_dec_objarr_entry(duk_json_dec_ctx *js_ctx);
+DUK_LOCAL_DECL void duk__json_dec_objarr_exit(duk_json_dec_ctx *js_ctx);
+DUK_LOCAL_DECL void duk__json_dec_object(duk_json_dec_ctx *js_ctx);
+DUK_LOCAL_DECL void duk__json_dec_array(duk_json_dec_ctx *js_ctx);
+DUK_LOCAL_DECL void duk__json_dec_value(duk_json_dec_ctx *js_ctx);
+DUK_LOCAL_DECL void duk__json_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);
@@ -36405,29 +36488,29 @@ DUK_LOCAL_DECL void duk__emit_cstring(duk_json_enc_ctx *js_ctx, const char *p);
#endif
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__json_enc_key_autoquote(duk_json_enc_ctx *js_ctx, duk_hstring *k);
+DUK_LOCAL_DECL void duk__json_enc_quote_string(duk_json_enc_ctx *js_ctx, duk_hstring *h_str);
+DUK_LOCAL_DECL void duk__json_enc_objarr_entry(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top);
+DUK_LOCAL_DECL void duk__json_enc_objarr_exit(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top);
+DUK_LOCAL_DECL void duk__json_enc_object(duk_json_enc_ctx *js_ctx);
+DUK_LOCAL_DECL void duk__json_enc_array(duk_json_enc_ctx *js_ctx);
+DUK_LOCAL_DECL duk_bool_t duk__json_enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_holder);
+DUK_LOCAL_DECL duk_bool_t duk__json_enc_allow_into_proplist(duk_tval *tv);
+DUK_LOCAL_DECL void duk__json_enc_double(duk_json_enc_ctx *js_ctx);
#if defined(DUK_USE_FASTINT)
-DUK_LOCAL_DECL void duk__enc_fastint_tval(duk_json_enc_ctx *js_ctx, duk_tval *tv);
+DUK_LOCAL_DECL void duk__json_enc_fastint_tval(duk_json_enc_ctx *js_ctx, duk_tval *tv);
#endif
#if defined(DUK_USE_JX) || defined(DUK_USE_JC)
-DUK_LOCAL_DECL void duk__enc_buffer_jx_jc(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__json_enc_buffer_jx_jc(duk_json_enc_ctx *js_ctx, duk_hbuffer *h);
+DUK_LOCAL_DECL void duk__json_enc_pointer(duk_json_enc_ctx *js_ctx, void *ptr);
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
-DUK_LOCAL_DECL void duk__enc_bufobj(duk_json_enc_ctx *js_ctx, duk_hbufobj *h_bufobj);
+DUK_LOCAL_DECL void duk__json_enc_bufobj(duk_json_enc_ctx *js_ctx, duk_hbufobj *h_bufobj);
#endif
#endif
#if defined(DUK_USE_JSON_STRINGIFY_FASTPATH)
-DUK_LOCAL_DECL void duk__enc_buffer_json_fastpath(duk_json_enc_ctx *js_ctx, duk_hbuffer *h);
+DUK_LOCAL_DECL void duk__json_enc_buffer_json_fastpath(duk_json_enc_ctx *js_ctx, duk_hbuffer *h);
#endif
-DUK_LOCAL_DECL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t depth);
+DUK_LOCAL_DECL void duk__json_enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t depth);
/*
* Helper tables
@@ -36552,7 +36635,7 @@ DUK_LOCAL const duk_uint8_t duk__json_decnumber_lookup[256] = {
* CESU-8 encodings.
*/
-DUK_LOCAL void duk__dec_syntax_error(duk_json_dec_ctx *js_ctx) {
+DUK_LOCAL void duk__json_dec_syntax_error(duk_json_dec_ctx *js_ctx) {
/* Shared handler to minimize parser size. Cause will be
* hidden, unfortunately, but we'll have an offset which
* is often quite enough.
@@ -36562,7 +36645,7 @@ DUK_LOCAL void duk__dec_syntax_error(duk_json_dec_ctx *js_ctx) {
DUK_WO_NORETURN(return;);
}
-DUK_LOCAL void duk__dec_eat_white(duk_json_dec_ctx *js_ctx) {
+DUK_LOCAL void duk__json_dec_eat_white(duk_json_dec_ctx *js_ctx) {
const duk_uint8_t *p;
duk_uint8_t t;
@@ -36593,24 +36676,24 @@ DUK_LOCAL void duk__dec_eat_white(duk_json_dec_ctx *js_ctx) {
}
#if defined(DUK_USE_JX)
-DUK_LOCAL duk_uint8_t duk__dec_peek(duk_json_dec_ctx *js_ctx) {
+DUK_LOCAL duk_uint8_t duk__json_dec_peek(duk_json_dec_ctx *js_ctx) {
DUK_ASSERT(js_ctx->p <= js_ctx->p_end);
return *js_ctx->p;
}
#endif
-DUK_LOCAL duk_uint8_t duk__dec_get(duk_json_dec_ctx *js_ctx) {
+DUK_LOCAL duk_uint8_t duk__json_dec_get(duk_json_dec_ctx *js_ctx) {
DUK_ASSERT(js_ctx->p <= js_ctx->p_end);
return *js_ctx->p++;
}
-DUK_LOCAL duk_uint8_t duk__dec_get_nonwhite(duk_json_dec_ctx *js_ctx) {
- duk__dec_eat_white(js_ctx);
- return duk__dec_get(js_ctx);
+DUK_LOCAL duk_uint8_t duk__json_dec_get_nonwhite(duk_json_dec_ctx *js_ctx) {
+ duk__json_dec_eat_white(js_ctx);
+ return duk__json_dec_get(js_ctx);
}
/* For JX, expressing the whole unsigned 32-bit range matters. */
-DUK_LOCAL duk_uint_fast32_t duk__dec_decode_hex_escape(duk_json_dec_ctx *js_ctx, duk_small_uint_t n) {
+DUK_LOCAL duk_uint_fast32_t duk__json_dec_decode_hex_escape(duk_json_dec_ctx *js_ctx, duk_small_uint_t n) {
duk_small_uint_t i;
duk_uint_fast32_t res = 0;
duk_uint8_t x;
@@ -36619,7 +36702,7 @@ DUK_LOCAL duk_uint_fast32_t duk__dec_decode_hex_escape(duk_json_dec_ctx *js_ctx,
for (i = 0; i < n; i++) {
/* XXX: share helper from lexer; duk_lexer.c / hexval(). */
- x = duk__dec_get(js_ctx);
+ x = duk__json_dec_get(js_ctx);
DUK_DDD(DUK_DDDPRINT("decode_hex_escape: i=%ld, n=%ld, res=%ld, x=%ld",
(long) i, (long) n, (long) res, (long) x));
@@ -36638,12 +36721,12 @@ DUK_LOCAL duk_uint_fast32_t duk__dec_decode_hex_escape(duk_json_dec_ctx *js_ctx,
return res;
syntax_error:
- duk__dec_syntax_error(js_ctx);
+ duk__json_dec_syntax_error(js_ctx);
DUK_UNREACHABLE();
return 0;
}
-DUK_LOCAL void duk__dec_req_stridx(duk_json_dec_ctx *js_ctx, duk_small_uint_t stridx) {
+DUK_LOCAL void duk__json_dec_req_stridx(duk_json_dec_ctx *js_ctx, duk_small_uint_t stridx) {
duk_hstring *h;
const duk_uint8_t *p;
duk_uint8_t x, y;
@@ -36665,7 +36748,7 @@ DUK_LOCAL void duk__dec_req_stridx(duk_json_dec_ctx *js_ctx, duk_small_uint_t st
if (x == 0) {
break;
}
- y = duk__dec_get(js_ctx);
+ y = duk__json_dec_get(js_ctx);
if (x != y) {
/* Catches EOF of JSON input. */
goto syntax_error;
@@ -36676,18 +36759,18 @@ DUK_LOCAL void duk__dec_req_stridx(duk_json_dec_ctx *js_ctx, duk_small_uint_t st
return;
syntax_error:
- duk__dec_syntax_error(js_ctx);
+ duk__json_dec_syntax_error(js_ctx);
DUK_UNREACHABLE();
}
-DUK_LOCAL duk_small_int_t duk__dec_string_escape(duk_json_dec_ctx *js_ctx, duk_uint8_t **ext_p) {
+DUK_LOCAL duk_small_int_t duk__json_dec_string_escape(duk_json_dec_ctx *js_ctx, duk_uint8_t **ext_p) {
duk_uint_fast32_t cp;
/* EOF (-1) will be cast to an unsigned value first
* and then re-cast for the switch. In any case, it
* will match the default case (syntax error).
*/
- cp = (duk_uint_fast32_t) duk__dec_get(js_ctx);
+ cp = (duk_uint_fast32_t) duk__json_dec_get(js_ctx);
switch (cp) {
case DUK_ASC_BACKSLASH: break;
case DUK_ASC_DOUBLEQUOTE: break;
@@ -36698,13 +36781,13 @@ DUK_LOCAL duk_small_int_t duk__dec_string_escape(duk_json_dec_ctx *js_ctx, duk_u
case DUK_ASC_LC_F: cp = 0x0c; break;
case DUK_ASC_LC_B: cp = 0x08; break;
case DUK_ASC_LC_U: {
- cp = duk__dec_decode_hex_escape(js_ctx, 4);
+ cp = duk__json_dec_decode_hex_escape(js_ctx, 4);
break;
}
#if defined(DUK_USE_JX)
case DUK_ASC_UC_U: {
if (js_ctx->flag_ext_custom) {
- cp = duk__dec_decode_hex_escape(js_ctx, 8);
+ cp = duk__json_dec_decode_hex_escape(js_ctx, 8);
} else {
return 1; /* syntax error */
}
@@ -36712,7 +36795,7 @@ DUK_LOCAL duk_small_int_t duk__dec_string_escape(duk_json_dec_ctx *js_ctx, duk_u
}
case DUK_ASC_LC_X: {
if (js_ctx->flag_ext_custom) {
- cp = duk__dec_decode_hex_escape(js_ctx, 2);
+ cp = duk__json_dec_decode_hex_escape(js_ctx, 2);
} else {
return 1; /* syntax error */
}
@@ -36729,7 +36812,7 @@ DUK_LOCAL duk_small_int_t duk__dec_string_escape(duk_json_dec_ctx *js_ctx, duk_u
return 0;
}
-DUK_LOCAL void duk__dec_string(duk_json_dec_ctx *js_ctx) {
+DUK_LOCAL void duk__json_dec_string(duk_json_dec_ctx *js_ctx) {
duk_hthread *thr = js_ctx->thr;
duk_bufwriter_ctx bw_alloc;
duk_bufwriter_ctx *bw;
@@ -36788,7 +36871,7 @@ DUK_LOCAL void duk__dec_string(duk_json_dec_ctx *js_ctx) {
* quite slow but it's uncommon).
*/
js_ctx->p = p;
- if (duk__dec_string_escape(js_ctx, &q) != 0) {
+ if (duk__json_dec_string_escape(js_ctx, &q) != 0) {
goto syntax_error;
}
break;
@@ -36805,12 +36888,12 @@ DUK_LOCAL void duk__dec_string(duk_json_dec_ctx *js_ctx) {
q = DUK_BW_ENSURE_RAW(js_ctx->thr, bw, DUK_UNICODE_MAX_XUTF8_LENGTH, q);
- x = duk__dec_get(js_ctx);
+ x = duk__json_dec_get(js_ctx);
if (x == DUK_ASC_DOUBLEQUOTE) {
break;
} else if (x == DUK_ASC_BACKSLASH) {
- if (duk__dec_string_escape(js_ctx, &q) != 0) {
+ if (duk__json_dec_string_escape(js_ctx, &q) != 0) {
goto syntax_error;
}
} else if (x < 0x20) {
@@ -36830,7 +36913,7 @@ DUK_LOCAL void duk__dec_string(duk_json_dec_ctx *js_ctx) {
return;
syntax_error:
- duk__dec_syntax_error(js_ctx);
+ duk__json_dec_syntax_error(js_ctx);
DUK_UNREACHABLE();
}
@@ -36838,7 +36921,7 @@ DUK_LOCAL void duk__dec_string(duk_json_dec_ctx *js_ctx) {
/* Decode a plain string consisting entirely of identifier characters.
* Used to parse plain keys (e.g. "foo: 123").
*/
-DUK_LOCAL void duk__dec_plain_string(duk_json_dec_ctx *js_ctx) {
+DUK_LOCAL void duk__json_dec_plain_string(duk_json_dec_ctx *js_ctx) {
duk_hthread *thr = js_ctx->thr;
const duk_uint8_t *p;
duk_small_int_t x;
@@ -36880,7 +36963,7 @@ DUK_LOCAL void duk__dec_plain_string(duk_json_dec_ctx *js_ctx) {
#endif /* DUK_USE_JX */
#if defined(DUK_USE_JX)
-DUK_LOCAL void duk__dec_pointer(duk_json_dec_ctx *js_ctx) {
+DUK_LOCAL void duk__json_dec_pointer(duk_json_dec_ctx *js_ctx) {
duk_hthread *thr = js_ctx->thr;
const duk_uint8_t *p;
duk_small_int_t x;
@@ -36927,13 +37010,13 @@ DUK_LOCAL void duk__dec_pointer(duk_json_dec_ctx *js_ctx) {
return;
syntax_error:
- duk__dec_syntax_error(js_ctx);
+ duk__json_dec_syntax_error(js_ctx);
DUK_UNREACHABLE();
}
#endif /* DUK_USE_JX */
#if defined(DUK_USE_JX)
-DUK_LOCAL void duk__dec_buffer(duk_json_dec_ctx *js_ctx) {
+DUK_LOCAL void duk__json_dec_buffer(duk_json_dec_ctx *js_ctx) {
duk_hthread *thr = js_ctx->thr;
const duk_uint8_t *p;
duk_uint8_t *buf;
@@ -36985,13 +37068,13 @@ DUK_LOCAL void duk__dec_buffer(duk_json_dec_ctx *js_ctx) {
return;
syntax_error:
- duk__dec_syntax_error(js_ctx);
+ duk__json_dec_syntax_error(js_ctx);
DUK_UNREACHABLE();
}
#endif /* DUK_USE_JX */
/* Parse a number, other than NaN or +/- Infinity */
-DUK_LOCAL void duk__dec_number(duk_json_dec_ctx *js_ctx) {
+DUK_LOCAL void duk__json_dec_number(duk_json_dec_ctx *js_ctx) {
duk_hthread *thr = js_ctx->thr;
const duk_uint8_t *p_start;
const duk_uint8_t *p;
@@ -37047,7 +37130,7 @@ DUK_LOCAL void duk__dec_number(duk_json_dec_ctx *js_ctx) {
(duk_tval *) duk_get_tval(thr, -1)));
duk_numconv_parse(thr, 10 /*radix*/, s2n_flags);
if (duk_is_nan(thr, -1)) {
- duk__dec_syntax_error(js_ctx);
+ duk__json_dec_syntax_error(js_ctx);
}
DUK_ASSERT(duk_is_number(thr, -1));
DUK_DDD(DUK_DDDPRINT("parse_number: final number: %!T",
@@ -37056,22 +37139,24 @@ DUK_LOCAL void duk__dec_number(duk_json_dec_ctx *js_ctx) {
/* [ ... num ] */
}
-DUK_LOCAL void duk__dec_objarr_entry(duk_json_dec_ctx *js_ctx) {
+DUK_LOCAL void duk__json_dec_objarr_entry(duk_json_dec_ctx *js_ctx) {
duk_hthread *thr = js_ctx->thr;
duk_require_stack(thr, DUK_JSON_DEC_REQSTACK);
/* c recursion check */
+ duk_native_stack_check(thr);
+
DUK_ASSERT_DISABLE(js_ctx->recursion_depth >= 0); /* unsigned */
DUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);
if (js_ctx->recursion_depth >= js_ctx->recursion_limit) {
- DUK_ERROR_RANGE(thr, DUK_STR_JSONDEC_RECLIMIT);
+ DUK_ERROR_RANGE(thr, DUK_STR_DEC_RECLIMIT);
DUK_WO_NORETURN(return;);
}
js_ctx->recursion_depth++;
}
-DUK_LOCAL void duk__dec_objarr_exit(duk_json_dec_ctx *js_ctx) {
+DUK_LOCAL void duk__json_dec_objarr_exit(duk_json_dec_ctx *js_ctx) {
/* c recursion check */
DUK_ASSERT(js_ctx->recursion_depth > 0);
@@ -37079,14 +37164,14 @@ DUK_LOCAL void duk__dec_objarr_exit(duk_json_dec_ctx *js_ctx) {
js_ctx->recursion_depth--;
}
-DUK_LOCAL void duk__dec_object(duk_json_dec_ctx *js_ctx) {
+DUK_LOCAL void duk__json_dec_object(duk_json_dec_ctx *js_ctx) {
duk_hthread *thr = js_ctx->thr;
duk_int_t key_count; /* XXX: a "first" flag would suffice */
duk_uint8_t x;
DUK_DDD(DUK_DDDPRINT("parse_object"));
- duk__dec_objarr_entry(js_ctx);
+ duk__json_dec_objarr_entry(js_ctx);
duk_push_object(thr);
@@ -37094,7 +37179,7 @@ DUK_LOCAL void duk__dec_object(duk_json_dec_ctx *js_ctx) {
key_count = 0;
for (;;) {
- x = duk__dec_get_nonwhite(js_ctx);
+ x = duk__json_dec_get_nonwhite(js_ctx);
DUK_DDD(DUK_DDDPRINT("parse_object: obj=%!T, x=%ld, key_count=%ld",
(duk_tval *) duk_get_tval(thr, -1),
@@ -37104,7 +37189,7 @@ DUK_LOCAL void duk__dec_object(duk_json_dec_ctx *js_ctx) {
if (x == DUK_ASC_COMMA && key_count > 0) {
/* accept comma, expect new value */
- x = duk__dec_get_nonwhite(js_ctx);
+ x = duk__json_dec_get_nonwhite(js_ctx);
} else if (x == DUK_ASC_RCURLY) {
/* eat closing brace */
break;
@@ -37121,11 +37206,11 @@ DUK_LOCAL void duk__dec_object(duk_json_dec_ctx *js_ctx) {
/* parse key and value */
if (x == DUK_ASC_DOUBLEQUOTE) {
- duk__dec_string(js_ctx);
+ duk__json_dec_string(js_ctx);
#if defined(DUK_USE_JX)
} else if (js_ctx->flag_ext_custom &&
duk_unicode_is_identifier_start((duk_codepoint_t) x)) {
- duk__dec_plain_string(js_ctx);
+ duk__json_dec_plain_string(js_ctx);
#endif
} else {
goto syntax_error;
@@ -37133,12 +37218,12 @@ DUK_LOCAL void duk__dec_object(duk_json_dec_ctx *js_ctx) {
/* [ ... obj key ] */
- x = duk__dec_get_nonwhite(js_ctx);
+ x = duk__json_dec_get_nonwhite(js_ctx);
if (x != DUK_ASC_COLON) {
goto syntax_error;
}
- duk__dec_value(js_ctx);
+ duk__json_dec_value(js_ctx);
/* [ ... obj key val ] */
@@ -37154,22 +37239,22 @@ DUK_LOCAL void duk__dec_object(duk_json_dec_ctx *js_ctx) {
DUK_DDD(DUK_DDDPRINT("parse_object: final object is %!T",
(duk_tval *) duk_get_tval(thr, -1)));
- duk__dec_objarr_exit(js_ctx);
+ duk__json_dec_objarr_exit(js_ctx);
return;
syntax_error:
- duk__dec_syntax_error(js_ctx);
+ duk__json_dec_syntax_error(js_ctx);
DUK_UNREACHABLE();
}
-DUK_LOCAL void duk__dec_array(duk_json_dec_ctx *js_ctx) {
+DUK_LOCAL void duk__json_dec_array(duk_json_dec_ctx *js_ctx) {
duk_hthread *thr = js_ctx->thr;
duk_uarridx_t arr_idx;
duk_uint8_t x;
DUK_DDD(DUK_DDDPRINT("parse_array"));
- duk__dec_objarr_entry(js_ctx);
+ duk__json_dec_objarr_entry(js_ctx);
duk_push_array(thr);
@@ -37177,7 +37262,7 @@ DUK_LOCAL void duk__dec_array(duk_json_dec_ctx *js_ctx) {
arr_idx = 0;
for (;;) {
- x = duk__dec_get_nonwhite(js_ctx);
+ x = duk__json_dec_get_nonwhite(js_ctx);
DUK_DDD(DUK_DDDPRINT("parse_array: arr=%!T, x=%ld, arr_idx=%ld",
(duk_tval *) duk_get_tval(thr, -1),
@@ -37193,7 +37278,7 @@ DUK_LOCAL void duk__dec_array(duk_json_dec_ctx *js_ctx) {
break;
} else if (arr_idx == 0) {
/* accept anything, expect first value (EOF will be
- * caught by duk__dec_value() below.
+ * caught by duk__json_dec_value() below.
*/
js_ctx->p--; /* backtrack (safe) */
} else {
@@ -37203,7 +37288,7 @@ DUK_LOCAL void duk__dec_array(duk_json_dec_ctx *js_ctx) {
/* parse value */
- duk__dec_value(js_ctx);
+ duk__json_dec_value(js_ctx);
/* [ ... arr val ] */
@@ -37222,30 +37307,30 @@ DUK_LOCAL void duk__dec_array(duk_json_dec_ctx *js_ctx) {
DUK_DDD(DUK_DDDPRINT("parse_array: final array is %!T",
(duk_tval *) duk_get_tval(thr, -1)));
- duk__dec_objarr_exit(js_ctx);
+ duk__json_dec_objarr_exit(js_ctx);
return;
syntax_error:
- duk__dec_syntax_error(js_ctx);
+ duk__json_dec_syntax_error(js_ctx);
DUK_UNREACHABLE();
}
-DUK_LOCAL void duk__dec_value(duk_json_dec_ctx *js_ctx) {
+DUK_LOCAL void duk__json_dec_value(duk_json_dec_ctx *js_ctx) {
duk_hthread *thr = js_ctx->thr;
duk_uint8_t x;
- x = duk__dec_get_nonwhite(js_ctx);
+ x = duk__json_dec_get_nonwhite(js_ctx);
DUK_DDD(DUK_DDDPRINT("parse_value: initial x=%ld", (long) x));
- /* Note: duk__dec_req_stridx() backtracks one char */
+ /* Note: duk__json_dec_req_stridx() backtracks one char */
if (x == DUK_ASC_DOUBLEQUOTE) {
- duk__dec_string(js_ctx);
+ duk__json_dec_string(js_ctx);
} else if ((x >= DUK_ASC_0 && x <= DUK_ASC_9) || (x == DUK_ASC_MINUS)) {
#if defined(DUK_USE_JX)
- if (js_ctx->flag_ext_custom && x == DUK_ASC_MINUS && duk__dec_peek(js_ctx) == DUK_ASC_UC_I) {
- duk__dec_req_stridx(js_ctx, DUK_STRIDX_MINUS_INFINITY); /* "-Infinity", '-' has been eaten */
+ if (js_ctx->flag_ext_custom && x == DUK_ASC_MINUS && duk__json_dec_peek(js_ctx) == DUK_ASC_UC_I) {
+ duk__json_dec_req_stridx(js_ctx, DUK_STRIDX_MINUS_INFINITY); /* "-Infinity", '-' has been eaten */
duk_push_number(thr, -DUK_DOUBLE_INFINITY);
} else {
#else
@@ -37253,60 +37338,63 @@ DUK_LOCAL void duk__dec_value(duk_json_dec_ctx *js_ctx) {
#endif
/* We already ate 'x', so backup one byte. */
js_ctx->p--; /* safe */
- duk__dec_number(js_ctx);
+ duk__json_dec_number(js_ctx);
}
} else if (x == DUK_ASC_LC_T) {
- duk__dec_req_stridx(js_ctx, DUK_STRIDX_TRUE);
+ duk__json_dec_req_stridx(js_ctx, DUK_STRIDX_TRUE);
duk_push_true(thr);
} else if (x == DUK_ASC_LC_F) {
- duk__dec_req_stridx(js_ctx, DUK_STRIDX_FALSE);
+ duk__json_dec_req_stridx(js_ctx, DUK_STRIDX_FALSE);
duk_push_false(thr);
} else if (x == DUK_ASC_LC_N) {
- duk__dec_req_stridx(js_ctx, DUK_STRIDX_LC_NULL);
+ duk__json_dec_req_stridx(js_ctx, DUK_STRIDX_LC_NULL);
duk_push_null(thr);
#if defined(DUK_USE_JX)
} else if (js_ctx->flag_ext_custom && x == DUK_ASC_LC_U) {
- duk__dec_req_stridx(js_ctx, DUK_STRIDX_LC_UNDEFINED);
+ duk__json_dec_req_stridx(js_ctx, DUK_STRIDX_LC_UNDEFINED);
duk_push_undefined(thr);
} else if (js_ctx->flag_ext_custom && x == DUK_ASC_UC_N) {
- duk__dec_req_stridx(js_ctx, DUK_STRIDX_NAN);
+ duk__json_dec_req_stridx(js_ctx, DUK_STRIDX_NAN);
duk_push_nan(thr);
} else if (js_ctx->flag_ext_custom && x == DUK_ASC_UC_I) {
- duk__dec_req_stridx(js_ctx, DUK_STRIDX_INFINITY);
+ duk__json_dec_req_stridx(js_ctx, DUK_STRIDX_INFINITY);
duk_push_number(thr, DUK_DOUBLE_INFINITY);
} else if (js_ctx->flag_ext_custom && x == DUK_ASC_LPAREN) {
- duk__dec_pointer(js_ctx);
+ duk__json_dec_pointer(js_ctx);
} else if (js_ctx->flag_ext_custom && x == DUK_ASC_PIPE) {
- duk__dec_buffer(js_ctx);
+ duk__json_dec_buffer(js_ctx);
#endif
} else if (x == DUK_ASC_LCURLY) {
- duk__dec_object(js_ctx);
+ duk__json_dec_object(js_ctx);
} else if (x == DUK_ASC_LBRACKET) {
- duk__dec_array(js_ctx);
+ duk__json_dec_array(js_ctx);
} else {
/* catches EOF (NUL) */
goto syntax_error;
}
- duk__dec_eat_white(js_ctx);
+ duk__json_dec_eat_white(js_ctx);
/* [ ... val ] */
return;
syntax_error:
- duk__dec_syntax_error(js_ctx);
+ duk__json_dec_syntax_error(js_ctx);
DUK_UNREACHABLE();
}
-/* Recursive value reviver, implements the Walk() algorithm. No C recursion
- * check is done here because the initial parsing step will already ensure
- * there is a reasonable limit on C recursion depth and hence object depth.
+/* Recursive value reviver, implements the Walk() algorithm. The parsing
+ * step ensures there is a reasonable depth limit to the input. However,
+ * the reviver may create more depth by editing object or array entries, so
+ * we have both C recursion limit and native stack checks here.
*/
-DUK_LOCAL void duk__dec_reviver_walk(duk_json_dec_ctx *js_ctx) {
+DUK_LOCAL void duk__json_dec_reviver_walk(duk_json_dec_ctx *js_ctx) {
duk_hthread *thr = js_ctx->thr;
duk_hobject *h;
duk_uarridx_t i, arr_len;
+ duk__json_dec_objarr_entry(js_ctx);
+
DUK_DDD(DUK_DDDPRINT("walk: top=%ld, holder=%!T, name=%!T",
(long) duk_get_top(thr),
(duk_tval *) duk_get_tval(thr, -2),
@@ -37329,7 +37417,7 @@ DUK_LOCAL void duk__dec_reviver_walk(duk_json_dec_ctx *js_ctx) {
duk_dup_top(thr);
(void) duk_push_uint_to_hstring(thr, (duk_uint_t) i); /* -> [ ... holder name val val ToString(i) ] */
- duk__dec_reviver_walk(js_ctx); /* -> [ ... holder name val new_elem ] */
+ duk__json_dec_reviver_walk(js_ctx); /* -> [ ... holder name val new_elem ] */
if (duk_is_undefined(thr, -1)) {
duk_pop(thr);
@@ -37356,7 +37444,7 @@ DUK_LOCAL void duk__dec_reviver_walk(duk_json_dec_ctx *js_ctx) {
duk_dup_m2(thr);
/* [ ... holder name val enum obj_key val obj_key ] */
- duk__dec_reviver_walk(js_ctx);
+ duk__json_dec_reviver_walk(js_ctx);
/* [ ... holder name val enum obj_key new_elem ] */
if (duk_is_undefined(thr, -1)) {
@@ -37385,6 +37473,8 @@ DUK_LOCAL void duk__dec_reviver_walk(duk_json_dec_ctx *js_ctx) {
duk_insert(thr, -4); /* -> [ ... reviver holder name val ] */
duk_call_method(thr, 2); /* -> [ ... res ] */
+ duk__json_dec_objarr_exit(js_ctx);
+
DUK_DDD(DUK_DDDPRINT("walk: top=%ld, result=%!T",
(long) duk_get_top(thr), (duk_tval *) duk_get_tval(thr, -1)));
}
@@ -37494,7 +37584,7 @@ DUK_LOCAL duk_uint8_t *duk__emit_esc_auto_fast(duk_json_enc_ctx *js_ctx, duk_uin
return q;
}
-DUK_LOCAL void duk__enc_key_autoquote(duk_json_enc_ctx *js_ctx, duk_hstring *k) {
+DUK_LOCAL void duk__json_enc_key_autoquote(duk_json_enc_ctx *js_ctx, duk_hstring *k) {
const duk_int8_t *p, *p_start, *p_end; /* Note: intentionally signed. */
duk_size_t k_len;
duk_codepoint_t cp;
@@ -37537,7 +37627,7 @@ DUK_LOCAL void duk__enc_key_autoquote(duk_json_enc_ctx *js_ctx, duk_hstring *k)
}
quote_normally:
- duk__enc_quote_string(js_ctx, k);
+ duk__json_enc_quote_string(js_ctx, k);
}
/* The Quote(value) operation: quote a string.
@@ -37545,13 +37635,13 @@ DUK_LOCAL void duk__enc_key_autoquote(duk_json_enc_ctx *js_ctx, duk_hstring *k)
* Stack policy: [ ] -> [ ].
*/
-DUK_LOCAL void duk__enc_quote_string(duk_json_enc_ctx *js_ctx, duk_hstring *h_str) {
+DUK_LOCAL void duk__json_enc_quote_string(duk_json_enc_ctx *js_ctx, duk_hstring *h_str) {
duk_hthread *thr = js_ctx->thr;
const duk_uint8_t *p, *p_start, *p_end, *p_now, *p_tmp;
duk_uint8_t *q;
duk_ucodepoint_t cp; /* typed for duk_unicode_decode_xutf8() */
- DUK_DDD(DUK_DDDPRINT("duk__enc_quote_string: h_str=%!O", (duk_heaphdr *) h_str));
+ DUK_DDD(DUK_DDDPRINT("duk__json_enc_quote_string: h_str=%!O", (duk_heaphdr *) h_str));
DUK_ASSERT(h_str != NULL);
p_start = DUK_HSTRING_GET_DATA(h_str);
@@ -37682,7 +37772,7 @@ DUK_LOCAL void duk__enc_quote_string(duk_json_enc_ctx *js_ctx, duk_hstring *h_st
/* Encode a double (checked by caller) from stack top. Stack top may be
* replaced by serialized string but is not popped (caller does that).
*/
-DUK_LOCAL void duk__enc_double(duk_json_enc_ctx *js_ctx) {
+DUK_LOCAL void duk__json_enc_double(duk_json_enc_ctx *js_ctx) {
duk_hthread *thr;
duk_tval *tv;
duk_double_t d;
@@ -37746,7 +37836,7 @@ DUK_LOCAL void duk__enc_double(duk_json_enc_ctx *js_ctx) {
#if defined(DUK_USE_FASTINT)
/* Encode a fastint from duk_tval ptr, no value stack effects. */
-DUK_LOCAL void duk__enc_fastint_tval(duk_json_enc_ctx *js_ctx, duk_tval *tv) {
+DUK_LOCAL void duk__json_enc_fastint_tval(duk_json_enc_ctx *js_ctx, duk_tval *tv) {
duk_int64_t v;
/* Fastint range is signed 48-bit so longest value is -2^47 = -140737488355328
@@ -37771,7 +37861,7 @@ DUK_LOCAL void duk__enc_fastint_tval(duk_json_enc_ctx *js_ctx, duk_tval *tv) {
#if defined(DUK_USE_JX) || defined(DUK_USE_JC)
#if defined(DUK_USE_HEX_FASTPATH)
-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 duk_uint8_t *duk__json_enc_buffer_data_hex(const duk_uint8_t *src, duk_size_t src_len, duk_uint8_t *dst) {
duk_uint8_t *q;
duk_uint16_t *q16;
duk_small_uint_t x;
@@ -37829,7 +37919,7 @@ DUK_LOCAL duk_uint8_t *duk__enc_buffer_data_hex(const duk_uint8_t *src, duk_size
return q;
}
#else /* DUK_USE_HEX_FASTPATH */
-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 duk_uint8_t *duk__json_enc_buffer_data_hex(const duk_uint8_t *src, duk_size_t src_len, duk_uint8_t *dst) {
const duk_uint8_t *p;
const duk_uint8_t *p_end;
duk_uint8_t *q;
@@ -37848,7 +37938,7 @@ DUK_LOCAL duk_uint8_t *duk__enc_buffer_data_hex(const duk_uint8_t *src, duk_size
}
#endif /* DUK_USE_HEX_FASTPATH */
-DUK_LOCAL void duk__enc_buffer_data(duk_json_enc_ctx *js_ctx, duk_uint8_t *buf_data, duk_size_t buf_len) {
+DUK_LOCAL void duk__json_enc_buffer_data(duk_json_enc_ctx *js_ctx, duk_uint8_t *buf_data, duk_size_t buf_len) {
duk_hthread *thr;
duk_uint8_t *q;
duk_size_t space;
@@ -37880,7 +37970,7 @@ DUK_LOCAL void duk__enc_buffer_data(duk_json_enc_ctx *js_ctx, duk_uint8_t *buf_d
#if defined(DUK_USE_JX)
{
*q++ = DUK_ASC_PIPE;
- q = duk__enc_buffer_data_hex(buf_data, buf_len, q);
+ q = duk__json_enc_buffer_data_hex(buf_data, buf_len, q);
*q++ = DUK_ASC_PIPE;
}
@@ -37893,7 +37983,7 @@ DUK_LOCAL void duk__enc_buffer_data(duk_json_enc_ctx *js_ctx, duk_uint8_t *buf_d
DUK_ASSERT(js_ctx->flag_ext_compatible);
duk_memcpy((void *) q, (const void *) "{\"_buf\":\"", 9); /* len: 9 */
q += 9;
- q = duk__enc_buffer_data_hex(buf_data, buf_len, q);
+ q = duk__json_enc_buffer_data_hex(buf_data, buf_len, q);
*q++ = DUK_ASC_DOUBLEQUOTE;
*q++ = DUK_ASC_RCURLY;
}
@@ -37902,15 +37992,15 @@ DUK_LOCAL void duk__enc_buffer_data(duk_json_enc_ctx *js_ctx, duk_uint8_t *buf_d
DUK_BW_SET_PTR(thr, &js_ctx->bw, q);
}
-DUK_LOCAL void duk__enc_buffer_jx_jc(duk_json_enc_ctx *js_ctx, duk_hbuffer *h) {
- duk__enc_buffer_data(js_ctx,
+DUK_LOCAL void duk__json_enc_buffer_jx_jc(duk_json_enc_ctx *js_ctx, duk_hbuffer *h) {
+ duk__json_enc_buffer_data(js_ctx,
(duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(js_ctx->thr->heap, h),
(duk_size_t) DUK_HBUFFER_GET_SIZE(h));
}
#endif /* DUK_USE_JX || DUK_USE_JC */
#if defined(DUK_USE_JSON_STRINGIFY_FASTPATH)
-DUK_LOCAL void duk__enc_buffer_json_fastpath(duk_json_enc_ctx *js_ctx, duk_hbuffer *h) {
+DUK_LOCAL void duk__json_enc_buffer_json_fastpath(duk_json_enc_ctx *js_ctx, duk_hbuffer *h) {
duk_size_t i, n;
const duk_uint8_t *buf;
duk_uint8_t *q;
@@ -37934,7 +38024,7 @@ DUK_LOCAL void duk__enc_buffer_json_fastpath(duk_json_enc_ctx *js_ctx, duk_hbuff
buf = (const duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(js_ctx->thr->heap, h);
if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {
for (i = 0; i < n; i++) {
- duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth + 1);
+ duk__json_enc_newline_indent(js_ctx, js_ctx->recursion_depth + 1);
q = DUK_BW_ENSURE_GETPTR(js_ctx->thr, &js_ctx->bw, 32);
q += DUK_SPRINTF((char *) q, "\"%lu\": %u,", (unsigned long) i, (unsigned int) buf[i]);
DUK_BW_SET_PTR(js_ctx->thr, &js_ctx->bw, q);
@@ -37950,14 +38040,14 @@ DUK_LOCAL void duk__enc_buffer_json_fastpath(duk_json_enc_ctx *js_ctx, duk_hbuff
DUK__UNEMIT_1(js_ctx); /* eat trailing comma */
if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {
- duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth);
+ duk__json_enc_newline_indent(js_ctx, js_ctx->recursion_depth);
}
DUK__EMIT_1(js_ctx, DUK_ASC_RCURLY);
}
#endif /* DUK_USE_JSON_STRINGIFY_FASTPATH */
#if defined(DUK_USE_JX) || defined(DUK_USE_JC)
-DUK_LOCAL void duk__enc_pointer(duk_json_enc_ctx *js_ctx, void *ptr) {
+DUK_LOCAL void duk__json_enc_pointer(duk_json_enc_ctx *js_ctx, void *ptr) {
char buf[64]; /* XXX: how to figure correct size? */
const char *fmt;
@@ -37995,14 +38085,14 @@ DUK_LOCAL void duk__enc_pointer(duk_json_enc_ctx *js_ctx, void *ptr) {
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
#if defined(DUK_USE_JX) || defined(DUK_USE_JC)
-DUK_LOCAL void duk__enc_bufobj(duk_json_enc_ctx *js_ctx, duk_hbufobj *h_bufobj) {
+DUK_LOCAL void duk__json_enc_bufobj(duk_json_enc_ctx *js_ctx, duk_hbufobj *h_bufobj) {
DUK_HBUFOBJ_ASSERT_VALID(h_bufobj);
if (h_bufobj->buf == NULL || !DUK_HBUFOBJ_VALID_SLICE(h_bufobj)) {
DUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL);
} else {
/* Handle both full and partial slice (as long as covered). */
- duk__enc_buffer_data(js_ctx,
+ duk__json_enc_buffer_data(js_ctx,
(duk_uint8_t *) DUK_HBUFOBJ_GET_SLICE_BASE(js_ctx->thr->heap, h_bufobj),
(duk_size_t) h_bufobj->length);
}
@@ -38014,7 +38104,7 @@ DUK_LOCAL void duk__enc_bufobj(duk_json_enc_ctx *js_ctx, duk_hbufobj *h_bufobj)
* directly related to indent depth.
*/
#if defined(DUK_USE_PREFER_SIZE)
-DUK_LOCAL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t depth) {
+DUK_LOCAL void duk__json_enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t depth) {
DUK_ASSERT(js_ctx->h_gap != NULL);
DUK_ASSERT(DUK_HSTRING_GET_BYTELEN(js_ctx->h_gap) > 0); /* caller guarantees */
@@ -38024,7 +38114,7 @@ DUK_LOCAL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t dept
}
}
#else /* DUK_USE_PREFER_SIZE */
-DUK_LOCAL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t depth) {
+DUK_LOCAL void duk__json_enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t depth) {
const duk_uint8_t *gap_data;
duk_size_t gap_len;
duk_size_t avail_bytes; /* bytes of indent available for copying */
@@ -38077,13 +38167,14 @@ DUK_LOCAL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t dept
#endif /* DUK_USE_PREFER_SIZE */
/* Shared entry handling for object/array serialization. */
-DUK_LOCAL void duk__enc_objarr_entry(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top) {
+DUK_LOCAL void duk__json_enc_objarr_entry(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top) {
duk_hthread *thr = js_ctx->thr;
duk_hobject *h_target;
duk_uint_fast32_t i, n;
*entry_top = duk_get_top(thr);
+ duk_native_stack_check(thr);
duk_require_stack(thr, DUK_JSON_ENC_REQSTACK);
/* Loop check using a hybrid approach: a fixed-size visited[] array
@@ -38121,7 +38212,7 @@ DUK_LOCAL void duk__enc_objarr_entry(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_
DUK_ASSERT_DISABLE(js_ctx->recursion_depth >= 0); /* unsigned */
DUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);
if (js_ctx->recursion_depth >= js_ctx->recursion_limit) {
- DUK_ERROR_RANGE(thr, DUK_STR_JSONENC_RECLIMIT);
+ DUK_ERROR_RANGE(thr, DUK_STR_ENC_RECLIMIT);
DUK_WO_NORETURN(return;);
}
js_ctx->recursion_depth++;
@@ -38131,7 +38222,7 @@ DUK_LOCAL void duk__enc_objarr_entry(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_
}
/* Shared exit handling for object/array serialization. */
-DUK_LOCAL void duk__enc_objarr_exit(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top) {
+DUK_LOCAL void duk__json_enc_objarr_exit(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top) {
duk_hthread *thr = js_ctx->thr;
duk_hobject *h_target;
@@ -38163,7 +38254,7 @@ DUK_LOCAL void duk__enc_objarr_exit(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_t
*
* Stack policy: [ object ] -> [ object ].
*/
-DUK_LOCAL void duk__enc_object(duk_json_enc_ctx *js_ctx) {
+DUK_LOCAL void duk__json_enc_object(duk_json_enc_ctx *js_ctx) {
duk_hthread *thr = js_ctx->thr;
duk_hstring *h_key;
duk_idx_t entry_top;
@@ -38173,9 +38264,9 @@ DUK_LOCAL void duk__enc_object(duk_json_enc_ctx *js_ctx) {
duk_uarridx_t arr_len, i;
duk_size_t prev_size;
- DUK_DDD(DUK_DDDPRINT("duk__enc_object: obj=%!T", (duk_tval *) duk_get_tval(thr, -1)));
+ DUK_DDD(DUK_DDDPRINT("duk__json_enc_object: obj=%!T", (duk_tval *) duk_get_tval(thr, -1)));
- duk__enc_objarr_entry(js_ctx, &entry_top);
+ duk__json_enc_objarr_entry(js_ctx, &entry_top);
idx_obj = entry_top - 1;
@@ -38217,17 +38308,17 @@ DUK_LOCAL void duk__enc_object(duk_json_enc_ctx *js_ctx) {
prev_size = DUK_BW_GET_SIZE(js_ctx->thr, &js_ctx->bw);
if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {
- duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth);
- duk__enc_key_autoquote(js_ctx, h_key);
+ duk__json_enc_newline_indent(js_ctx, js_ctx->recursion_depth);
+ duk__json_enc_key_autoquote(js_ctx, h_key);
DUK__EMIT_2(js_ctx, DUK_ASC_COLON, DUK_ASC_SPACE);
} else {
- duk__enc_key_autoquote(js_ctx, h_key);
+ duk__json_enc_key_autoquote(js_ctx, h_key);
DUK__EMIT_1(js_ctx, DUK_ASC_COLON);
}
/* [ ... key ] */
- if (DUK_UNLIKELY(duk__enc_value(js_ctx, idx_obj) == 0)) {
+ if (DUK_UNLIKELY(duk__json_enc_value(js_ctx, idx_obj) == 0)) {
/* Value would yield 'undefined', so skip key altogether.
* Side effects have already happened.
*/
@@ -38245,12 +38336,12 @@ DUK_LOCAL void duk__enc_object(duk_json_enc_ctx *js_ctx) {
DUK__UNEMIT_1(js_ctx); /* eat trailing comma */
if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {
DUK_ASSERT(js_ctx->recursion_depth >= 1);
- duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U);
+ duk__json_enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U);
}
}
DUK__EMIT_1(js_ctx, DUK_ASC_RCURLY);
- duk__enc_objarr_exit(js_ctx, &entry_top);
+ duk__json_enc_objarr_exit(js_ctx, &entry_top);
DUK_ASSERT_TOP(thr, entry_top);
}
@@ -38259,17 +38350,17 @@ DUK_LOCAL void duk__enc_object(duk_json_enc_ctx *js_ctx) {
*
* Stack policy: [ array ] -> [ array ].
*/
-DUK_LOCAL void duk__enc_array(duk_json_enc_ctx *js_ctx) {
+DUK_LOCAL void duk__json_enc_array(duk_json_enc_ctx *js_ctx) {
duk_hthread *thr = js_ctx->thr;
duk_idx_t entry_top;
duk_idx_t idx_arr;
duk_bool_t emitted;
duk_uarridx_t i, arr_len;
- DUK_DDD(DUK_DDDPRINT("duk__enc_array: array=%!T",
+ DUK_DDD(DUK_DDDPRINT("duk__json_enc_array: array=%!T",
(duk_tval *) duk_get_tval(thr, -1)));
- duk__enc_objarr_entry(js_ctx, &entry_top);
+ duk__json_enc_objarr_entry(js_ctx, &entry_top);
idx_arr = entry_top - 1;
@@ -38286,14 +38377,14 @@ DUK_LOCAL void duk__enc_array(duk_json_enc_ctx *js_ctx) {
if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {
DUK_ASSERT(js_ctx->recursion_depth >= 1);
- duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth);
+ duk__json_enc_newline_indent(js_ctx, js_ctx->recursion_depth);
}
(void) duk_push_uint_to_hstring(thr, (duk_uint_t) i); /* -> [ ... key ] */
/* [ ... key ] */
- if (DUK_UNLIKELY(duk__enc_value(js_ctx, idx_arr) == 0)) {
+ if (DUK_UNLIKELY(duk__json_enc_value(js_ctx, idx_arr) == 0)) {
/* Value would normally be omitted, replace with 'null'. */
DUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL);
} else {
@@ -38311,12 +38402,12 @@ DUK_LOCAL void duk__enc_array(duk_json_enc_ctx *js_ctx) {
DUK__UNEMIT_1(js_ctx); /* eat trailing comma */
if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {
DUK_ASSERT(js_ctx->recursion_depth >= 1);
- duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U);
+ duk__json_enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U);
}
}
DUK__EMIT_1(js_ctx, DUK_ASC_RBRACKET);
- duk__enc_objarr_exit(js_ctx, &entry_top);
+ duk__json_enc_objarr_exit(js_ctx, &entry_top);
DUK_ASSERT_TOP(thr, entry_top);
}
@@ -38325,14 +38416,14 @@ DUK_LOCAL void duk__enc_array(duk_json_enc_ctx *js_ctx) {
*
* Stack policy: [ ... key ] -> [ ... ]
*/
-DUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_holder) {
+DUK_LOCAL duk_bool_t duk__json_enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_holder) {
duk_hthread *thr = js_ctx->thr;
duk_tval *tv;
duk_tval *tv_holder;
duk_tval *tv_key;
duk_small_int_t c;
- DUK_DDD(DUK_DDDPRINT("duk__enc_value: idx_holder=%ld, holder=%!T, key=%!T",
+ DUK_DDD(DUK_DDDPRINT("duk__json_enc_value: idx_holder=%ld, holder=%!T, key=%!T",
(long) idx_holder, (duk_tval *) duk_get_tval(thr, idx_holder),
(duk_tval *) duk_get_tval(thr, -1)));
@@ -38402,7 +38493,7 @@ DUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_hold
duk_hbufobj *h_bufobj;
h_bufobj = (duk_hbufobj *) h;
DUK_HBUFOBJ_ASSERT_VALID(h_bufobj);
- duk__enc_bufobj(js_ctx, h_bufobj);
+ duk__json_enc_bufobj(js_ctx, h_bufobj);
goto pop2_emitted;
}
/* Otherwise bufferobjects get serialized as normal objects. */
@@ -38498,7 +38589,7 @@ DUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_hold
#if defined(DUK_USE_JX) || defined(DUK_USE_JC)
/* When JX/JC not in use, the type mask above will avoid this case if needed. */
case DUK_TAG_POINTER: {
- duk__enc_pointer(js_ctx, DUK_TVAL_GET_POINTER(tv));
+ duk__json_enc_pointer(js_ctx, DUK_TVAL_GET_POINTER(tv));
break;
}
#endif /* DUK_USE_JX || DUK_USE_JC */
@@ -38508,7 +38599,7 @@ DUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_hold
if (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {
goto pop2_undef;
}
- duk__enc_quote_string(js_ctx, h);
+ duk__json_enc_quote_string(js_ctx, h);
break;
}
case DUK_TAG_OBJECT: {
@@ -38521,9 +38612,9 @@ DUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_hold
DUK_ASSERT(!DUK_HOBJECT_IS_CALLABLE(h));
if (duk_js_isarray_hobject(h)) {
- duk__enc_array(js_ctx);
+ duk__json_enc_array(js_ctx);
} else {
- duk__enc_object(js_ctx);
+ duk__json_enc_object(js_ctx);
}
break;
}
@@ -38536,7 +38627,7 @@ DUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_hold
case DUK_TAG_BUFFER: {
#if defined(DUK_USE_JX) || defined(DUK_USE_JC)
if (js_ctx->flag_ext_custom_or_compatible) {
- duk__enc_buffer_jx_jc(js_ctx, DUK_TVAL_GET_BUFFER(tv));
+ duk__json_enc_buffer_jx_jc(js_ctx, DUK_TVAL_GET_BUFFER(tv));
break;
}
#endif
@@ -38545,7 +38636,7 @@ DUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_hold
* to handle realloc side effects correctly.
*/
duk_to_object(thr, -1);
- duk__enc_object(js_ctx);
+ duk__json_enc_object(js_ctx);
break;
}
case DUK_TAG_LIGHTFUNC: {
@@ -38564,7 +38655,7 @@ DUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_hold
/* Number serialization has a significant impact relative to
* other fast path code, so careful fast path for fastints.
*/
- duk__enc_fastint_tval(js_ctx, tv);
+ duk__json_enc_fastint_tval(js_ctx, tv);
break;
#endif
default: {
@@ -38574,7 +38665,7 @@ DUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_hold
/* XXX: A fast path for usual integers would be useful when
* fastint support is not enabled.
*/
- duk__enc_double(js_ctx);
+ duk__json_enc_double(js_ctx);
break;
}
}
@@ -38591,7 +38682,7 @@ DUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_hold
}
/* E5 Section 15.12.3, main algorithm, step 4.b.ii steps 1-4. */
-DUK_LOCAL duk_bool_t duk__enc_allow_into_proplist(duk_tval *tv) {
+DUK_LOCAL duk_bool_t duk__json_enc_allow_into_proplist(duk_tval *tv) {
duk_small_int_t c;
/* XXX: some kind of external internal type checker?
@@ -38674,7 +38765,7 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du
if (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {
goto emit_undefined;
}
- duk__enc_quote_string(js_ctx, h);
+ duk__json_enc_quote_string(js_ctx, h);
break;
}
case DUK_TAG_OBJECT: {
@@ -38719,7 +38810,7 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du
DUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);
if (js_ctx->recursion_depth >= js_ctx->recursion_limit) {
DUK_DD(DUK_DDPRINT("fast path recursion limit"));
- DUK_ERROR_RANGE(js_ctx->thr, DUK_STR_JSONDEC_RECLIMIT);
+ DUK_ERROR_RANGE(js_ctx->thr, DUK_STR_DEC_RECLIMIT);
DUK_WO_NORETURN(return 0;);
}
@@ -38846,11 +38937,11 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du
prev_size = DUK_BW_GET_SIZE(js_ctx->thr, &js_ctx->bw);
if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {
- duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth);
- duk__enc_key_autoquote(js_ctx, k);
+ duk__json_enc_newline_indent(js_ctx, js_ctx->recursion_depth);
+ duk__json_enc_key_autoquote(js_ctx, k);
DUK__EMIT_2(js_ctx, DUK_ASC_COLON, DUK_ASC_SPACE);
} else {
- duk__enc_key_autoquote(js_ctx, k);
+ duk__json_enc_key_autoquote(js_ctx, k);
DUK__EMIT_1(js_ctx, DUK_ASC_COLON);
}
@@ -38873,7 +38964,7 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du
DUK__UNEMIT_1(js_ctx); /* eat trailing comma */
if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {
DUK_ASSERT(js_ctx->recursion_depth >= 1);
- duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U);
+ duk__json_enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U);
}
}
DUK__EMIT_1(js_ctx, DUK_ASC_RCURLY);
@@ -38901,7 +38992,7 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du
duk_bool_t has_inherited;
if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {
- duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth);
+ duk__json_enc_newline_indent(js_ctx, js_ctx->recursion_depth);
}
if (DUK_LIKELY(i < asize)) {
@@ -38950,7 +39041,7 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du
DUK__UNEMIT_1(js_ctx); /* eat trailing comma */
if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {
DUK_ASSERT(js_ctx->recursion_depth >= 1);
- duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U);
+ duk__json_enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U);
}
}
DUK__EMIT_1(js_ctx, DUK_ASC_RBRACKET);
@@ -38992,7 +39083,7 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du
DUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_function);
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
} else if (c_bit & c_bufobj) {
- duk__enc_bufobj(js_ctx, (duk_hbufobj *) obj);
+ duk__json_enc_bufobj(js_ctx, (duk_hbufobj *) obj);
#endif
#endif
} else if (c_bit & c_abort) {
@@ -39032,7 +39123,7 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du
#if defined(DUK_USE_JX) || defined(DUK_USE_JC)
if (js_ctx->flag_ext_custom_or_compatible) {
- duk__enc_buffer_jx_jc(js_ctx, DUK_TVAL_GET_BUFFER(tv));
+ duk__json_enc_buffer_jx_jc(js_ctx, DUK_TVAL_GET_BUFFER(tv));
break;
}
#endif
@@ -39040,13 +39131,13 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du
/* Plain buffers mimic Uint8Arrays, and have enumerable index
* properties.
*/
- duk__enc_buffer_json_fastpath(js_ctx, DUK_TVAL_GET_BUFFER(tv));
+ duk__json_enc_buffer_json_fastpath(js_ctx, DUK_TVAL_GET_BUFFER(tv));
break;
}
case DUK_TAG_POINTER: {
#if defined(DUK_USE_JX) || defined(DUK_USE_JC)
if (js_ctx->flag_ext_custom_or_compatible) {
- duk__enc_pointer(js_ctx, DUK_TVAL_GET_POINTER(tv));
+ duk__json_enc_pointer(js_ctx, DUK_TVAL_GET_POINTER(tv));
break;
} else {
goto emit_undefined;
@@ -39068,7 +39159,7 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du
/* Number serialization has a significant impact relative to
* other fast path code, so careful fast path for fastints.
*/
- duk__enc_fastint_tval(js_ctx, tv);
+ duk__json_enc_fastint_tval(js_ctx, tv);
break;
}
#endif
@@ -39081,7 +39172,7 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du
/* XXX: Stack discipline is annoying, could be changed in numconv. */
duk_push_tval(js_ctx->thr, tv);
- duk__enc_double(js_ctx);
+ duk__json_enc_double(js_ctx);
duk_pop(js_ctx->thr);
#if 0
@@ -39193,14 +39284,15 @@ void duk_bi_json_parse_helper(duk_hthread *thr,
DUK_HSTRING_GET_BYTELEN(h_text);
DUK_ASSERT(*(js_ctx->p_end) == 0x00);
- duk__dec_value(js_ctx); /* -> [ ... value ] */
+ duk__json_dec_value(js_ctx); /* -> [ ... value ] */
+ DUK_ASSERT(js_ctx->recursion_depth == 0);
- /* Trailing whitespace has been eaten by duk__dec_value(), so if
+ /* Trailing whitespace has been eaten by duk__json_dec_value(), so if
* we're not at end of input here, it's a SyntaxError.
*/
if (js_ctx->p != js_ctx->p_end) {
- duk__dec_syntax_error(js_ctx);
+ duk__json_dec_syntax_error(js_ctx);
}
if (duk_is_callable(thr, idx_reviver)) {
@@ -39218,7 +39310,9 @@ void duk_bi_json_parse_helper(duk_hthread *thr,
(duk_tval *) duk_get_tval(thr, -2),
(duk_tval *) duk_get_tval(thr, -1)));
- duk__dec_reviver_walk(js_ctx); /* [ ... val root "" ] -> [ ... val val' ] */
+ DUK_ASSERT(js_ctx->recursion_depth == 0);
+ duk__json_dec_reviver_walk(js_ctx); /* [ ... val root "" ] -> [ ... val val' ] */
+ DUK_ASSERT(js_ctx->recursion_depth == 0);
duk_remove_m2(thr); /* -> [ ... val' ] */
} else {
DUK_DDD(DUK_DDDPRINT("reviver does not exist or is not callable: %!T",
@@ -39366,14 +39460,14 @@ void duk_bi_json_stringify_helper(duk_hthread *thr,
duk_uarridx_t plist_idx = 0;
duk_small_uint_t enum_flags;
- js_ctx->idx_proplist = duk_push_array(thr); /* XXX: array internal? */
+ js_ctx->idx_proplist = duk_push_bare_array(thr);
enum_flags = DUK_ENUM_ARRAY_INDICES_ONLY |
DUK_ENUM_SORT_ARRAY_INDICES; /* expensive flag */
duk_enum(thr, idx_replacer, enum_flags);
while (duk_next(thr, -1 /*enum_index*/, 1 /*get_value*/)) {
/* [ ... proplist enum_obj key val ] */
- if (duk__enc_allow_into_proplist(duk_get_tval(thr, -1))) {
+ if (duk__json_enc_allow_into_proplist(duk_get_tval(thr, -1))) {
/* XXX: duplicates should be eliminated here */
DUK_DDD(DUK_DDDPRINT("proplist enum: key=%!T, val=%!T --> accept",
(duk_tval *) duk_get_tval(thr, -2),
@@ -39533,7 +39627,7 @@ void duk_bi_json_stringify_helper(duk_hthread *thr,
js_ctx->recursion_limit = DUK_USE_JSON_ENC_RECLIMIT;
DUK_ASSERT(js_ctx->recursion_depth == 0);
- if (DUK_UNLIKELY(duk__enc_value(js_ctx, idx_holder) == 0)) { /* [ ... holder key ] -> [ ... holder ] */
+ if (DUK_UNLIKELY(duk__json_enc_value(js_ctx, idx_holder) == 0)) { /* [ ... holder key ] -> [ ... holder ] */
/* Result is undefined. */
duk_push_undefined(thr);
} else {
@@ -41436,7 +41530,9 @@ DUK_INTERNAL void duk_proxy_ownkeys_postprocess(duk_hthread *thr, duk_hobject *h
}
/* [ obj trap_result res_arr propname ] */
- duk_put_prop_index(thr, -2, idx++);
+ duk_push_uarridx(thr, idx++);
+ duk_insert(thr, -2);
+ duk_def_prop(thr, -3, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_SET_WEC);
continue;
skip_key:
@@ -42461,6 +42557,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_hthread *thr) {
#endif /* DUK_USE_REGEXP_SUPPORT */
const duk_uint8_t *p_start, *p_end, *p; /* input string scan */
const duk_uint8_t *q_start; /* match string */
+ duk_size_t p_blen;
duk_size_t q_blen;
#if defined(DUK_USE_REGEXP_SUPPORT)
@@ -42469,13 +42566,19 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_hthread *thr) {
p_start = DUK_HSTRING_GET_DATA(h_input);
p_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input);
+ p_blen = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h_input);
p = p_start;
h_search = duk_known_hstring(thr, 0);
q_start = DUK_HSTRING_GET_DATA(h_search);
q_blen = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h_search);
+ if (q_blen > p_blen) {
+ break; /* no match */
+ }
+
p_end -= q_blen; /* ensure full memcmp() fits in while */
+ DUK_ASSERT(p_end >= p);
match_start_coff = 0;
@@ -43290,44 +43393,65 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_locale_compare(duk_hthread *thr)
#if defined(DUK_USE_ES6)
DUK_INTERNAL duk_ret_t duk_bi_string_prototype_startswith_endswith(duk_hthread *thr) {
duk_int_t magic;
- duk_hstring *h;
+ duk_hstring *h_target;
+ duk_size_t blen_target;
duk_hstring *h_search;
duk_size_t blen_search;
- const duk_uint8_t *p_cmp_start;
- duk_bool_t result;
+ duk_int_t off;
+ duk_bool_t result = 0;
+ duk_size_t blen_left;
- h = duk_push_this_coercible_to_string(thr);
- DUK_ASSERT(h != NULL);
+ /* Because string byte lengths are in [0,DUK_INT_MAX] it's safe to
+ * subtract two string lengths without overflow.
+ */
+ DUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= DUK_INT_MAX);
+
+ h_target = duk_push_this_coercible_to_string(thr);
+ DUK_ASSERT(h_target != NULL);
h_search = duk__str_tostring_notregexp(thr, 0);
DUK_ASSERT(h_search != NULL);
magic = duk_get_current_magic(thr);
- p_cmp_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);
+ /* Careful to avoid pointer overflows in the matching logic. */
+
+ blen_target = DUK_HSTRING_GET_BYTELEN(h_target);
blen_search = DUK_HSTRING_GET_BYTELEN(h_search);
+#if 0
+ /* If search string is longer than the target string, we can
+ * never match. Could check explicitly, but should be handled
+ * correctly below.
+ */
+ if (blen_search > blen_target) {
+ goto finish;
+ }
+#endif
+
+ off = 0;
if (duk_is_undefined(thr, 1)) {
if (magic) {
- p_cmp_start = p_cmp_start + DUK_HSTRING_GET_BYTELEN(h) - blen_search;
+ off = (duk_int_t) blen_target - (duk_int_t) blen_search;
} else {
- /* p_cmp_start already OK */
+ DUK_ASSERT(off == 0);
}
} else {
duk_int_t len;
duk_int_t pos;
DUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= DUK_INT_MAX);
- len = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h);
+ len = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h_target);
pos = duk_to_int_clamped(thr, 1, 0, len);
DUK_ASSERT(pos >= 0 && pos <= len);
+ off = (duk_int_t) duk_heap_strcache_offset_char2byte(thr, h_target, (duk_uint_fast32_t) pos);
if (magic) {
- p_cmp_start -= blen_search; /* Conceptually subtracted last, but do already here. */
+ off -= (duk_int_t) blen_search;
}
- DUK_ASSERT(pos >= 0 && pos <= len);
-
- p_cmp_start += duk_heap_strcache_offset_char2byte(thr, h, (duk_uint_fast32_t) pos);
+ }
+ if (off < 0 || off > (duk_int_t) blen_target) {
+ goto finish;
}
/* The main comparison can be done using a memcmp() rather than
@@ -43337,16 +43461,18 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_startswith_endswith(duk_hthread *
* comparison range.
*/
- result = 0;
- if (p_cmp_start >= DUK_HSTRING_GET_DATA(h) &&
- (duk_size_t) (p_cmp_start - (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h)) + blen_search <= DUK_HSTRING_GET_BYTELEN(h)) {
- if (duk_memcmp((const void *) p_cmp_start,
- (const void *) DUK_HSTRING_GET_DATA(h_search),
- (size_t) blen_search) == 0) {
+ DUK_ASSERT(off >= 0);
+ DUK_ASSERT((duk_size_t) off <= blen_target);
+ blen_left = blen_target - (duk_size_t) off;
+ if (blen_left >= blen_search) {
+ const duk_uint8_t *p_cmp_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_target) + off;
+ const duk_uint8_t *p_search = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_search);
+ if (duk_memcmp_unsafe((const void *) p_cmp_start, (const void *) p_search, (size_t) blen_search) == 0) {
result = 1;
}
}
+ finish:
duk_push_boolean(thr, result);
return 1;
}
@@ -52244,6 +52370,7 @@ DUK_INTERNAL void duk_heap_mark_and_sweep(duk_heap *heap, duk_small_uint_t flags
#if defined(DUK_USE_VOLUNTARY_GC)
duk_size_t tmp;
#endif
+ duk_bool_t entry_creating_error;
DUK_STATS_INC(heap, stats_ms_try_count);
#if defined(DUK_USE_DEBUG)
@@ -52314,6 +52441,8 @@ DUK_INTERNAL void duk_heap_mark_and_sweep(duk_heap *heap, duk_small_uint_t flags
DUK_ASSERT(heap->ms_running == 0);
heap->ms_prevent_count = 1;
heap->ms_running = 1;
+ entry_creating_error = heap->creating_error;
+ heap->creating_error = 0;
/*
* Free activation/catcher freelists on every mark-and-sweep for now.
@@ -52444,6 +52573,7 @@ DUK_INTERNAL void duk_heap_mark_and_sweep(duk_heap *heap, duk_small_uint_t flags
DUK_ASSERT(heap->ms_running == 1);
heap->ms_prevent_count = 0;
heap->ms_running = 0;
+ heap->creating_error = entry_creating_error; /* for nested error handling, see GH-2278 */
/*
* Assertions after
@@ -55979,6 +56109,13 @@ DUK_LOCAL void duk__sort_enum_keys_es6(duk_hthread *thr, duk_hobject *h_obj, duk
keys[idx_insert] = h_curr;
}
}
+
+ /* Entry part has been reordered now with no side effects.
+ * If the object has a hash part, it will now be incorrect
+ * and we need to rehash. Do that by forcing a resize to
+ * the current size.
+ */
+ duk_hobject_resize_entrypart(thr, h_obj, DUK_HOBJECT_GET_ESIZE(h_obj));
}
/*
@@ -74164,10 +74301,13 @@ DUK_LOCAL void duk__parse_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_
*/
test_func_decl = allow_source_elem;
#if defined(DUK_USE_NONSTD_FUNC_STMT)
- /* Lenient: allow function declarations outside top level in
- * non-strict mode but reject them in strict mode.
+ /* Lenient: allow function declarations outside top level in both
+ * strict and non-strict modes. However, don't allow labelled
+ * function declarations in strict mode.
*/
- test_func_decl = test_func_decl || !comp_ctx->curr_func.is_strict;
+ test_func_decl = test_func_decl ||
+ !comp_ctx->curr_func.is_strict ||
+ label_id < 0;
#endif /* DUK_USE_NONSTD_FUNC_STMT */
/* Strict: never allow function declarations outside top level. */
if (test_func_decl) {
@@ -77196,17 +77336,21 @@ DUK_LOCAL duk_small_uint_t duk__handle_longjmp(duk_hthread *thr, duk_activation
DUK_DD(DUK_DDPRINT("-> yield an error, converted to a throw in the resumer, propagate"));
goto check_longjmp;
} else {
- duk_hthread_activation_unwind_norz(resumer);
- duk__handle_yield(thr, resumer, &thr->heap->lj.value1);
+ /* When handling the yield, the last reference to
+ * 'thr' may disappear.
+ */
+ DUK_GC_TORTURE(resumer->heap);
+ duk_hthread_activation_unwind_norz(resumer);
+ DUK_GC_TORTURE(resumer->heap);
thr->state = DUK_HTHREAD_STATE_YIELDED;
thr->resumer = NULL;
DUK_HTHREAD_DECREF_NORZ(thr, resumer);
resumer->state = DUK_HTHREAD_STATE_RUNNING;
DUK_HEAP_SWITCH_THREAD(thr->heap, resumer);
-#if 0
- thr = resumer; /* not needed, as we exit right away */
-#endif
+ duk__handle_yield(thr, resumer, &thr->heap->lj.value1);
+ thr = resumer;
+ DUK_GC_TORTURE(resumer->heap);
DUK_DD(DUK_DDPRINT("-> yield a value, restart execution in resumer"));
retval = DUK__LONGJMP_RESTART;
@@ -83909,6 +84053,7 @@ void duk__putvar_helper(duk_hthread *thr,
duk_tval *val,
duk_bool_t strict) {
duk__id_lookup_result ref;
+ duk_tval tv_tmp_val;
duk_tval tv_tmp_obj;
duk_tval tv_tmp_key;
duk_bool_t parents;
@@ -83926,10 +84071,13 @@ void duk__putvar_helper(duk_hthread *thr,
DUK_ASSERT(val != NULL);
/* env and act may be NULL */
- DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(env);
- DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(name);
+ DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(env);
+ DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(name);
DUK_ASSERT_REFCOUNT_NONZERO_TVAL(val);
+ DUK_TVAL_SET_TVAL(&tv_tmp_val, val); /* Stabilize. */
+ val = NULL;
+
/*
* In strict mode E5 protects 'eval' and 'arguments' from being
* assigned to (or even declared anywhere). Attempt to do so
@@ -83961,7 +84109,7 @@ void duk__putvar_helper(duk_hthread *thr,
tv_val = ref.value;
DUK_ASSERT(tv_val != NULL);
- DUK_TVAL_SET_TVAL_UPDREF(thr, tv_val, val); /* side effects */
+ DUK_TVAL_SET_TVAL_UPDREF(thr, tv_val, &tv_tmp_val); /* side effects */
/* ref.value invalidated here */
} else {
@@ -83969,7 +84117,7 @@ void duk__putvar_helper(duk_hthread *thr,
DUK_TVAL_SET_OBJECT(&tv_tmp_obj, ref.holder);
DUK_TVAL_SET_STRING(&tv_tmp_key, name);
- (void) duk_hobject_putprop(thr, &tv_tmp_obj, &tv_tmp_key, val, strict);
+ (void) duk_hobject_putprop(thr, &tv_tmp_obj, &tv_tmp_key, &tv_tmp_val, strict);
/* ref.value invalidated here */
}
@@ -83994,7 +84142,7 @@ void duk__putvar_helper(duk_hthread *thr,
DUK_TVAL_SET_OBJECT(&tv_tmp_obj, thr->builtins[DUK_BIDX_GLOBAL]);
DUK_TVAL_SET_STRING(&tv_tmp_key, name);
- (void) duk_hobject_putprop(thr, &tv_tmp_obj, &tv_tmp_key, val, 0); /* 0 = no throw */
+ (void) duk_hobject_putprop(thr, &tv_tmp_obj, &tv_tmp_key, &tv_tmp_val, 0); /* 0 = no throw */
/* NB: 'val' may be invalidated here because put_value may realloc valstack,
* caller beware.
@@ -91415,10 +91563,12 @@ DUK_LOCAL void duk__regexp_match_helper(duk_hthread *thr, duk_small_int_t force_
* as 'undefined'. The same is done when saved[] pointers are insane
* (this should, of course, never happen in practice).
*/
+ duk_push_uarridx(thr, (duk_uarridx_t) (i / 2));
+
if (re_ctx.saved[i] && re_ctx.saved[i + 1] && re_ctx.saved[i + 1] >= re_ctx.saved[i]) {
duk_push_lstring(thr,
(const char *) re_ctx.saved[i],
- (duk_size_t) (re_ctx.saved[i+1] - re_ctx.saved[i]));
+ (duk_size_t) (re_ctx.saved[i + 1] - re_ctx.saved[i]));
if (i == 0) {
/* Assumes that saved[0] and saved[1] are always
* set by regexp bytecode (if not, char_end_offset
@@ -91431,8 +91581,8 @@ DUK_LOCAL void duk__regexp_match_helper(duk_hthread *thr, duk_small_int_t force_
duk_push_undefined(thr);
}
- /* [ ... re_obj input bc saved_buf res_obj val ] */
- duk_put_prop_index(thr, -2, (duk_uarridx_t) (i / 2));
+ /* [ ... re_obj input bc saved_buf res_obj idx val ] */
+ duk_def_prop(thr, -3, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_SET_WEC);
}
/* [ ... re_obj input bc saved_buf res_obj ] */
diff --git a/duktape/duktape.h b/duktape/duktape.h
index 7850c99..e5b46c2 100644
--- a/duktape/duktape.h
+++ b/duktape/duktape.h
@@ -1,13 +1,13 @@
/*
- * Duktape public API for Duktape 2.5.0.
+ * Duktape public API for Duktape 2.6.0.
*
* See the API reference for documentation on call semantics. The exposed,
* supported API is between the "BEGIN PUBLIC API" and "END PUBLIC API"
* comments. Other parts of the header are Duktape internal and related to
* e.g. platform/compiler/feature detection.
*
- * Git commit 6001888049cb42656f8649db020e804bcdeca6a7 (v2.5.0).
- * Git branch master.
+ * Git commit fffa346eff06a8764b02c31d4336f63a773a95c3 (v2.6.0).
+ * Git branch v2-maintenance.
*
* See Duktape AUTHORS.rst and LICENSE.txt for copyright and
* licensing information.
@@ -176,16 +176,16 @@
* development snapshots have 99 for patch level (e.g. 0.10.99 would be a
* development version after 0.10.0 but before the next official release).
*/
-#define DUK_VERSION 20500L
+#define DUK_VERSION 20600L
/* Git commit, describe, and branch for Duktape build. Useful for
* non-official snapshot builds so that application code can easily log
* which Duktape snapshot was used. Not available in the ECMAScript
* environment.
*/
-#define DUK_GIT_COMMIT "6001888049cb42656f8649db020e804bcdeca6a7"
-#define DUK_GIT_DESCRIBE "v2.5.0"
-#define DUK_GIT_BRANCH "master"
+#define DUK_GIT_COMMIT "fffa346eff06a8764b02c31d4336f63a773a95c3"
+#define DUK_GIT_DESCRIBE "v2.6.0"
+#define DUK_GIT_BRANCH "v2-maintenance"
/* External duk_config.h provides platform/compiler/OS dependent
* typedefs and macros, and DUK_USE_xxx config options so that