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)?;
|
arg.process(state, Some(sig), loc)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we increment the frame ptr to right after the current frame:
|
// Whatever shall we send as a frame pointer to the new fn? Our pool pointer, because we
|
||||||
// see cursed test case in vtest/forge_tests.rs
|
// know that's free, even if we've alloced anything, it'll increment it:
|
||||||
sig.emit("peekr");
|
sig.emit("popr"); sig.emit("peekr"); // take the frame ptr off and copy the pool off
|
||||||
let frame_size = sig.frame_size();
|
sig.emit("swap"); sig.emit("pushr"); // swap the pool under the frame and put the frame back on
|
||||||
if frame_size > 0 {
|
|
||||||
sig.emit_arg("add", frame_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Eval the target
|
// Eval the target
|
||||||
self.target.0.process(state, Some(sig), loc)?;
|
self.target.0.process(state, Some(sig), loc)?;
|
||||||
@@ -51,8 +48,7 @@ mod test {
|
|||||||
vec![
|
vec![
|
||||||
"push 2", // evaluating args, in order
|
"push 2", // evaluating args, in order
|
||||||
"push 3",
|
"push 3",
|
||||||
"peekr", // The new fn's frame ptr:
|
"popr", "peekr", "swap", "pushr", // Pool ptr to send to the new call
|
||||||
"add 6",
|
|
||||||
"push _forge_gensym_1", // evaluating target (this fn)
|
"push _forge_gensym_1", // evaluating target (this fn)
|
||||||
"call", // Actually make the call
|
"call", // Actually make the call
|
||||||
"pop", // expr-as-statement drops the evaluated value
|
"pop", // expr-as-statement drops the evaluated value
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ mod test {
|
|||||||
"_forge_gensym_3:", // fn main()
|
"_forge_gensym_3:", // fn main()
|
||||||
"dup", "pushr", // capture pool ptr
|
"dup", "pushr", // capture pool ptr
|
||||||
"pushr", // capture frame 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
|
"push _forge_gensym_1", // load foo
|
||||||
"call", // call it
|
"call", // call it
|
||||||
"pop", // Throw away its return value
|
"pop", // Throw away its return value
|
||||||
|
|||||||
@@ -86,7 +86,26 @@ fn scope_test() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[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
|
// This is a cursed subtlety of block scoping and the way calls are compiled. It's not actually
|
||||||
// a bug. It's explained below:
|
// a bug. It's explained below:
|
||||||
let src = "
|
let src = "
|
||||||
|
|||||||
Reference in New Issue
Block a user