Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chapter 7 and TailJmp replacement #16

Open
funnydog opened this issue Apr 2, 2022 · 0 comments
Open

Chapter 7 and TailJmp replacement #16

funnydog opened this issue Apr 2, 2022 · 0 comments

Comments

@funnydog
Copy link

funnydog commented Apr 2, 2022

Hi,

I'm at the end of Chapter 7 and I implemented the last pass, prelude-and-conclusion.

Unfortunately when I try to run the tests I get the following error:

lookup: didn't find rbp in (rax rdi r9 r15)

By looking at the debug output I was able to track down the problem with the way the interpreter applies the functions, in the call-function public method:

         ;; interpret the body of the function in the new-env
         (define result-env
           (parameterize ([get-basic-blocks blocks])
             ((interp-x86-block new-env)
              (dict-ref blocks (symbol-append f 'start)))))

Instead of calling the function, the evaluation begins at the start basic block, skipping the prelude.

While I understand that the reason it was done this way was to bypass the need of the function's entry/exit points while implementing the previous passes, unfortunately when the interpreter skips the prelude and the conclusion it misses a bunch of instructions like pushes (and pops).

When the TailJmp fake instruction is replaced with real instructions meant to pop the current frame (in the last pass), the interpreter doesn't know that %rbp (and possiby other registers) were pushed on the stack.

As a hack I changed the interpreter to add to the env the %rbp register but of course then it halts on unmatched popq.

I also tried unsuccessfully to fake the push and the pops, but then realized that what I really needed was the interpreter to execute the code in the prelude: it's there for a reason and faking its behavior wasn't going to cut it.

Is there a way to have the interpreter call the actual preludes and conclusions?

The produced code works correctly when compiled, and here I found another issue: the (compiler-tests) function matches only X86Program and not ProgramDefs, while interp-x86-4 doesn't like the X86Program AST node.

For now I'm only testing the last pass with the compilation step and comment out the pass when I need the interpreter. Is this the way it was supposed to work from the start?

I'd like to close this lengthy post by thanking you for the great source of knowledge this book / course is, I think I'm not only going to code my first compiler but also know every detail about it. It's mind opening and I'm really enjoying the journey with every incremental improvement.

Thank you,

funnydog

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant