diff --git a/src/duktape/duktape/duk_config.h b/src/duktape/duktape/duk_config.h index 64c10ea79f..c0ebc0c88c 100644 --- a/src/duktape/duktape/duk_config.h +++ b/src/duktape/duktape/duk_config.h @@ -1,9 +1,9 @@ /* * duk_config.h configuration header generated by genconfig.py. * - * Git commit: cad6f595382a0cc1a7e4207794ade5be11b3e397 - * Git describe: v1.4.0 - * Git branch: master + * Git commit: 70315eded64ade7852680433e4becbfa28afe8e2 + * Git describe: v1.4.1 + * Git branch: HEAD * * Supported platforms: * - Mac OSX, iPhone, Darwin @@ -3126,7 +3126,7 @@ typedef FILE duk_file; #elif defined(DUK_OPT_NO_PACKED_TVAL) #undef DUK_USE_PACKED_TVAL #else -#undef DUK_USE_PACKED_TVAL +/* Already provided above */ #endif #undef DUK_USE_PANIC_ABORT @@ -3213,7 +3213,7 @@ typedef FILE duk_file; #elif defined(DUK_OPT_NO_SETJMP) #undef DUK_USE_SETJMP #else -#define DUK_USE_SETJMP +/* Already provided above */ #endif #if defined(DUK_OPT_SHUFFLE_TORTURE) @@ -3229,7 +3229,7 @@ typedef FILE duk_file; #elif defined(DUK_OPT_NO_SIGSETJMP) #undef DUK_USE_SIGSETJMP #else -#undef DUK_USE_SIGSETJMP +/* Already provided above */ #endif #if defined(DUK_OPT_SOURCE_NONBMP) @@ -3319,7 +3319,7 @@ typedef FILE duk_file; #elif defined(DUK_OPT_NO_UNDERSCORE_SETJMP) #undef DUK_USE_UNDERSCORE_SETJMP #else -#undef DUK_USE_UNDERSCORE_SETJMP +/* Already provided above */ #endif #if defined(DUK_OPT_DECLARE) diff --git a/src/duktape/duktape/duktape.c b/src/duktape/duktape/duktape.c index dc62df8d19..031e47e236 100644 --- a/src/duktape/duktape/duktape.c +++ b/src/duktape/duktape/duktape.c @@ -1,8 +1,8 @@ /* - * Single source autogenerated distributable for Duktape 1.4.0. + * Single source autogenerated distributable for Duktape 1.4.1. * - * Git commit cad6f595382a0cc1a7e4207794ade5be11b3e397 (v1.4.0). - * Git branch master. + * Git commit 70315eded64ade7852680433e4becbfa28afe8e2 (v1.4.1). + * Git branch HEAD. * * See Duktape AUTHORS.rst and LICENSE.txt for copyright and * licensing information. @@ -12367,35 +12367,35 @@ DUK_INTERNAL const duk_uint8_t duk_builtins_data[1955] = { 146,25,106,5,0,4,101,40,20,0,21,146,160,80,0,102,66,129,64,1,216,234,5,0,8, 99,39,47,49,83,215,152,138,73,0,1,97,168,129,132,160,80,0,150,10,129,64,2, 152,10,5,0,11,95,168,20,0,48,31,255,224,5,17,72,66,249,37,129,127,255,0,0, -191,255,128,0,63,255,197,31,192,0,0,0,0,0,80,196,64,8,26,112,17,169,0,154, -80,1,171,28,124,88,65,233,49,7,133,100,29,149,15,14,138,71,135,37,3,195,66, -114,5,77,252,0,243,178,40,25,200,48,101,30,0,127,210,128,0,85,31,192,0,31, -244,224,5,71,22,8,0,13,20,88,1,85,127,0,0,127,212,128,21,29,220,32,0,52,87, -112,5,89,252,0,1,255,86,16,166,64,0,0,0,0,0,0,2,0,170,72,38,29,219,247,16, -49,75,32,193,52,130,244,193,225,114,96,248,0,8,249,48,124,0,8,90,152,62,0, -6,44,76,31,0,4,21,166,15,128,2,147,255,252,38,212,16,184,155,250,226,217, -150,47,46,91,249,54,96,139,229,229,203,127,36,26,119,32,203,203,150,254,72, -52,97,221,147,102,157,217,192,10,191,248,0,157,4,72,15,250,224,1,154,140, -36,0,8,43,31,224,0,15,251,0,16,55,139,164,0,192,220,46,144,2,3,104,186,64, -12,77,130,233,0,33,53,139,164,0,200,212,46,144,2,35,72,186,64,8,205,2,233, -0,36,51,140,180,0,192,204,50,208,2,3,40,203,64,12,76,131,45,0,33,49,140, -180,0,200,196,50,208,2,35,8,203,64,8,204,3,45,0,36,7,255,248,1,82,101,16, -112,24,72,0,8,86,159,193,56,192,0,0,0,0,0,0,240,63,1,151,246,96,0,21,183, -240,78,48,0,0,0,0,0,0,60,15,192,101,253,168,0,5,113,252,19,140,0,0,0,0,0,0, -15,3,240,25,127,110,0,1,93,127,4,227,0,0,0,0,0,0,0,1,0,6,95,220,128,0,87, -159,193,56,192,0,0,0,0,0,0,0,64,1,151,247,96,0,21,247,240,78,48,0,0,0,0,0, -0,4,16,0,101,253,232,0,5,129,252,19,140,0,0,0,0,0,0,1,4,0,25,127,126,0,1, -97,127,4,227,0,0,0,0,0,0,0,65,0,6,95,224,128,0,88,159,193,56,192,0,0,0,0,0, -0,32,64,1,151,248,96,0,22,55,240,5,157,170,33,68,178,69,10,193,20,10,104, -79,138,36,0,12,31,248,160,88,154,23,66,100,93,32,2,9,129,116,128,0,165,197, -210,0,18,150,23,72,0,138,84,93,32,3,41,65,116,128,1,36,197,210,0,20,146,23, -72,0,146,68,93,32,3,73,1,116,128,1,163,197,210,0,22,142,23,72,0,34,52,93, -32,1,136,193,118,128,2,162,197,218,0,26,138,23,104,0,170,36,93,160,3,168, -129,150,33,198,90,0,32,134,25,104,0,10,20,101,160,1,40,65,150,128,8,160, -198,90,0,50,130,25,104,0,18,4,101,160,1,72,1,150,128,9,31,198,90,0,52,126, -25,104,0,25,244,101,160,1,103,193,150,128,2,30,198,90,0,24,122,25,136,0,41, -228,102,32,1,167,129,152,128,10,157,198,98,0,59,71,91,99,157,104,9,213,118, -39,5,8,159,20,40,0,10,109,90,19,81,132,39,151,32, +191,255,128,0,63,255,197,31,192,0,0,0,0,128,80,196,64,8,26,112,17,169,0, +154,80,1,171,28,124,88,65,233,49,7,133,100,29,149,15,14,138,71,135,37,3, +195,66,114,5,77,252,0,243,178,40,25,200,48,101,30,0,127,210,128,0,85,31, +192,0,31,244,224,5,71,22,8,0,13,20,88,1,85,127,0,0,127,212,128,21,29,220, +32,0,52,87,112,5,89,252,0,1,255,86,16,166,64,0,0,0,0,0,0,2,0,170,72,38,29, +219,247,16,49,75,32,193,52,130,244,193,225,114,96,248,0,8,249,48,124,0,8, +90,152,62,0,6,44,76,31,0,4,21,166,15,128,2,147,255,252,38,212,16,184,155, +250,226,217,150,47,46,91,249,54,96,139,229,229,203,127,36,26,119,32,203, +203,150,254,72,52,97,221,147,102,157,217,192,10,191,248,0,157,4,72,15,250, +224,1,154,140,36,0,8,43,31,224,0,15,251,0,16,55,139,164,0,192,220,46,144,2, +3,104,186,64,12,77,130,233,0,33,53,139,164,0,200,212,46,144,2,35,72,186,64, +8,205,2,233,0,36,51,140,180,0,192,204,50,208,2,3,40,203,64,12,76,131,45,0, +33,49,140,180,0,200,196,50,208,2,35,8,203,64,8,204,3,45,0,36,7,255,248,1, +82,101,16,112,24,72,0,8,86,159,193,56,192,0,0,0,0,0,0,240,63,1,151,246,96, +0,21,183,240,78,48,0,0,0,0,0,0,60,15,192,101,253,168,0,5,113,252,19,140,0, +0,0,0,0,0,15,3,240,25,127,110,0,1,93,127,4,227,0,0,0,0,0,0,0,1,0,6,95,220, +128,0,87,159,193,56,192,0,0,0,0,0,0,0,64,1,151,247,96,0,21,247,240,78,48,0, +0,0,0,0,0,4,16,0,101,253,232,0,5,129,252,19,140,0,0,0,0,0,0,1,4,0,25,127, +126,0,1,97,127,4,227,0,0,0,0,0,0,0,65,0,6,95,224,128,0,88,159,193,56,192,0, +0,0,0,0,0,32,64,1,151,248,96,0,22,55,240,5,157,170,33,68,178,69,10,193,20, +10,104,79,138,36,0,12,31,248,160,88,154,23,66,100,93,32,2,9,129,116,128,0, +165,197,210,0,18,150,23,72,0,138,84,93,32,3,41,65,116,128,1,36,197,210,0, +20,146,23,72,0,146,68,93,32,3,73,1,116,128,1,163,197,210,0,22,142,23,72,0, +34,52,93,32,1,136,193,118,128,2,162,197,218,0,26,138,23,104,0,170,36,93, +160,3,168,129,150,33,198,90,0,32,134,25,104,0,10,20,101,160,1,40,65,150, +128,8,160,198,90,0,50,130,25,104,0,18,4,101,160,1,72,1,150,128,9,31,198,90, +0,52,126,25,104,0,25,244,101,160,1,103,193,150,128,2,30,198,90,0,24,122,25, +136,0,41,228,102,32,1,167,129,152,128,10,157,198,98,0,59,71,91,99,157,104, +9,213,118,39,5,8,159,20,40,0,10,109,90,19,81,132,39,151,32, }; #ifdef DUK_USE_BUILTIN_INITJS DUK_INTERNAL const duk_uint8_t duk_initjs_data[187] = { @@ -12754,8 +12754,8 @@ DUK_INTERNAL const duk_uint8_t duk_builtins_data[1955] = { 98,146,25,106,5,0,4,101,40,20,0,21,146,160,80,0,102,66,129,64,1,216,234,5, 0,8,99,39,47,49,83,215,152,138,73,0,1,97,168,129,132,160,80,0,150,10,129, 64,2,152,10,5,0,11,95,168,20,0,48,31,255,224,5,17,72,66,249,37,129,127,255, -0,0,191,255,128,0,63,255,197,31,192,64,196,80,0,0,0,0,0,8,26,112,17,169,0, -154,80,1,171,28,124,88,65,233,49,7,133,100,29,149,15,14,138,71,135,37,3, +0,0,191,255,128,0,63,255,197,31,192,64,196,80,128,0,0,0,0,8,26,112,17,169, +0,154,80,1,171,28,124,88,65,233,49,7,133,100,29,149,15,14,138,71,135,37,3, 195,66,114,5,77,252,0,243,178,40,25,200,48,101,30,0,127,210,128,0,85,31, 192,0,31,244,224,5,71,22,8,0,13,20,88,1,85,127,0,0,127,212,128,21,29,220, 32,0,52,87,112,5,89,252,0,1,255,86,16,166,66,0,0,0,0,0,0,0,0,170,72,38,29, @@ -13141,8 +13141,8 @@ DUK_INTERNAL const duk_uint8_t duk_builtins_data[1955] = { 98,146,25,106,5,0,4,101,40,20,0,21,146,160,80,0,102,66,129,64,1,216,234,5, 0,8,99,39,47,49,83,215,152,138,73,0,1,97,168,129,132,160,80,0,150,10,129, 64,2,152,10,5,0,11,95,168,20,0,48,31,255,224,5,17,72,66,249,37,129,127,255, -0,0,191,255,128,0,63,255,197,31,192,0,80,196,64,0,0,0,0,8,26,112,17,169,0, -154,80,1,171,28,124,88,65,233,49,7,133,100,29,149,15,14,138,71,135,37,3, +0,0,191,255,128,0,63,255,197,31,192,128,80,196,64,0,0,0,0,8,26,112,17,169, +0,154,80,1,171,28,124,88,65,233,49,7,133,100,29,149,15,14,138,71,135,37,3, 195,66,114,5,77,252,0,243,178,40,25,200,48,101,30,0,127,210,128,0,85,31, 192,0,31,244,224,5,71,22,8,0,13,20,88,1,85,127,0,0,127,212,128,21,29,220, 32,0,52,87,112,5,89,252,0,1,255,86,16,166,64,0,0,2,0,0,0,0,0,170,72,38,29, @@ -17183,6 +17183,8 @@ DUK_EXTERNAL void duk_debugger_attach(duk_context *ctx, * already attached? */ + DUK_D(DUK_DPRINT("application called duk_debugger_attach()")); + DUK_ASSERT_CTX_VALID(ctx); DUK_ASSERT(read_cb != NULL); DUK_ASSERT(write_cb != NULL); @@ -17229,6 +17231,8 @@ DUK_EXTERNAL void duk_debugger_attach(duk_context *ctx, DUK_EXTERNAL void duk_debugger_detach(duk_context *ctx) { duk_hthread *thr; + DUK_D(DUK_DPRINT("application called duk_debugger_detach()")); + DUK_ASSERT_CTX_VALID(ctx); thr = (duk_hthread *) ctx; DUK_ASSERT(thr != NULL); @@ -17258,9 +17262,7 @@ DUK_EXTERNAL void duk_debugger_cooperate(duk_context *ctx) { return; } - thr->heap->dbg_processing = 1; processed_messages = duk_debug_process_messages(thr, 1 /*no_block*/); - thr->heap->dbg_processing = 0; DUK_UNREF(processed_messages); } @@ -40057,6 +40059,7 @@ DUK_LOCAL void duk__debug_do_detach1(duk_heap *heap, duk_int_t reason) { */ if (heap->dbg_detaching) { + DUK_D(DUK_DPRINT("debugger already detaching, ignore detach1")); return; } @@ -40082,7 +40085,7 @@ DUK_LOCAL void duk__debug_do_detach1(duk_heap *heap, duk_int_t reason) { heap->dbg_write_flush_cb = NULL; /* heap->dbg_detached_cb: keep */ /* heap->dbg_udata: keep */ - heap->dbg_processing = 0; + /*heap->dbg_processing: keep on purpose to avoid debugger re-entry in detaching state */ heap->dbg_paused = 0; heap->dbg_state_dirty = 0; heap->dbg_force_restart = 0; @@ -40268,7 +40271,7 @@ DUK_INTERNAL void duk_debug_read_bytes(duk_hthread *thr, duk_uint8_t *data, duk_ #endif got = heap->dbg_read_cb(heap->dbg_udata, (char *) p, left); if (got == 0 || got > left) { - heap->dbg_write_cb = NULL; /* squelch further writes */ + heap->dbg_write_cb = NULL; /* squelch further writes in detach1() */ DUK_D(DUK_DPRINT("connection error during read, return zero data")); DUK__SET_CONN_BROKEN(thr, 1); goto fail; @@ -40563,7 +40566,7 @@ DUK_INTERNAL void duk_debug_write_bytes(duk_hthread *thr, const duk_uint8_t *dat #endif got = heap->dbg_write_cb(heap->dbg_udata, (const char *) p, left); if (got == 0 || got > left) { - heap->dbg_write_cb = NULL; /* squelch further writes */ + heap->dbg_write_cb = NULL; /* squelch further writes in detach1() */ DUK_D(DUK_DPRINT("connection error during write")); DUK__SET_CONN_BROKEN(thr, 1); return; @@ -40573,24 +40576,7 @@ DUK_INTERNAL void duk_debug_write_bytes(duk_hthread *thr, const duk_uint8_t *dat } DUK_INTERNAL void duk_debug_write_byte(duk_hthread *thr, duk_uint8_t x) { - duk_heap *heap; - duk_size_t got; - - DUK_ASSERT(thr != NULL); - heap = thr->heap; - DUK_ASSERT(heap != NULL); - - if (heap->dbg_write_cb == NULL) { - DUK_D(DUK_DPRINT("attempt to write 1 bytes in detached state, ignore")); - return; - } - - DUK_ASSERT(heap->dbg_write_cb != NULL); - got = heap->dbg_write_cb(heap->dbg_udata, (const char *) (&x), 1); - if (got != 1) { - DUK_D(DUK_DPRINT("connection error during write")); - DUK__SET_CONN_BROKEN(thr, 1); - } + duk_debug_write_bytes(thr, (const duk_uint8_t *) &x, 1); } DUK_INTERNAL void duk_debug_write_unused(duk_hthread *thr) { @@ -41860,18 +41846,17 @@ DUK_INTERNAL void duk_debug_halt_execution(duk_hthread *thr, duk_bool_t use_prev /* Process debug messages until we are no longer paused. */ - /* NOTE: This is a bit fragile. It's important to ensure that neither - * duk_debug_send_status() or duk_debug_process_messages() throws an - * error or act->curr_pc will never be reset. + /* NOTE: This is a bit fragile. It's important to ensure that + * duk_debug_process_messages() never throws an error or + * act->curr_pc will never be reset. */ - thr->heap->dbg_processing = 1; - duk_debug_send_status(thr); + thr->heap->dbg_state_dirty = 1; while (thr->heap->dbg_paused) { + DUK_ASSERT(DUK_HEAP_IS_DEBUGGER_ATTACHED(thr->heap)); DUK_ASSERT(thr->heap->dbg_processing); duk_debug_process_messages(thr, 0 /*no_block*/); } - thr->heap->dbg_processing = 0; /* XXX: Decrementing and restoring act->curr_pc works now, but if the * debugger message loop gains the ability to adjust the current PC @@ -41885,6 +41870,13 @@ DUK_INTERNAL void duk_debug_halt_execution(duk_hthread *thr, duk_bool_t use_prev } } +DUK_LOCAL void duk__check_resend_status(duk_hthread *thr) { + if (thr->heap->dbg_read_cb != NULL && thr->heap->dbg_state_dirty) { + duk_debug_send_status(thr); + thr->heap->dbg_state_dirty = 0; + } +} + DUK_INTERNAL duk_bool_t duk_debug_process_messages(duk_hthread *thr, duk_bool_t no_block) { duk_context *ctx = (duk_context *) thr; #if defined(DUK_USE_ASSERTIONS) @@ -41895,25 +41887,79 @@ DUK_INTERNAL duk_bool_t duk_debug_process_messages(duk_hthread *thr, duk_bool_t DUK_ASSERT(thr != NULL); DUK_UNREF(ctx); DUK_ASSERT(thr->heap != NULL); - DUK_ASSERT(DUK_HEAP_IS_DEBUGGER_ATTACHED(thr->heap)); #if defined(DUK_USE_ASSERTIONS) entry_top = duk_get_top(ctx); #endif + DUK_D(DUK_DPRINT("process debug messages: read_cb=%s, no_block=%ld, detaching=%ld, processing=%ld", + thr->heap->dbg_read_cb ? "not NULL" : "NULL", (long) no_block, + (long) thr->heap->dbg_detaching, (long) thr->heap->dbg_processing)); DUK_DD(DUK_DDPRINT("top at entry: %ld", (long) duk_get_top(ctx))); + /* thr->heap->dbg_detaching may be != 0 if a debugger write outside + * the message loop caused a transport error and detach1() to run. + */ + DUK_ASSERT(thr->heap->dbg_detaching == 0 || thr->heap->dbg_detaching == 1); + DUK_ASSERT(thr->heap->dbg_processing == 0); + thr->heap->dbg_processing = 1; + + /* Ensure dirty state causes a Status even if never process any + * messages. This is expected by the bytecode executor when in + * the running state. + */ + duk__check_resend_status(thr); + for (;;) { /* Process messages until we're no longer paused or we peek * and see there's nothing to read right now. */ DUK_DD(DUK_DDPRINT("top at loop top: %ld", (long) duk_get_top(ctx))); + DUK_ASSERT(thr->heap->dbg_processing == 1); + + while (thr->heap->dbg_read_cb == NULL && thr->heap->dbg_detaching) { + /* Detach is pending; can be triggered from outside the + * debugger loop (e.g. Status notify write error) or by + * previous message handling. Call detached callback + * here, in a controlled state, to ensure a possible + * reattach inside the detached_cb is handled correctly. + * + * Recheck for detach in a while loop: an immediate + * reattach involves a call to duk_debugger_attach() + * which writes a debugger handshake line immediately + * inside the API call. If the transport write fails + * for that handshake, we can immediately end up in a + * "transport broken, detaching" case several times here. + * Loop back until we're either cleanly attached or + * fully detached. + * + * NOTE: Reset dbg_processing = 1 forcibly, in case we + * re-attached; duk_debugger_attach() sets dbg_processing + * to 0 at the moment. + */ + + DUK_D(DUK_DPRINT("detach pending (dbg_read_cb == NULL, dbg_detaching != 0), call detach2")); + + duk__debug_do_detach2(thr->heap); + thr->heap->dbg_processing = 1; /* may be set to 0 by duk_debugger_attach() inside callback */ + + DUK_D(DUK_DPRINT("after detach2 (and possible reattach): dbg_read_cb=%s, dbg_detaching=%ld", + thr->heap->dbg_read_cb ? "not NULL" : "NULL", (long) thr->heap->dbg_detaching)); + } + DUK_ASSERT(thr->heap->dbg_detaching == 0); /* true even with reattach */ + DUK_ASSERT(thr->heap->dbg_processing == 1); /* even after a detach and possible reattach */ if (thr->heap->dbg_read_cb == NULL) { - DUK_D(DUK_DPRINT("debug connection broken, stop processing messages")); + DUK_D(DUK_DPRINT("debug connection broken (and not detaching), stop processing messages")); break; - } else if (!thr->heap->dbg_paused || no_block) { + } + + if (!thr->heap->dbg_paused || no_block) { if (!duk_debug_read_peek(thr)) { - DUK_D(DUK_DPRINT("processing debug message, peek indicated no data, stop processing")); + /* Note: peek cannot currently trigger a detach + * so the dbg_detaching == 0 assert outside the + * loop is correct. + */ + DUK_D(DUK_DPRINT("processing debug message, peek indicated no data, stop processing messages")); break; } DUK_D(DUK_DPRINT("processing debug message, peek indicated there is data, handle it")); @@ -41921,32 +41967,22 @@ DUK_INTERNAL duk_bool_t duk_debug_process_messages(duk_hthread *thr, duk_bool_t DUK_D(DUK_DPRINT("paused, process debug message, blocking if necessary")); } + duk__check_resend_status(thr); duk__debug_process_message(thr); + duk__check_resend_status(thr); - if (thr->heap->dbg_read_cb == NULL) { - /* Became detached during message handling (perhaps because - * of an error or by an explicit Detach). Call detached - * callback here, between messages, to avoid confusing the - * broken connection and a possible replacement (which may - * be provided by an instant reattach inside the detached - * callback). - */ - duk__debug_do_detach2(thr->heap); - } - if (thr->heap->dbg_state_dirty) { - /* Executed something that may have affected status, - * resend. - */ - duk_debug_send_status(thr); - thr->heap->dbg_state_dirty = 0; - } retval = 1; /* processed one or more messages */ } + DUK_ASSERT(thr->heap->dbg_detaching == 0); + DUK_ASSERT(thr->heap->dbg_processing == 1); + thr->heap->dbg_processing = 0; + /* As an initial implementation, read flush after exiting the message - * loop. + * loop. If transport is broken, this is a no-op (with debug logs). */ - duk_debug_read_flush(thr); + duk_debug_read_flush(thr); /* this cannot initiate a detach */ + DUK_ASSERT(thr->heap->dbg_detaching == 0); DUK_DD(DUK_DDPRINT("top at exit: %ld", (long) duk_get_top(ctx))); @@ -42999,7 +43035,7 @@ DUK_INTERNAL duk_hbuffer *duk_hbuffer_alloc(duk_heap *heap, duk_size_t size, duk if (flags & DUK_BUF_FLAG_EXTERNAL) { header_size = sizeof(duk_hbuffer_external); alloc_size = sizeof(duk_hbuffer_external); - } if (flags & DUK_BUF_FLAG_DYNAMIC) { + } else if (flags & DUK_BUF_FLAG_DYNAMIC) { header_size = sizeof(duk_hbuffer_dynamic); alloc_size = sizeof(duk_hbuffer_dynamic); } else { @@ -46506,8 +46542,12 @@ DUK_LOCAL void duk__refzero_free_pending(duk_hthread *thr) { DUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZABLE(h1)); DUK_ASSERT(DUK_HEAPHDR_HAS_FINALIZED(h1)); DUK_HEAPHDR_CLEAR_FINALIZED(h1); + h2 = heap->heap_allocated; DUK_HEAPHDR_SET_PREV(heap, h1, NULL); - DUK_HEAPHDR_SET_NEXT(heap, h1, heap->heap_allocated); + if (h2) { + DUK_HEAPHDR_SET_PREV(heap, h2, h1); + } + DUK_HEAPHDR_SET_NEXT(heap, h1, h2); heap->heap_allocated = h1; } else { /* no -> decref members, then free */ @@ -68732,10 +68772,11 @@ DUK_LOCAL void duk__interrupt_handle_debugger(duk_hthread *thr, duk_bool_t *out_ duk_breakpoint *bp; duk_breakpoint **bp_active; duk_uint_fast32_t line = 0; - duk_bool_t send_status; duk_bool_t process_messages; duk_bool_t processed_messages = 0; + DUK_ASSERT(thr->heap->dbg_processing == 0); /* don't re-enter e.g. during Eval */ + ctx = (duk_context *) thr; act = thr->callstack + thr->callstack_top - 1; @@ -68812,16 +68853,12 @@ DUK_LOCAL void duk__interrupt_handle_debugger(duk_hthread *thr, duk_bool_t *out_ * counter is used to rate limit getting timestamps. */ - if (thr->heap->dbg_state_dirty || thr->heap->dbg_paused) { - send_status = 1; - } else { - send_status = 0; - } - - if (thr->heap->dbg_paused) { + process_messages = 0; + if (thr->heap->dbg_state_dirty || thr->heap->dbg_paused || thr->heap->dbg_detaching) { + /* Enter message processing loop for sending Status notifys and + * to finish a pending detach. + */ process_messages = 1; - } else { - process_messages = 0; } /* XXX: remove heap->dbg_exec_counter, use heap->inst_count_interrupt instead? */ @@ -68846,33 +68883,33 @@ DUK_LOCAL void duk__interrupt_handle_debugger(duk_hthread *thr, duk_bool_t *out_ */ thr->heap->dbg_last_time = now; - send_status = 1; + thr->heap->dbg_state_dirty = 1; process_messages = 1; } } /* - * Send status + * Process messages and send status if necessary. + * + * If we're paused, we'll block for new messages. If we're not + * paused, we'll process anything we can peek but won't block + * for more. Detach (and re-attach) handling is all localized + * to duk_debug_process_messages() too. + * + * Debugger writes outside the message loop may cause debugger + * detach1 phase to run, after which dbg_read_cb == NULL and + * dbg_detaching != 0. The message loop will finish the detach + * by running detach2 phase, so enter the message loop also when + * detaching. */ act = NULL; /* may be changed */ - if (send_status) { - duk_debug_send_status(thr); - thr->heap->dbg_state_dirty = 0; - } - - /* - * Process messages. If we're paused, we'll block for new messages. - * if we're not paused, we'll process anything we can peek but won't - * block for more. - */ - if (process_messages) { + DUK_ASSERT(thr->heap->dbg_processing == 0); processed_messages = duk_debug_process_messages(thr, 0 /*no_block*/); + DUK_ASSERT(thr->heap->dbg_processing == 0); } - /* XXX: any case here where we need to re-send status? */ - /* Continue checked execution if there are breakpoints or we're stepping. * Also use checked execution if paused flag is active - it shouldn't be * because the debug message loop shouldn't terminate if it was. Step out @@ -68985,7 +69022,11 @@ DUK_LOCAL duk_small_uint_t duk__executor_interrupt(duk_hthread *thr) { #endif /* DUK_USE_EXEC_TIMEOUT_CHECK */ #if defined(DUK_USE_DEBUGGER_SUPPORT) - if (DUK_HEAP_IS_DEBUGGER_ATTACHED(thr->heap)) { + if (!thr->heap->dbg_processing && + (thr->heap->dbg_read_cb != NULL || thr->heap->dbg_detaching)) { + /* Avoid recursive re-entry; enter when we're attached or + * detaching (to finish off the pending detach). + */ duk__interrupt_handle_debugger(thr, &immediate, &retval); act = thr->callstack + thr->callstack_top - 1; /* relookup if changed */ } @@ -69021,6 +69062,7 @@ DUK_LOCAL duk_small_uint_t duk__executor_interrupt(duk_hthread *thr) { * in checked or normal mode. Note that we can't do this when an activation * is created, because breakpoint status (and stepping status) may change * later, so we must recheck every time we're executing an activation. + * This primitive should be side effect free to avoid changes during check. */ #if defined(DUK_USE_DEBUGGER_SUPPORT) @@ -69486,10 +69528,8 @@ DUK_LOCAL DUK_NOINLINE void duk__js_execute_bytecode_inner(duk_hthread *entry_th #if defined(DUK_USE_DEBUGGER_SUPPORT) if (DUK_HEAP_IS_DEBUGGER_ATTACHED(thr->heap) && !thr->heap->dbg_processing) { - thr->heap->dbg_processing = 1; duk__executor_recheck_debugger(thr, act, fun); - act = thr->callstack + thr->callstack_top - 1; /* relookup after side effects */ - thr->heap->dbg_processing = 0; + act = thr->callstack + thr->callstack_top - 1; /* relookup after side effects (no side effects currently however) */ } #endif /* DUK_USE_DEBUGGER_SUPPORT */ diff --git a/src/duktape/duktape/duktape.h b/src/duktape/duktape/duktape.h index 7f7a7c3273..7c8fcedeb9 100644 --- a/src/duktape/duktape/duktape.h +++ b/src/duktape/duktape/duktape.h @@ -1,12 +1,12 @@ /* - * Duktape public API for Duktape 1.4.0. + * Duktape public API for Duktape 1.4.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 cad6f595382a0cc1a7e4207794ade5be11b3e397 (v1.4.0). - * Git branch master. + * Git commit 70315eded64ade7852680433e4becbfa28afe8e2 (v1.4.1). + * Git branch HEAD. * * See Duktape AUTHORS.rst and LICENSE.txt for copyright and * licensing information. @@ -213,16 +213,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 10400L +#define DUK_VERSION 10401L /* 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 "cad6f595382a0cc1a7e4207794ade5be11b3e397" -#define DUK_GIT_DESCRIBE "v1.4.0" -#define DUK_GIT_BRANCH "master" +#define DUK_GIT_COMMIT "70315eded64ade7852680433e4becbfa28afe8e2" +#define DUK_GIT_DESCRIBE "v1.4.1" +#define DUK_GIT_BRANCH "HEAD" /* Duktape debug protocol version used by this build. */ #define DUK_DEBUG_PROTOCOL_VERSION 1