Professional Documents
Culture Documents
C Sharp Nots
C Sharp Nots
C Sharp Nots
Parameter Passing
Lecture Outline
Topic 1
Review
add(w,x,y,z)
begin
x + (y + (z + (w + 42)))
end
xn
... pushed by
caller
popped x1
by callee Old FP
FP Return Addr.
FP−4
saved by
Temp NS(e)
callee
increasing ...
Temp 1
values of
addresses
(this diagram disagrees
direction of stack growth slightly with lecture 12:
here, the callee saves FP)
Topic 2
Handling Procedure Calls and Returns
space to save
i0-i7 and l0-l7 16 words
current sp if necessary
callee’s fp
callee’s frame
low addresses
high addresses
caller’s frame
incoming
arguments
return address
stack
saved growth
registers
frame ptr
ebp saved ebp
locals and
stack ptr temporaries
esp
callee’s frame
low addresses
high addresses
caller’s frame
incoming
arguments
locals and
temporaries stack
growth
callee-save
registers
outgoing
stack ptr arguments
$sp
callee’s frame
low addresses
Topic 3
Parameter Passing Mechanisms
callByValue(int y)
{
y = y + 1; output:
print(y); x = 42
} y = 43
x = 42
main()
{ x’s value does not
int x = 42; change when y’s
print(x); value is changed
callByValue(x);
print(x);
}
Compiler Design I (2011) 28
Call-by-reference
callByRef(int &y)
{
y = y + 1; output:
print(y); x = 42
} y = 43
x = 43
main()
{ x’s value changes
int x = 42; when y’s value
print(x); is changed
callByRef(x);
print(x);
}
Compiler Design I (2011) 29
Call-by-reference can be faked with pointers
C++: C:
callByRef(int &y) fakeCallByRef(int *y)
{ {
y = y + 1; *y = *y + 1;
print(y); print(*y);
} }
must explicitly
pass the address
main() main() of a local variable
{ {
int x = 42; int x = 42;
print(x); print(x);
callByRef(x); fakeCallByRef(&x);
print(x); print(x);
} }
callByValueResult(int y, int z)
{
y = y + 1; z = z + 1;
print(y); print(z); output:
} x = 42
y = 43
main() z = 43
{ x = 43
int x = 42;
print(x); Note that x’s value
is different from both
callByValueResult(x, x);
using call-by-value
print(x); and call-by-reference
}
Call-by-reference
The arguments must have allocated memory locations
The compiler passes the address of the variable, and
the parameter becomes an alias for the argument
Local accesses to the parameter are turned into
indirect accesses
Compiler Design I (2011) 34
Implementing Parameter Passing (Cont.)
Call-by-value-result
The arguments are evaluated at call time and the
value parameters are copied (as in call-by-value)
and used as a local variables
The final values of these variables are copied back to
the location of the arguments when the procedure
exits (note that the activation record cannot be
freed by the callee!)
code + environment
(env has just ‘x’ here)
callByName(int closure y)
{ eval
print(y);
print(y); // => print(x = x+1)
} output:
x = 42
both evals
main() y = 43
have side
{ y = 44
effects
int x = 42; x = 44
print(x);
callByName( [[ x = x+1 ]] ); x’s value changes
print(x); when y is evaluated
} closure
Topic 4
(probably not covered in lecture)
Object Layout
class P {
x : Int <- 3; self
0 tag: P
y : String <- "Hi"; 1 x 3
f( ) : Int { x }; 2 y “Hi”
z : Bool <- true; 3 f( ) P.f: “return self [1]”
g( ) : String { y }; 4 z true
}; 5 g( ) P.g: “return self [2]”
class P { .. (same) .. };
self
overridden
0 tag: C
class C inherits P { 1 x 3
w : Int <- 42; // new 2 y “Hi”
P
f( ) : Int { w }; // override 3 f( ) C.f: “return self [6]”
• Simple
– Just append subclass fields
• Efficient
– Code can ignore dynamic type -- just act as if it is
the static type
• Supports overriding of methods
– Just replace the appropriate dispatch pointers
• We implement type conformance (compile-time
concept) with representation conformance
(run-time concept)
Consider 3 instances
C.f: “return self [6]”
of class C:
tag: C tag: C tag: C
x x x
y y y
f( ) f( ) f( )
z z z
g( ) g( ) g( )
w w w
h( ) h( ) h( )
0 tag: P tag: C 0
1 dispPtr dispPtr 1
2 x x 2
3 y y 3
P.f: “return self [2]” 4 z z 4
w 5
Offset
(in bytes)
Needed for Class Tag 0
garbage Object Size 4
collector Dispatch Ptr 8
Attribute 1 12
Attribute 2 16
...