CpS 450 Language Translation Systems

Code Generation - Method Calls

A MiniDream program must generate code for method calls that occur in two different contexts:

  • Call Statement
  • Call Expression

The techniques for handling both are similar.

Call Statements

The following is the only legal method call statement in MiniDream:

out.writeint(expr)

To generate code for this call, you first generate code to evaluate expr.

After evaluating expr, emit a call instruction to invoke the writeint function in the MiniDream standard library, followed by an instruction to remove the parameter from the stack:

call writeint
addl $4, %esp  

For example, consider the following MiniDream fragment:

out.writeint(x + 3)

Here’s the code your compiler might generate:

pushl x          # from IdExpr
pushl $3         # from IntLitExpr
popl %ebx        # now, BinOpExpr
popl %eax
addl %ebx, %eax
pushl %eax
# Now, from CallStmt, perform the call and clean up the stack
call writeint
addl $4, %esp

Call Expressions

The following is the only legal method call that may occur in an expression in MiniDream:

in.readint()

Generating code for this call is much the same as for a call statement. The difference is that, after the call completes, you must push the return value onto the stack, to be used in the expression evaluation.

The C calling convention specifies that the called function leaves its return value in the EAX register. Thus, in visitCallExpr, you might emit code like this:

call readint
pushl %eax  

For example, consider the following Dream fragment:

x := in.readint()

Here’s the code your compiler might generate:

# From visitCallExpr, perform the call
call readint
pushl %eax

# Now, from visitAssignStmt...
popl _x