% Self souper upper. % % Strategy: run-time dynamic binding % Intercept /self. Determine run-time binding, and optimize code on the fly. systemdict begin systemdict /tracelog known not { systemdict /tracelog (tracelog) (w) file put } if systemdict /old_self known not { systemdict /old_self /self load put } if /self { % - => obj /estack currentprocess /ExecutionStack get /dstack currentprocess /DictionaryStack get /cd currentdict 20 dict begin def def def currentprocess /Stdout 2 copy get /f exch cvlit def tracelog put /caller estack dup length 4 sub get cvlit def /offset estack dup length 3 sub get cvlit def (SELF:\n) print caller isarray? { ( caller: { ) print offset 1 sub caller { 1 index 0 eq { (=> ) print } if (% ) printf dup 0 eq { (<= ) print } if 1 sub } forall (}\n) print pop } { ( caller: ) print caller = } ifelse ( offset: ) print offset == ( currentdict: ) print cd = cd isinstance? { ( instance of class: ) print /ClassName cd send == } { cd isclass? { ( class: ) print /ClassName cd send == } if } ifelse ( self: ) print old_self = old_self isinstance? { ( instance of class: ) print /ClassName old_self send == } { old_self isclass? { ( class: ) print /ClassName old_self send == } if } ifelse tracelog flushfile currentprocess /Stdout f put end old_self } def end % systemdict