Browse Source

fix assertion error for tailcalls when the activation to be tailcalled from was an ecmascript activation with 'preventyield' flag

pull/9/head
Sami Vaarala 11 years ago
parent
commit
f9e2d4241a
  1. 9
      src/duk_js_call.c
  2. 6
      src/duk_js_executor.c

9
src/duk_js_call.c

@ -1885,6 +1885,12 @@ void duk_handle_ecma_call_setup(duk_hthread *thr,
DUK_DDD(DUK_DDDPRINT("tailcall disabled because 'caller' property enabled and target is non-strict")); DUK_DDD(DUK_DDDPRINT("tailcall disabled because 'caller' property enabled and target is non-strict"));
DUK_ASSERT(use_tailcall == 0); /* compiler ensures this */ DUK_ASSERT(use_tailcall == 0); /* compiler ensures this */
#endif #endif
act = thr->callstack + thr->callstack_top - 1;
if (act->flags & DUK_ACT_FLAG_PREVENT_YIELD) {
/* See: ecmascript-testcases/test-bug-tailcall-thread-yield-resume.js */
DUK_DDD(DUK_DDDPRINT("tailcall prevented by current activation having DUK_ACT_FLAG_PREVENTYIELD"));
use_tailcall = 0;
}
if (use_tailcall) { if (use_tailcall) {
duk_tval *tv1, *tv2; duk_tval *tv1, *tv2;
@ -1905,8 +1911,7 @@ void duk_handle_ecma_call_setup(duk_hthread *thr,
DUK_DDD(DUK_DDDPRINT("is tailcall, reusing activation at callstack top, at index %d", DUK_DDD(DUK_DDDPRINT("is tailcall, reusing activation at callstack top, at index %d",
thr->callstack_top - 1)); thr->callstack_top - 1));
act = thr->callstack + thr->callstack_top - 1; /* 'act' already set above */
DUK_UNREF(act); /* unreferenced unless assertions used */
DUK_ASSERT(!DUK_HOBJECT_HAS_BOUND(func)); DUK_ASSERT(!DUK_HOBJECT_HAS_BOUND(func));
DUK_ASSERT(!DUK_HOBJECT_HAS_NATIVEFUNCTION(func)); DUK_ASSERT(!DUK_HOBJECT_HAS_NATIVEFUNCTION(func));

6
src/duk_js_executor.c

@ -2613,8 +2613,14 @@ void duk_js_execute_bytecode(duk_hthread *entry_thread) {
*/ */
/* FIXME: optimize flag handling, by coordinating with bytecode */ /* FIXME: optimize flag handling, by coordinating with bytecode */
call_flags = 0; call_flags = 0;
if (flag_tailcall) { if (flag_tailcall) {
/* We request a tailcall, but in some corner cases
* call handling can decide that a tailcall is
* actually not possible.
* See: test-bug-tailcall-preventyield-assert.c.
*/
call_flags |= DUK_CALL_FLAG_IS_TAILCALL; call_flags |= DUK_CALL_FLAG_IS_TAILCALL;
} }

Loading…
Cancel
Save