Skip to content

Commit

Permalink
* core/callcc.c: bug in continuations. needed to send back self ra…
Browse files Browse the repository at this point in the history
…ther than `cl` from the yield.

 * test: a few tests of continuations.
  • Loading branch information
_why committed Jul 17, 2009
1 parent 3234618 commit 2d18fee
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 6 deletions.
11 changes: 6 additions & 5 deletions core/callcc.c
Expand Up @@ -24,7 +24,8 @@ PN potion_continuation_yield(Potion *P, PN cl, PN self) {
#endif

if ((PN)sp1 != cc->stack[0]) {
fprintf(stderr, "** TODO: continuations which switch stacks must be rewritten.\n");
fprintf(stderr, "** TODO: continuations which switch stacks must be rewritten. (%p != %p)\n",
sp1, (void *)(cc->stack[0]));
return PN_NIL;
}

Expand All @@ -50,9 +51,9 @@ PN potion_continuation_yield(Potion *P, PN cl, PN self) {
"mov 0x30(%%rbx), %%r14;"
"mov 0x38(%%rbx), %%r15;"
"mov 0x18(%%rbx), %%rbx;"
"leave; ret"
"leaveq; retq"
:/* no output */
:"r"(cl), "r"(start), "r"(end), "r"(cc->stack)
:"r"(cc), "r"(start), "r"(end), "r"(cc->stack)
:"%rax", "%rsp", "%rbx"
);
#else
Expand All @@ -73,14 +74,14 @@ PN potion_continuation_yield(Potion *P, PN cl, PN self) {
"mov 0xc(%%esi), %%esi;"
"leave; ret"
:/* no output */
:"r"(cl), "r"(start), "r"(end), "r"(cc->stack)
:"r"(cc), "r"(start), "r"(end), "r"(cc->stack)
:"%eax", "%esp", "%ebp", "%esi"
);
#endif
#else
fprintf(stderr, "** TODO: callcc does not work outside of X86.\n");
#endif
return cl;
return self;
}

PN potion_callcc(Potion *P, PN cl, PN self) {
Expand Down
2 changes: 1 addition & 1 deletion core/pn-scan.rl
Expand Up @@ -58,7 +58,7 @@
path = "/" ("/" | utfw)+;
query = "?" eats message;
querypath = "?" eats path;
comment = "#"+ (utf8 - newline)*;
comment = "#"+ (utf8 - newline)* newline?;

nil = "nil";
true = "true";
Expand Down
9 changes: 9 additions & 0 deletions test/flow/callcc.pn
@@ -0,0 +1,9 @@
names = ("Freddie", "Herbie", "Ron", "Max", "Ringo")
goto = here
name = names pop
(name, "\n") join print
if (name != "Ron"): goto ().
# Ringo
# Max
# Ron
# nil
55 changes: 55 additions & 0 deletions test/flow/except.pn
@@ -0,0 +1,55 @@
Exception =
class (msg, mark):
/message = msg
/mark = mark
/ignored = false.

Exception resume = ():
/ignored = true
"RESUMING\n" print
m = /mark
m ().

SCOPES = ()

throw = (msg):
e = Exception (msg, here)
if (! e /ignored):
s = SCOPES last
c = s (0), s (0) = e
c ().
nil.

try = (block, catch):
cc = ()
c = here
if (! cc (0)):
cc push (c)
SCOPES push (cc)
block ()
. else:
catch (SCOPES last (0)).
.

1 to 2 (x):
try (:
"TRY\n" print
if (x == 1):
throw ("TRY ERROR!\n").
"SUCCESS\n" print.

(e):
e /message print
e resume.
)
.

nil

# TRY
# TRY ERROR!
# RESUMING
# SUCCESS
# TRY
# SUCCESS
# nil

0 comments on commit 2d18fee

Please sign in to comment.