Pattern Patter
| Post-Process Binaries |
January, 1998 |
| Add capabilities to a language without
extending the language. [Architecture Pattern] |
Example
You may have a source language that doesn't provide a particular
capability. You can't or won't change the source language. (Perhaps
you can't change the language; perhaps making the user recompile
just to acquire that capability is too time-consuming.)
Forces
- You want to add a generic capability without requiring its
presence to be (too) visible in the source language.
- You can afford to work in both the source and object
levels.
- You can map from the object level back to the source (as far as
your capability is concerned). Or perhaps the capability can be
interpreted independently of the source representation.
Resolution
Insert the capability at the object level. Provide tools to map
back to the source level if necessary.
Discussion
- The capability may interact with optimization; you need to
ensure that compiler optimizations will not significantly interfere
with your capability. For example, a tool to log procedure calls
might not detect inlined calls.
- The mapping to the source level is often problematic.
- Adding the capability will interfere with the usual timing of
operations.
Other Uses
- A debugger might cause a "break on call" by replacing a
procedure call with an interrupt or a call to the deugger's own
procedures. [ASPLOS ref on s/w breakpoints?]
- The Purify tool (from Rational) monitors a program for
illegal data access by replacing the user's standard libraries and
by modifying data access code in place.
- The ObjectStore database (from ODI) modifies C++ or Java object files to
add persistence. This case is interesting because they can use a
fairly non-intrusive change at the source level (e.g., inheriting
from a marker interface), then use that change as an indicator of
which objects to modify.
[Written 12-4-97; revised 1-6-98.]
|