[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Can someone explain how this apparent magic happens



I noticed that when you call a function say FOO which has
an argument BAR and you look at FOO's stack frame in the
debugger then BAR appears as a "Arg" slot in the stack frame.
But if you later SETQ BAR to something else and then do a
m-L in the debugger there are actually two entries for
BAR, the first labeled "Arg" with the original value passed
as a parameter, and the second labeled "Local" with the
the new value just SETQed. If I access BAR, of course I
get the new "Local" value. According to the naive expectation
of what the system is doing, I would have though that
a SETQ to an argument would simply overwrite the old value.
But how (and why) does the system retain the original
value and how does the system know how to get the old vs.
the new value when I access BAR depending upon whether
I have SETQed it?

To see my point, witness the following transcript:

  (defun foo (bar)
    (break)
    (setq bar 'quux)
    (break))
FOO
  (compile 'foo)
For Function FOO
  (BREAK) breakpoint in program
  (BREAK) breakpoint in program
FOO
  (foo 'baz)
Break: (BREAK) executed

FOO
   Arg 0 (BAR): BAZ
s-A, q:    Return from BREAK
s-B, q:    Return to Breakpoint ZMACS in Editor Typeout Window 1
s-C:           Editor Top Level
s-D:           Restart process Zmacs Windows
 Meta-L Show Frame :Detailed Yes :Clear Window Yes
 Called to return, funcalled.

FOO

 Arg 0 (BAR): BAZ

Disassembled code:
     0  ENTRY: 1 REQUIRED, 0 OPTIONAL
     1  CALL-0-IGNORE #'BREAK
=>   2  PUSH-CONSTANT 'QUUX
     3  POP-LOCAL FP|0          ;BAR
     4  CALL-0-RETURN #'BREAK
 Resume Proceed
Return from BREAK
Break: (BREAK) executed

FOO
   Arg 0 (BAR): BAZ
s-A, q:    Return from BREAK
s-B, q:    Return to Breakpoint ZMACS in Editor Typeout Window 1
s-C:           Editor Top Level
s-D:           Restart process Zmacs Windows
 Meta-L Show Frame :Detailed Yes :Clear Window Yes
 Called to return, funcalled.

FOO

 Arg 0 (BAR): BAZ
 Local 0 (BAR): QUUX

Disassembled code:
     0  ENTRY: 1 REQUIRED, 0 OPTIONAL
     1  CALL-0-IGNORE #'BREAK
     2  PUSH-CONSTANT 'QUUX
     3  POP-LOCAL FP|0          ;BAR
     4  CALL-0-RETURN #'BREAK
=> 

What I want to know in particular, is if I muck arround and
access stack frames via: SYS:%STACK-FRAME-POINTER and
DBG:FRAME-PREVIOUS-FRAME and then get a locative to a slot
in a stack frame via:

(SETQ BAR-LOCATION
      (SYS:%MAKE-POINTER-OFFSET SYS:DTP-LOCATIVE FRAME-OF-INTEREST 0))

where I know that in the FRAME-OF-INTEREST the desired argument
(say BAR as in the above example) is in slot 0 then does
BAR-LOCATION point to "Arg 0" or to "Local 0" i.e. BAZ or QUUX?
Can I be assured of this? What about both before and after I
do the first (SETQ BAR ...)? What happens if I do a
(SETQ (LOCATION-CONTENTS BAR-LOCATION) ...)? Do I change "Arg 0"
or "Local 0"? How can I access the alternate value? In general,
can someone please explain to me exactly what is going on here.
Please don't warn me that I am going to lose by mucking arround
with stack frames, there is a very compelling reason why I am
doing so. I understand that my code won't work on future machines
and under future releases but I still want to do what I am
doing.
        Thanks,
        Jeff
-------