Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e682be9f3e | ||
|
|
580607b910 | ||
|
|
baa09c72c5 | ||
|
|
ca63417594 | ||
|
|
21d419cbbf | ||
|
|
9e830a16c3 | ||
|
|
824630843d |
+7
-2
@@ -8462,7 +8462,12 @@ TclNRTailcallEval(
|
||||
TclMarkTailcall(interp);
|
||||
TclNRAddCallback(interp, TclNRReleaseValues, listPtr, NULL, NULL,NULL);
|
||||
iPtr->lookupNsPtr = (Namespace *) nsPtr;
|
||||
return TclNREvalObjv(interp, objc-1, objv+1, 0, NULL);
|
||||
/* Error messages (because TCL_EVAL_NOERR - don't call TEOV_PushExceptionHandlers,
|
||||
* to avoid exception on CONTINUE, BREAK or RETURN at level 0. */
|
||||
objc--; objv++;
|
||||
TclNRAddCallback(interp, TEOV_Error, INT2PTR(objc),
|
||||
(ClientData)objv, NULL, NULL);
|
||||
return TclNREvalObjv(interp, objc, objv, TCL_EVAL_NOERR, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -9089,7 +9094,7 @@ TclNRCoroutineObjCmd(
|
||||
|
||||
/* ensure that the command is looked up in the correct namespace */
|
||||
iPtr->lookupNsPtr = lookupNsPtr;
|
||||
Tcl_NREvalObj(interp, Tcl_NewListObj(objc-2, objv+2), 0);
|
||||
Tcl_NREvalObj(interp, Tcl_NewListObj(objc-2, objv+2), TCL_EVAL_NOERR);
|
||||
iPtr->numLevels--;
|
||||
|
||||
SAVE_CONTEXT(corPtr->running);
|
||||
|
||||
@@ -19,6 +19,7 @@ catch [list package require -exact Tcltest [info patchlevel]]
|
||||
|
||||
testConstraint testnrelevels [llength [info commands testnrelevels]]
|
||||
testConstraint memory [llength [info commands memory]]
|
||||
testConstraint testevalobjv [llength [info commands testevalobjv]]
|
||||
|
||||
set lambda [list {{start 0} {stop 10}} {
|
||||
# init
|
||||
@@ -781,6 +782,129 @@ test coroutine-8.1.2 {coro inject with result, ticket 42202ba1e5ff566e} -body {
|
||||
set result
|
||||
} -result {inject-executed}
|
||||
|
||||
# following tests cover direct break/return from coroutine into proc,
|
||||
# coro or top-level up-scope loop, in case of "infinite" loop the result is 10 or
|
||||
# `invalid command name "c"`, in case of broken scope - `invoked "break" outside of a loop`
|
||||
# (expected 1 for break and "" for return), test with "-nc" suffix are non-compiled.
|
||||
test coroutine-9.1a {as direct return from proc: break into proc up-scope loop} -setup {
|
||||
proc p {} {yield; return -code break}
|
||||
} -body {
|
||||
coroutine c p;
|
||||
proc t {} {while {[incr i] < 10} {c}; set i}
|
||||
t
|
||||
} -cleanup {
|
||||
rename p {}; rename t {}
|
||||
} -result 1
|
||||
test coroutine-9.1b {as direct return from proc: break into top-level up-scope loop} -setup {
|
||||
proc p {} {yield; return -code break}
|
||||
set i 0
|
||||
} -body {
|
||||
coroutine c p;
|
||||
while {[incr i] < 10} {c}; set i
|
||||
} -cleanup {
|
||||
rename p {}
|
||||
} -result 1
|
||||
test coroutine-9.1b-nc {as direct return from proc: break into top-level up-scope loop (non-compiled)} \
|
||||
-constraints {testevalobjv} -body {
|
||||
exec [info nameofexecutable] << {
|
||||
proc p {} {yield; return -code break}
|
||||
set i 0
|
||||
coroutine c p;
|
||||
testevalobjv 1 while {[incr i] < 10} c; puts $i
|
||||
}
|
||||
} -result 1
|
||||
test coroutine-9.1c {as direct return from coro: break into lambda up-scope loop} -setup {
|
||||
proc p {} {yield; return -code break}
|
||||
set i 0
|
||||
} -body {
|
||||
apply {{} {coroutine c p; while {[incr i] < 10} c; set i}}
|
||||
} -cleanup {
|
||||
rename p {}
|
||||
} -result 1
|
||||
test coroutine-9.1d {no yield, as direct return from proc: break into proc up-scope loop} -setup {
|
||||
proc p {} {return -code break}
|
||||
} -body {
|
||||
proc t {} {while {[incr i] < 10} {coroutine c p}; set i}
|
||||
t
|
||||
} -cleanup {
|
||||
rename p {}; rename t {}
|
||||
} -result 1
|
||||
test coroutine-9.1e {no yield, as direct return from proc: break into top-level up-scope loop} -setup {
|
||||
proc p {} {return -code break}
|
||||
set i 0
|
||||
} -body {
|
||||
while {[incr i] < 10} {coroutine c p}; set i
|
||||
} -cleanup {
|
||||
rename p {}
|
||||
} -result 1
|
||||
test coroutine-9.1e-nc {no yield, as direct return from proc: break into top-level up-scope loop (non-compiled)} \
|
||||
-constraints {testevalobjv} -body {
|
||||
exec [info nameofexecutable] << {
|
||||
proc p {} {return -code break}
|
||||
set i 0
|
||||
testevalobjv 1 while {[incr i] < 10} {coroutine c p}; puts $i
|
||||
}
|
||||
} -result 1
|
||||
|
||||
test coroutine-9.2a {as direct return from proc: return into proc up-scope loop} -setup {
|
||||
proc p {} {yield; return -code return}
|
||||
} -body {
|
||||
coroutine c p;
|
||||
proc t {} {while {[incr i] < 10} {c}; set i}
|
||||
t
|
||||
} -cleanup {
|
||||
rename p {}; rename t {}
|
||||
} -result ""
|
||||
test coroutine-9.2b {as direct return from proc: return into top-level up-scope loop} -setup {
|
||||
proc p {} {yield; return -code return}
|
||||
set i 0
|
||||
} -body {
|
||||
coroutine c p;
|
||||
while {[incr i] < 10} {c}; set i
|
||||
} -cleanup {
|
||||
rename p {}
|
||||
} -result ""
|
||||
test coroutine-9.2b-nc {as direct return from proc: return into top-level up-scope loop (non-compiled)} \
|
||||
-constraints {testevalobjv} -body {
|
||||
exec [info nameofexecutable] << {
|
||||
proc p {} {yield; return -code return}
|
||||
set i 0
|
||||
coroutine c p;
|
||||
testevalobjv 1 while {[incr i] < 10} c; puts $i
|
||||
}
|
||||
} -result ""
|
||||
test coroutine-9.2c {as direct return from coro: return into lambda up-scope loop} -setup {
|
||||
proc p {} {yield; return -code return}
|
||||
set i 0
|
||||
} -body {
|
||||
apply {{} {coroutine c p; while {[incr i] < 10} c; set i}}
|
||||
} -cleanup {
|
||||
rename p {}
|
||||
} -result ""
|
||||
test coroutine-9.2d {no yield, as direct return from proc: return into proc up-scope loop} -setup {
|
||||
proc p {} {return -code return}
|
||||
} -body {
|
||||
proc t {} {while {[incr i] < 10} {coroutine c p}; set i}
|
||||
t
|
||||
} -cleanup {
|
||||
rename p {}; rename t {}
|
||||
} -result ""
|
||||
test coroutine-9.2e {no yield, as direct return from proc: return into top-level up-scope loop} -setup {
|
||||
proc p {} {return -code return}
|
||||
set i 0
|
||||
} -body {
|
||||
while {[incr i] < 10} {coroutine c p}; set i
|
||||
} -cleanup {
|
||||
rename p {}
|
||||
} -result ""
|
||||
test coroutine-9.2e-nc {no yield, as direct return from proc: return into top-level up-scope loop (non-compiled)} \
|
||||
-constraints {testevalobjv} -body {
|
||||
exec [info nameofexecutable] << {
|
||||
proc p {} {return -code return}
|
||||
set i 0
|
||||
testevalobjv 1 while {[incr i] < 10} {coroutine c p}; puts $i
|
||||
}
|
||||
} -result ""
|
||||
|
||||
|
||||
# cleanup
|
||||
|
||||
@@ -18,6 +18,7 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
|
||||
catch [list package require -exact Tcltest [info patchlevel]]
|
||||
|
||||
testConstraint testnrelevels [llength [info commands testnrelevels]]
|
||||
testConstraint testevalobjv [llength [info commands testevalobjv]]
|
||||
|
||||
#
|
||||
# The tests that risked blowing the C stack on failure have been removed: we
|
||||
@@ -708,6 +709,93 @@ test tailcall-14.1-bc {{in a deleted namespace} {byte compiled}} -body {
|
||||
}
|
||||
} -returnCodes 1 -result {namespace "::ns" not found}
|
||||
|
||||
# following tests cover tailcall as direct break/return from proc into proc,
|
||||
# coro or top-level up-scope loop, in case of "infinite" loop the result is 10
|
||||
# (expected 1 for break and "" for return), test with "-nc" suffix are non-compiled.
|
||||
test tailcall-15.1a {as direct return from proc: break into proc up-scope loop} -setup {
|
||||
proc p {} {tailcall break}
|
||||
} -body {
|
||||
proc t {} {while {[incr i] < 10} p; set i}
|
||||
t
|
||||
} -cleanup {
|
||||
rename p {}; rename t {}
|
||||
} -result 1
|
||||
test tailcall-15.1b {as direct return from proc: break into top-level up-scope loop} -setup {
|
||||
proc p {} {tailcall break}
|
||||
set i 0
|
||||
} -body {
|
||||
while {[incr i] < 10} p; set i
|
||||
} -cleanup {
|
||||
rename p {}
|
||||
} -result 1
|
||||
test tailcall-15.1b-nc {as direct return from proc: break into top-level up-scope loop (non-compiled)} \
|
||||
-constraints {testevalobjv} -body {
|
||||
exec [info nameofexecutable] << {
|
||||
proc p {} {tailcall break}
|
||||
set i 0
|
||||
while {[incr i] < 10} p; puts $i
|
||||
}
|
||||
} -result 1
|
||||
test tailcall-15.1c {as direct return from coro: break into lambda up-scope loop} -setup {
|
||||
proc p {} {yield; tailcall break}
|
||||
set i 0
|
||||
} -body {
|
||||
apply {{} {coroutine c p}}
|
||||
while {[incr i] < 10} c; set i
|
||||
} -cleanup {
|
||||
rename p {}
|
||||
} -result 1
|
||||
test tailcall-15.1d {as direct return from proc: break into coro up-scope loop} -setup {
|
||||
proc p {} {tailcall break}
|
||||
set i 0
|
||||
} -body {
|
||||
apply {{} {while {[incr i] < 10} {coroutine c p}; set i}}
|
||||
} -cleanup {
|
||||
rename p {}
|
||||
} -result 1
|
||||
|
||||
test tailcall-15.2a {as direct return from proc: return into proc up-scope loop} -setup {
|
||||
proc p {} {tailcall return}
|
||||
} -body {
|
||||
proc t {} {while {[incr i] < 10} p; set i}
|
||||
t
|
||||
} -cleanup {
|
||||
rename p {}; rename t {}
|
||||
} -result ""
|
||||
test tailcall-15.2b {as direct return from proc: return into top-level up-scope loop} -setup {
|
||||
proc p {} {tailcall return}
|
||||
set i 0
|
||||
} -body {
|
||||
while {[incr i] < 10} p; set i
|
||||
} -cleanup {
|
||||
rename p {}
|
||||
} -result ""
|
||||
test tailcall-15.2b-nc {as direct return from proc: return into top-level up-scope loop (non-compiled)} \
|
||||
-constraints {testevalobjv} -body {
|
||||
exec [info nameofexecutable] << {
|
||||
proc p {} {tailcall return}
|
||||
set i 0
|
||||
while {[incr i] < 10} p; puts $i
|
||||
}
|
||||
} -result ""
|
||||
test tailcall-15.2c {as direct return from coro: return into lambda up-scope loop} -setup {
|
||||
proc p {} {yield; tailcall return}
|
||||
set i 0
|
||||
} -body {
|
||||
apply {{} {coroutine c p}}
|
||||
while {[incr i] < 10} c; set i
|
||||
} -cleanup {
|
||||
rename p {}
|
||||
} -result ""
|
||||
test tailcall-15.2d {as direct return from proc: return into coro up-scope loop} -setup {
|
||||
proc p {} {tailcall return}
|
||||
set i 0
|
||||
} -body {
|
||||
apply {{} {while {[incr i] < 10} {coroutine c p}; set i}}
|
||||
} -cleanup {
|
||||
rename p {}
|
||||
} -result ""
|
||||
|
||||
# cleanup
|
||||
::tcltest::cleanupTests
|
||||
|
||||
|
||||
Reference in New Issue
Block a user