A bunch of prerequisites before we can do arrays, part 3.1, using the pool pointer in calls (removes the cursed test case)
This commit is contained in:
@@ -16,13 +16,10 @@ impl Compilable for Call {
|
||||
arg.process(state, Some(sig), loc)?;
|
||||
}
|
||||
|
||||
// Now we increment the frame ptr to right after the current frame:
|
||||
// see cursed test case in vtest/forge_tests.rs
|
||||
sig.emit("peekr");
|
||||
let frame_size = sig.frame_size();
|
||||
if frame_size > 0 {
|
||||
sig.emit_arg("add", frame_size);
|
||||
}
|
||||
// Whatever shall we send as a frame pointer to the new fn? Our pool pointer, because we
|
||||
// know that's free, even if we've alloced anything, it'll increment it:
|
||||
sig.emit("popr"); sig.emit("peekr"); // take the frame ptr off and copy the pool off
|
||||
sig.emit("swap"); sig.emit("pushr"); // swap the pool under the frame and put the frame back on
|
||||
|
||||
// Eval the target
|
||||
self.target.0.process(state, Some(sig), loc)?;
|
||||
@@ -51,8 +48,7 @@ mod test {
|
||||
vec![
|
||||
"push 2", // evaluating args, in order
|
||||
"push 3",
|
||||
"peekr", // The new fn's frame ptr:
|
||||
"add 6",
|
||||
"popr", "peekr", "swap", "pushr", // Pool ptr to send to the new call
|
||||
"push _forge_gensym_1", // evaluating target (this fn)
|
||||
"call", // Actually make the call
|
||||
"pop", // expr-as-statement drops the evaluated value
|
||||
|
||||
@@ -140,7 +140,7 @@ mod test {
|
||||
"_forge_gensym_3:", // fn main()
|
||||
"dup", "pushr", // capture pool ptr
|
||||
"pushr", // capture frame ptr
|
||||
"peekr", // prep frame ptr to send to foo
|
||||
"popr", "peekr", "swap", "pushr", // Grab pool ptr to send to foo
|
||||
"push _forge_gensym_1", // load foo
|
||||
"call", // call it
|
||||
"pop", // Throw away its return value
|
||||
|
||||
@@ -86,7 +86,26 @@ fn scope_test() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cursed_call_test() {
|
||||
fn recursion_test() {
|
||||
// Recursive call with some stuff in it
|
||||
assert_eq!(
|
||||
main_return(
|
||||
"fn sum(n) {
|
||||
if (n > 0) {
|
||||
return n + sum(n - 1);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
fn main() { return sum(5); }"),
|
||||
15
|
||||
)
|
||||
}
|
||||
|
||||
//#[test]
|
||||
// This is no longer cursed, or a test. The revised calling convention with the pool pointer makes
|
||||
// it now perfectly sane. Left here for posterity.
|
||||
fn _cursed_call_test() {
|
||||
// This is a cursed subtlety of block scoping and the way calls are compiled. It's not actually
|
||||
// a bug. It's explained below:
|
||||
let src = "
|
||||
|
||||
Reference in New Issue
Block a user