From 9800c5f298f2a6387cf8ef9341e9b01f35fcb2a6 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Wed, 31 Aug 2016 18:34:39 +0100 Subject: Duktape: Update to version 1.5.1. Version 1.5.1 includes some of our own fixes, reducing our delta to upstream. These should not be needed now: - 2cbb337756d9af5bda4d594964d446439f602551 Squash harmless Clang warning introduced in Duktape 1.5.0. - 8f8cda2b48d1063366302204559c1ed3362656bc Fix Duktape on AmigaOS3 (thanks to Tygre and Sami) --- content/handlers/javascript/duktape/duk_config.h | 61 +++++++- content/handlers/javascript/duktape/duktape.c | 175 +++++++++++++++-------- content/handlers/javascript/duktape/duktape.h | 30 ++-- 3 files changed, 185 insertions(+), 81 deletions(-) (limited to 'content') diff --git a/content/handlers/javascript/duktape/duk_config.h b/content/handlers/javascript/duktape/duk_config.h index 4a83e77f4..c336603eb 100644 --- a/content/handlers/javascript/duktape/duk_config.h +++ b/content/handlers/javascript/duktape/duk_config.h @@ -1,9 +1,9 @@ /* * duk_config.h configuration header generated by genconfig.py. * - * Git commit: 83d557704ee63f68ab40b6fcb00995c9b3d6777c - * Git describe: v1.5.0 - * Git branch: master + * Git commit: 2cc76e9ff1f64869e1146ad7317d8cbe33bbd27e + * Git describe: v1.5.1 + * Git branch: HEAD * * Supported platforms: * - Mac OSX, iPhone, Darwin @@ -918,12 +918,27 @@ #define DUK_EXTERNAL_DECL __attribute__ ((visibility("default"))) extern #define DUK_EXTERNAL __attribute__ ((visibility("default"))) #if defined(DUK_SINGLE_FILE) +#if (defined(DUK_F_GCC_VERSION) && DUK_F_GCC_VERSION >= 30101) || defined(DUK_F_CLANG) +/* Minimize warnings for unused internal functions with GCC >= 3.1.1 and + * Clang. Based on documentation it should suffice to have the attribute + * in the declaration only, but in practice some warnings are generated unless + * the attribute is also applied to the definition. + */ +#define DUK_INTERNAL_DECL static __attribute__ ((unused)) +#define DUK_INTERNAL static __attribute__ ((unused)) +#else #define DUK_INTERNAL_DECL static #define DUK_INTERNAL static +#endif +#else +#if (defined(DUK_F_GCC_VERSION) && DUK_F_GCC_VERSION >= 30101) || defined(DUK_F_CLANG) +#define DUK_INTERNAL_DECL __attribute__ ((visibility("hidden"))) __attribute__ ((unused)) extern +#define DUK_INTERNAL __attribute__ ((visibility("hidden"))) __attribute__ ((unused)) #else #define DUK_INTERNAL_DECL __attribute__ ((visibility("hidden"))) extern #define DUK_INTERNAL __attribute__ ((visibility("hidden"))) #endif +#endif #define DUK_LOCAL_DECL static #define DUK_LOCAL static #endif @@ -1012,12 +1027,27 @@ #define DUK_EXTERNAL_DECL __attribute__ ((visibility("default"))) extern #define DUK_EXTERNAL __attribute__ ((visibility("default"))) #if defined(DUK_SINGLE_FILE) +#if (defined(DUK_F_GCC_VERSION) && DUK_F_GCC_VERSION >= 30101) || defined(DUK_F_CLANG) +/* Minimize warnings for unused internal functions with GCC >= 3.1.1 and + * Clang. Based on documentation it should suffice to have the attribute + * in the declaration only, but in practice some warnings are generated unless + * the attribute is also applied to the definition. + */ +#define DUK_INTERNAL_DECL static __attribute__ ((unused)) +#define DUK_INTERNAL static __attribute__ ((unused)) +#else #define DUK_INTERNAL_DECL static #define DUK_INTERNAL static +#endif +#else +#if (defined(DUK_F_GCC_VERSION) && DUK_F_GCC_VERSION >= 30101) || defined(DUK_F_CLANG) +#define DUK_INTERNAL_DECL __attribute__ ((visibility("hidden"))) __attribute__ ((unused)) extern +#define DUK_INTERNAL __attribute__ ((visibility("hidden"))) __attribute__ ((unused)) #else #define DUK_INTERNAL_DECL __attribute__ ((visibility("hidden"))) extern #define DUK_INTERNAL __attribute__ ((visibility("hidden"))) #endif +#endif #define DUK_LOCAL_DECL static #define DUK_LOCAL static #endif @@ -1174,12 +1204,27 @@ #define DUK_EXTERNAL_DECL __attribute__ ((visibility("default"))) extern #define DUK_EXTERNAL __attribute__ ((visibility("default"))) #if defined(DUK_SINGLE_FILE) +#if (defined(DUK_F_GCC_VERSION) && DUK_F_GCC_VERSION >= 30101) || defined(DUK_F_CLANG) +/* Minimize warnings for unused internal functions with GCC >= 3.1.1 and + * Clang. Based on documentation it should suffice to have the attribute + * in the declaration only, but in practice some warnings are generated unless + * the attribute is also applied to the definition. + */ +#define DUK_INTERNAL_DECL static __attribute__ ((unused)) +#define DUK_INTERNAL static __attribute__ ((unused)) +#else #define DUK_INTERNAL_DECL static #define DUK_INTERNAL static +#endif +#else +#if (defined(DUK_F_GCC_VERSION) && DUK_F_GCC_VERSION >= 30101) || defined(DUK_F_CLANG) +#define DUK_INTERNAL_DECL __attribute__ ((visibility("hidden"))) __attribute__ ((unused)) extern +#define DUK_INTERNAL __attribute__ ((visibility("hidden"))) __attribute__ ((unused)) #else #define DUK_INTERNAL_DECL __attribute__ ((visibility("hidden"))) extern #define DUK_INTERNAL __attribute__ ((visibility("hidden"))) #endif +#endif #define DUK_LOCAL_DECL static #define DUK_LOCAL static @@ -2076,8 +2121,14 @@ typedef FILE duk_file; defined(FP_SUBNORMAL) && defined(FP_NORMAL)) /* Missing some obvious constants. */ #define DUK_F_USE_REPL_ALL -#elif defined(DUK_F_AMIGAOS) -/* VBCC is missing the built-ins even in C99 mode (perhaps a header issue) */ +#elif defined(DUK_F_AMIGAOS) && defined(DUK_F_VBCC) +/* VBCC is missing the built-ins even in C99 mode (perhaps a header issue). */ +#define DUK_F_USE_REPL_ALL +#elif defined(DUK_F_AMIGAOS) && defined(DUK_F_M68K) +/* AmigaOS + M68K seems to have math issues even when using GCC cross + * compilation. Use replacements for all AmigaOS versions on M68K + * regardless of compiler. + */ #define DUK_F_USE_REPL_ALL #elif defined(DUK_F_FREEBSD) && defined(DUK_F_CLANG) /* Placeholder fix for (detection is wider than necessary): diff --git a/content/handlers/javascript/duktape/duktape.c b/content/handlers/javascript/duktape/duktape.c index eb4c77a04..83edfd1d6 100644 --- a/content/handlers/javascript/duktape/duktape.c +++ b/content/handlers/javascript/duktape/duktape.c @@ -1,10 +1,8 @@ -/* Omit from static analysis. */ -#ifndef __clang_analyzer__ /* - * Single source autogenerated distributable for Duktape 1.5.0. + * Single source autogenerated distributable for Duktape 1.5.1. * - * Git commit 83d557704ee63f68ab40b6fcb00995c9b3d6777c (v1.5.0). - * Git branch master. + * Git commit 2cc76e9ff1f64869e1146ad7317d8cbe33bbd27e (v1.5.1). + * Git branch HEAD. * * See Duktape AUTHORS.rst and LICENSE.txt for copyright and * licensing information. @@ -2250,12 +2248,12 @@ DUK_INTERNAL_DECL duk_uint8_t *duk_bw_insert_ensure_area(duk_hthread *thr, duk_b DUK_INTERNAL_DECL void duk_bw_remove_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len); /* No duk_bw_remove_ensure_slice(), functionality would be identical. */ -DUK_INTERNAL_DECL DUK_INLINE duk_uint16_t duk_raw_read_u16_be(duk_uint8_t **p); -DUK_INTERNAL_DECL DUK_INLINE duk_uint32_t duk_raw_read_u32_be(duk_uint8_t **p); -DUK_INTERNAL_DECL DUK_INLINE duk_double_t duk_raw_read_double_be(duk_uint8_t **p); -DUK_INTERNAL_DECL DUK_INLINE void duk_raw_write_u16_be(duk_uint8_t **p, duk_uint16_t val); -DUK_INTERNAL_DECL DUK_INLINE void duk_raw_write_u32_be(duk_uint8_t **p, duk_uint32_t val); -DUK_INTERNAL_DECL DUK_INLINE void duk_raw_write_double_be(duk_uint8_t **p, duk_double_t val); +DUK_INTERNAL_DECL duk_uint16_t duk_raw_read_u16_be(duk_uint8_t **p); +DUK_INTERNAL_DECL duk_uint32_t duk_raw_read_u32_be(duk_uint8_t **p); +DUK_INTERNAL_DECL duk_double_t duk_raw_read_double_be(duk_uint8_t **p); +DUK_INTERNAL_DECL void duk_raw_write_u16_be(duk_uint8_t **p, duk_uint16_t val); +DUK_INTERNAL_DECL void duk_raw_write_u32_be(duk_uint8_t **p, duk_uint32_t val); +DUK_INTERNAL_DECL void duk_raw_write_double_be(duk_uint8_t **p, duk_double_t val); #if defined(DUK_USE_DEBUGGER_SUPPORT) /* For now only needed by the debugger. */ DUK_INTERNAL void duk_byteswap_bytes(duk_uint8_t *p, duk_small_uint_t len); @@ -7891,7 +7889,7 @@ DUK_INTERNAL_DECL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb); #define DUK_ERROR_UNSUPPORTED(thr,msg) do { \ DUK_ERROR((thr), DUK_ERR_UNSUPPORTED_ERROR, (msg)); \ } while (0) -#ifndef DUK_USE_BYTECODE_DUMP_SUPPORT +#if !defined(DUK_USE_BYTECODE_DUMP_SUPPORT) #define DUK_ERROR_UNSUPPORTED_DEFMSG(thr) do { \ duk_err_unsupported_defmsg((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \ } while (0) @@ -8013,7 +8011,7 @@ DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_api_index(duk_hthread *thr, const ch DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_api(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message)); DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_range(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message)); DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_unimplemented_defmsg(duk_hthread *thr, const char *filename, duk_int_t linenumber)); -#ifndef DUK_USE_BYTECODE_DUMP_SUPPORT +#if !defined(DUK_USE_BYTECODE_DUMP_SUPPORT) DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_unsupported_defmsg(duk_hthread *thr, const char *filename, duk_int_t linenumber)); #endif DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_internal_defmsg(duk_hthread *thr, const char *filename, duk_int_t linenumber)); @@ -9354,7 +9352,7 @@ DUK_INTERNAL const duk_uint8_t duk_builtins_data[3833] = { 88,119,100,223,181,68,16,94,91,250,238,200,160,80,0,152,31,61,59,148,10,0, 21,4,231,199,151,69,2,128,5,192,250,97,220,160,80,0,192,127,255,128,20,23, 134,30,92,242,164,34,19,207,167,45,59,179,233,205,229,37,129,127,255,0,0, -191,255,128,0,63,255,197,131,246,203,203,158,157,251,160,0,0,0,0,0,65,98, +191,255,128,0,63,255,197,131,246,203,203,158,157,251,160,0,0,0,0,64,65,98, 32,3,166,156,30,53,32,249,165,131,76,223,159,62,94,70,172,114,16,176,144, 60,56,250,19,18,5,159,25,89,32,121,180,238,42,30,129,229,221,140,164,122,7, 147,46,50,129,232,62,61,251,120,97,199,208,156,129,83,127,0,50,250,69,3, @@ -9534,7 +9532,7 @@ DUK_INTERNAL const duk_uint8_t duk_builtins_data[3833] = { 88,119,100,223,181,68,16,94,91,250,238,200,160,80,0,152,31,61,59,148,10,0, 21,4,231,199,151,69,2,128,5,192,250,97,220,160,80,0,192,127,255,128,20,23, 134,30,92,242,164,34,19,207,167,45,59,179,233,205,229,37,129,127,255,0,0, -191,255,128,0,63,255,197,131,246,203,203,158,157,251,160,32,98,65,0,0,0,0, +191,255,128,0,63,255,197,131,246,203,203,158,157,251,160,32,98,65,64,0,0,0, 0,3,166,156,30,53,32,249,165,131,76,223,159,62,94,70,172,114,16,176,144,60, 56,250,19,18,5,159,25,89,32,121,180,238,42,30,129,229,221,140,164,122,7, 147,46,50,129,232,62,61,251,120,97,199,208,156,129,83,127,0,50,250,69,3, @@ -9714,7 +9712,7 @@ DUK_INTERNAL const duk_uint8_t duk_builtins_data[3833] = { 88,119,100,223,181,68,16,94,91,250,238,200,160,80,0,152,31,61,59,148,10,0, 21,4,231,199,151,69,2,128,5,192,250,97,220,160,80,0,192,127,255,128,20,23, 134,30,92,242,164,34,19,207,167,45,59,179,233,205,229,37,129,127,255,0,0, -191,255,128,0,63,255,197,131,246,203,203,158,157,251,160,0,65,98,32,0,0,0, +191,255,128,0,63,255,197,131,246,203,203,158,157,251,160,64,65,98,32,0,0,0, 0,3,166,156,30,53,32,249,165,131,76,223,159,62,94,70,172,114,16,176,144,60, 56,250,19,18,5,159,25,89,32,121,180,238,42,30,129,229,221,140,164,122,7, 147,46,50,129,232,62,61,251,120,97,199,208,156,129,83,127,0,50,250,69,3, @@ -9838,7 +9836,7 @@ DUK_INTERNAL void duk_err_api(duk_hthread *thr, const char *filename, duk_int_t DUK_INTERNAL void duk_err_unimplemented_defmsg(duk_hthread *thr, const char *filename, duk_int_t linenumber) { DUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_UNIMPLEMENTED_ERROR, DUK_STR_UNIMPLEMENTED); } -#ifndef DUK_USE_BYTECODE_DUMP_SUPPORT +#if !defined(DUK_USE_BYTECODE_DUMP_SUPPORT) DUK_INTERNAL void duk_err_unsupported_defmsg(duk_hthread *thr, const char *filename, duk_int_t linenumber) { DUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_UNSUPPORTED_ERROR, DUK_STR_UNSUPPORTED); } @@ -12675,21 +12673,41 @@ DUK_EXTERNAL void duk_new(duk_context *ctx, duk_idx_t nargs) { duk_dup(ctx, idx_cons); for (;;) { - cons = duk_get_hobject(ctx, -1); - if (cons == NULL || !DUK_HOBJECT_HAS_CONSTRUCTABLE(cons)) { - /* Checking constructability from anything else than the - * initial constructor is not strictly necessary, but a - * nice sanity check. - */ - goto not_constructable; - } - if (!DUK_HOBJECT_HAS_BOUND(cons)) { + duk_tval *tv; + tv = DUK_GET_TVAL_NEGIDX(ctx, -1); + DUK_ASSERT(tv != NULL); + + if (DUK_TVAL_IS_OBJECT(tv)) { + cons = DUK_TVAL_GET_OBJECT(tv); + DUK_ASSERT(cons != NULL); + if (!DUK_HOBJECT_IS_CALLABLE(cons) || !DUK_HOBJECT_HAS_CONSTRUCTABLE(cons)) { + /* Checking callability of the immediate target + * is important, same for constructability. + * Checking it for functions down the bound + * function chain is not strictly necessary + * because .bind() should normally reject them. + * But it's good to check anyway because it's + * technically possible to edit the bound function + * chain via internal keys. + */ + goto not_constructable; + } + if (!DUK_HOBJECT_HAS_BOUND(cons)) { + break; + } + } else if (DUK_TVAL_IS_LIGHTFUNC(tv)) { + /* Lightfuncs cannot be bound. */ break; + } else { + /* Anything else is not constructable. */ + goto not_constructable; } duk_get_prop_stridx(ctx, -1, DUK_STRIDX_INT_TARGET); /* -> [... cons target] */ duk_remove(ctx, -2); /* -> [... target] */ } - DUK_ASSERT(cons != NULL && !DUK_HOBJECT_HAS_BOUND(cons)); + DUK_ASSERT(duk_is_callable(ctx, -1)); + DUK_ASSERT(duk_is_lightfunc(ctx, -1) || + (duk_get_hobject(ctx, -1) != NULL && !DUK_HOBJECT_HAS_BOUND(duk_get_hobject(ctx, -1)))); /* [... constructor arg1 ... argN final_cons] */ @@ -26600,6 +26618,10 @@ DUK_INTERNAL duk_ret_t duk_bi_duktape_object_info(duk_context *ctx) { hdr_size = (duk_small_uint_t) sizeof(duk_hnativefunction); } else if (DUK_HOBJECT_IS_THREAD(h_obj)) { hdr_size = (duk_small_uint_t) sizeof(duk_hthread); +#if defined(DUK_USE_BUFFEROBJECT_SUPPORT) + } else if (DUK_HOBJECT_IS_BUFFEROBJECT(h_obj)) { + hdr_size = (duk_small_uint_t) sizeof(duk_hbufferobject); +#endif } else { hdr_size = (duk_small_uint_t) sizeof(duk_hobject); } @@ -30800,7 +30822,7 @@ DUK_LOCAL void duk__enc_array(duk_json_enc_ctx *js_ctx) { DUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_holder) { duk_context *ctx = (duk_context *) js_ctx->thr; duk_hthread *thr = (duk_hthread *) ctx; - duk_hobject *h; + duk_hobject *h_tmp; duk_tval *tv; duk_tval *tv_holder; duk_tval *tv_key; @@ -30822,12 +30844,12 @@ DUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_hold DUK_DDD(DUK_DDDPRINT("value=%!T", (duk_tval *) duk_get_tval(ctx, -1))); - h = duk_get_hobject_or_lfunc_coerce(ctx, -1); - if (h != NULL) { + h_tmp = duk_get_hobject_or_lfunc_coerce(ctx, -1); + if (h_tmp != NULL) { duk_get_prop_stridx(ctx, -1, DUK_STRIDX_TO_JSON); - h = duk_get_hobject_or_lfunc_coerce(ctx, -1); /* toJSON() can also be a lightfunc */ + h_tmp = duk_get_hobject_or_lfunc_coerce(ctx, -1); /* toJSON() can also be a lightfunc */ - if (h != NULL && DUK_HOBJECT_IS_CALLABLE(h)) { + if (h_tmp != NULL && DUK_HOBJECT_IS_CALLABLE(h_tmp)) { DUK_DDD(DUK_DDDPRINT("value is object, has callable toJSON() -> call it")); /* XXX: duk_dup_unvalidated(ctx, -2) etc. */ duk_dup(ctx, -2); /* -> [ ... key val toJSON val ] */ @@ -30860,6 +30882,8 @@ DUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_hold tv = DUK_GET_TVAL_NEGIDX(ctx, -1); if (DUK_TVAL_IS_OBJECT(tv)) { + duk_hobject *h; + h = DUK_TVAL_GET_OBJECT(tv); DUK_ASSERT(h != NULL); @@ -38612,7 +38636,7 @@ DUK_LOCAL void duk__debug_dump_strtab_probe(duk_hthread *thr, duk_heap *heap) { for (i = 0; i < heap->st_size; i++) { #if defined(DUK_USE_HEAPPTR16) - h = DUK_USE_HEAPPTR_DEC16(heap->strtable16[i]); + h = DUK_USE_HEAPPTR_DEC16(heap->heap_udata, heap->strtable16[i]); #else h = heap->strtable[i]; #endif @@ -42578,7 +42602,7 @@ DUK_LOCAL void duk__sweep_stringtable_probe(duk_heap *heap, duk_size_t *out_coun for (i = 0; i < heap->st_size; i++) { #if defined(DUK_USE_HEAPPTR16) - h = (duk_hstring *) DUK_USE_HEAPPTR_DEC16(heap->strtable16[i]); + h = (duk_hstring *) DUK_USE_HEAPPTR_DEC16(heap->heap_udata, heap->strtable16[i]); #else h = heap->strtable[i]; #endif @@ -43236,6 +43260,9 @@ DUK_INTERNAL duk_bool_t duk_heap_mark_and_sweep(duk_heap *heap, duk_small_uint_t /* XXX: stringtable emergency compaction? */ + /* XXX: remove this feature entirely? it would only matter for + * emergency GC. Disable for lowest memory builds. + */ #if defined(DUK_USE_MS_STRINGTABLE_RESIZE) if (!(flags & DUK_MS_FLAG_NO_STRINGTABLE_RESIZE)) { DUK_DD(DUK_DDPRINT("resize stringtable: %p", (void *) heap)); @@ -44730,6 +44757,15 @@ DUK_INTERNAL duk_uint_fast32_t duk_heap_strcache_offset_char2byte(duk_hthread *t #define DUK__DELETED_MARKER(heap) DUK_STRTAB_DELETED_MARKER((heap)) #endif +#if defined(DUK_USE_MARK_AND_SWEEP) +#define DUK__PREVENT_MS_SIDE_EFFECTS(heap) do { \ + (heap)->mark_and_sweep_base_flags |= \ + DUK_MS_FLAG_NO_STRINGTABLE_RESIZE | /* avoid recursive string table call */ \ + DUK_MS_FLAG_NO_FINALIZERS | /* avoid pressure to add/remove strings, invalidation of call data argument, etc. */ \ + DUK_MS_FLAG_NO_OBJECT_COMPACTION; /* avoid array abandoning which interns strings */ \ + } while (0) +#endif + /* * Create a hstring and insert into the heap. The created object * is directly garbage collectable with reference count zero. @@ -44766,7 +44802,7 @@ duk_hstring *duk__alloc_init_hstring(duk_heap *heap, goto alloc_error; } DUK_MEMZERO(res, sizeof(duk_hstring_external)); -#ifdef DUK_USE_EXPLICIT_NULL_INIT +#if defined(DUK_USE_EXPLICIT_NULL_INIT) DUK_HEAPHDR_STRING_INIT_NULLS(&res->hdr); #endif DUK_HEAPHDR_SET_TYPE_AND_FLAGS(&res->hdr, DUK_HTYPE_STRING, DUK_HSTRING_FLAG_EXTDATA); @@ -44780,7 +44816,7 @@ duk_hstring *duk__alloc_init_hstring(duk_heap *heap, goto alloc_error; } DUK_MEMZERO(res, sizeof(duk_hstring)); -#ifdef DUK_USE_EXPLICIT_NULL_INIT +#if defined(DUK_USE_EXPLICIT_NULL_INIT) DUK_HEAPHDR_STRING_INIT_NULLS(&res->hdr); #endif DUK_HEAPHDR_SET_TYPE_AND_FLAGS(&res->hdr, DUK_HTYPE_STRING, 0); @@ -45356,10 +45392,7 @@ DUK_LOCAL void duk__remove_matching_hstring_probe(duk_heap *heap, duk_hstring ** } DUK_LOCAL duk_bool_t duk__resize_strtab_raw_probe(duk_heap *heap, duk_uint32_t new_size) { -#ifdef DUK_USE_MARK_AND_SWEEP - duk_small_uint_t prev_mark_and_sweep_base_flags; -#endif -#ifdef DUK_USE_DEBUG +#if defined(DUK_USE_DEBUG) duk_uint32_t old_used = heap->st_used; #endif duk_uint32_t old_size = heap->st_size; @@ -45373,7 +45406,7 @@ DUK_LOCAL duk_bool_t duk__resize_strtab_raw_probe(duk_heap *heap, duk_uint32_t n duk_uint32_t new_used = 0; duk_uint32_t i; -#ifdef DUK_USE_DEBUG +#if defined(DUK_USE_DEBUG) DUK_UNREF(old_used); /* unused with some debug level combinations */ #endif @@ -45387,23 +45420,18 @@ DUK_LOCAL duk_bool_t duk__resize_strtab_raw_probe(duk_heap *heap, duk_uint32_t n DUK_ASSERT(new_size > (duk_uint32_t) duk__count_used_probe(heap)); /* required for rehash to succeed, equality not that useful */ DUK_ASSERT(old_entries); -#ifdef DUK_USE_MARK_AND_SWEEP - DUK_ASSERT((heap->mark_and_sweep_base_flags & DUK_MS_FLAG_NO_STRINGTABLE_RESIZE) == 0); -#endif /* * The attempt to allocate may cause a GC. Such a GC must not attempt to resize * the stringtable (though it can be swept); finalizer execution and object * compaction must also be postponed to avoid the pressure to add strings to the - * string table. + * string table. Call site must prevent these. */ -#ifdef DUK_USE_MARK_AND_SWEEP - prev_mark_and_sweep_base_flags = heap->mark_and_sweep_base_flags; - heap->mark_and_sweep_base_flags |= \ - DUK_MS_FLAG_NO_STRINGTABLE_RESIZE | /* avoid recursive call here */ - DUK_MS_FLAG_NO_FINALIZERS | /* avoid pressure to add/remove strings */ - DUK_MS_FLAG_NO_OBJECT_COMPACTION; /* avoid array abandoning which interns strings */ +#if defined(DUK_USE_MARK_AND_SWEEP) + DUK_ASSERT(heap->mark_and_sweep_base_flags & DUK_MS_FLAG_NO_STRINGTABLE_RESIZE); + DUK_ASSERT(heap->mark_and_sweep_base_flags & DUK_MS_FLAG_NO_FINALIZERS); + DUK_ASSERT(heap->mark_and_sweep_base_flags & DUK_MS_FLAG_NO_OBJECT_COMPACTION); #endif #if defined(DUK_USE_HEAPPTR16) @@ -45412,15 +45440,11 @@ DUK_LOCAL duk_bool_t duk__resize_strtab_raw_probe(duk_heap *heap, duk_uint32_t n new_entries = (duk_hstring **) DUK_ALLOC(heap, sizeof(duk_hstring *) * new_size); #endif -#ifdef DUK_USE_MARK_AND_SWEEP - heap->mark_and_sweep_base_flags = prev_mark_and_sweep_base_flags; -#endif - if (!new_entries) { goto resize_error; } -#ifdef DUK_USE_EXPLICIT_NULL_INIT +#if defined(DUK_USE_EXPLICIT_NULL_INIT) for (i = 0; i < new_size; i++) { #if defined(DUK_USE_HEAPPTR16) new_entries[i] = heap->heapptr_null16; @@ -45556,10 +45580,24 @@ DUK_INTERNAL void duk_heap_dump_strtab(duk_heap *heap) { DUK_LOCAL duk_hstring *duk__do_intern(duk_heap *heap, const duk_uint8_t *str, duk_uint32_t blen, duk_uint32_t strhash) { duk_hstring *res; const duk_uint8_t *extdata; +#if defined(DUK_USE_MARK_AND_SWEEP) + duk_small_uint_t prev_mark_and_sweep_base_flags; +#endif + + /* Prevent any side effects on the string table and the caller provided + * str/blen arguments while interning is in progress. For example, if + * the caller provided str/blen from a dynamic buffer, a finalizer might + * resize that dynamic buffer, invalidating the call arguments. + */ +#if defined(DUK_USE_MARK_AND_SWEEP) + DUK_ASSERT((heap->mark_and_sweep_base_flags & DUK_MS_FLAG_NO_STRINGTABLE_RESIZE) == 0); + prev_mark_and_sweep_base_flags = heap->mark_and_sweep_base_flags; + DUK__PREVENT_MS_SIDE_EFFECTS(heap); +#endif #if defined(DUK_USE_STRTAB_PROBE) if (duk__recheck_strtab_size_probe(heap, heap->st_used + 1)) { - return NULL; + goto failed; } #endif @@ -45587,14 +45625,14 @@ DUK_LOCAL duk_hstring *duk__do_intern(duk_heap *heap, const duk_uint8_t *str, du #endif res = duk__alloc_init_hstring(heap, str, blen, strhash, extdata); if (!res) { - return NULL; + goto failed; } #if defined(DUK_USE_STRTAB_CHAIN) if (duk__insert_hstring_chain(heap, res)) { /* failed */ DUK_FREE(heap, res); - return NULL; + goto failed; } #elif defined(DUK_USE_STRTAB_PROBE) /* guaranteed to succeed */ @@ -45616,7 +45654,15 @@ DUK_LOCAL duk_hstring *duk__do_intern(duk_heap *heap, const duk_uint8_t *str, du * operations which require allocation (and possible gc). */ + done: +#if defined(DUK_USE_MARK_AND_SWEEP) + heap->mark_and_sweep_base_flags = prev_mark_and_sweep_base_flags; +#endif return res; + + failed: + res = NULL; + goto done; } DUK_LOCAL duk_hstring *duk__do_lookup(duk_heap *heap, const duk_uint8_t *str, duk_uint32_t blen, duk_uint32_t *out_strhash) { @@ -45752,16 +45798,24 @@ DUK_INTERNAL void duk_heap_string_remove(duk_heap *heap, duk_hstring *h) { #if defined(DUK_USE_MARK_AND_SWEEP) && defined(DUK_USE_MS_STRINGTABLE_RESIZE) DUK_INTERNAL void duk_heap_force_strtab_resize(duk_heap *heap) { + duk_small_uint_t prev_mark_and_sweep_base_flags; /* Force a resize so that DELETED entries are eliminated. * Another option would be duk__recheck_strtab_size_probe(); * but since that happens on every intern anyway, this whole * check can now be disabled. */ + + DUK_ASSERT((heap->mark_and_sweep_base_flags & DUK_MS_FLAG_NO_STRINGTABLE_RESIZE) == 0); + prev_mark_and_sweep_base_flags = heap->mark_and_sweep_base_flags; + DUK__PREVENT_MS_SIDE_EFFECTS(heap); + #if defined(DUK_USE_STRTAB_CHAIN) DUK_UNREF(heap); #elif defined(DUK_USE_STRTAB_PROBE) - duk__resize_strtab_probe(heap); + (void) duk__resize_strtab_probe(heap); #endif + + heap->mark_and_sweep_base_flags = prev_mark_and_sweep_base_flags; } #endif @@ -86510,4 +86564,3 @@ DUK_INTERNAL duk_double_t duk_util_tinyrandom_get_double(duk_hthread *thr) { return t; } -#endif diff --git a/content/handlers/javascript/duktape/duktape.h b/content/handlers/javascript/duktape/duktape.h index a727187eb..2cb9a5047 100644 --- a/content/handlers/javascript/duktape/duktape.h +++ b/content/handlers/javascript/duktape/duktape.h @@ -1,13 +1,13 @@ /* - * Duktape public API for Duktape 1.5.0. + * Duktape public API for Duktape 1.5.1. * * See the API reference for documentation on call semantics. * The exposed API is inside the DUK_API_PUBLIC_H_INCLUDED * include guard. Other parts of the header are Duktape * internal and related to platform/compiler/feature detection. * - * Git commit 83d557704ee63f68ab40b6fcb00995c9b3d6777c (v1.5.0). - * Git branch master. + * Git commit 2cc76e9ff1f64869e1146ad7317d8cbe33bbd27e (v1.5.1). + * Git branch HEAD. * * See Duktape AUTHORS.rst and LICENSE.txt for copyright and * licensing information. @@ -218,16 +218,16 @@ struct duk_number_list_entry { * 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 10500L +#define DUK_VERSION 10501L /* 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 "83d557704ee63f68ab40b6fcb00995c9b3d6777c" -#define DUK_GIT_DESCRIBE "v1.5.0" -#define DUK_GIT_BRANCH "master" +#define DUK_GIT_COMMIT "2cc76e9ff1f64869e1146ad7317d8cbe33bbd27e" +#define DUK_GIT_DESCRIBE "v1.5.1" +#define DUK_GIT_BRANCH "HEAD" /* Duktape debug protocol version used by this build. */ #define DUK_DEBUG_PROTOCOL_VERSION 1 @@ -426,7 +426,7 @@ DUK_API_NORETURN(DUK_EXTERNAL_DECL void duk_error_raw(duk_context *ctx, duk_errc #ifdef DUK_API_VARIADIC_MACROS #define duk_error(ctx,err_code,...) \ - duk_error_raw((ctx), (duk_errcode_t) (err_code), (const char *) (__FILE__), (duk_int_t) (__LINE__), __VA_ARGS__) + duk_error_raw((ctx), (duk_errcode_t) (err_code), (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__) #else DUK_API_NORETURN(DUK_EXTERNAL_DECL void duk_error_stash(duk_context *ctx, duk_errcode_t err_code, const char *fmt, ...)); /* One problem with this macro is that expressions like the following fail @@ -434,14 +434,14 @@ DUK_API_NORETURN(DUK_EXTERNAL_DECL void duk_error_stash(duk_context *ctx, duk_er * they make little sense anyway. */ #define duk_error \ - (duk_api_global_filename = (const char *) (__FILE__), \ - duk_api_global_line = (duk_int_t) (__LINE__), \ + (duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \ + duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \ duk_error_stash) /* last value is func pointer, arguments follow in parens */ #endif DUK_API_NORETURN(DUK_EXTERNAL_DECL void duk_error_va_raw(duk_context *ctx, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, va_list ap)); #define duk_error_va(ctx,err_code,fmt,ap) \ - duk_error_va_raw((ctx), (duk_errcode_t) (err_code), (const char *) (__FILE__), (duk_int_t) (__LINE__), (fmt), (ap)) + duk_error_va_raw((ctx), (duk_errcode_t) (err_code), (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)) /* * Other state related functions @@ -547,19 +547,19 @@ DUK_EXTERNAL_DECL duk_idx_t duk_push_error_object_raw(duk_context *ctx, duk_errc #ifdef DUK_API_VARIADIC_MACROS #define duk_push_error_object(ctx,err_code,...) \ - duk_push_error_object_raw((ctx), (err_code), (const char *) (__FILE__), (duk_int_t) (__LINE__), __VA_ARGS__) + duk_push_error_object_raw((ctx), (err_code), (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__) #else DUK_EXTERNAL_DECL duk_idx_t duk_push_error_object_stash(duk_context *ctx, duk_errcode_t err_code, const char *fmt, ...); /* Note: parentheses are required so that the comma expression works in assignments. */ #define duk_push_error_object \ - (duk_api_global_filename = (const char *) (__FILE__), \ - duk_api_global_line = (duk_int_t) (__LINE__), \ + (duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \ + duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \ duk_push_error_object_stash) /* last value is func pointer, arguments follow in parens */ #endif DUK_EXTERNAL_DECL duk_idx_t duk_push_error_object_va_raw(duk_context *ctx, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, va_list ap); #define duk_push_error_object_va(ctx,err_code,fmt,ap) \ - duk_push_error_object_va_raw((ctx), (err_code), (const char *) (__FILE__), (duk_int_t) (__LINE__), (fmt), (ap)) + duk_push_error_object_va_raw((ctx), (err_code), (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)) #define DUK_BUF_FLAG_DYNAMIC (1 << 0) /* internal flag: dynamic buffer */ #define DUK_BUF_FLAG_EXTERNAL (1 << 1) /* internal flag: external buffer */ -- cgit v1.2.3