Marcus Denker

Marcus Denker Squeak
email: squeak@21c3

Squeak

Introduction

This is not a real article. While putting together the demo image for for 21C3, I decided to not write an article that is just to be read (mostly because these are really boring to write...)

This text is just a short 'user manual' for that thing (we call it Squeak Image) that I will use for the demo at 21C3. So if you follow the instructions, you will be able to go through the slides and play with everything yourself.

Installation

The first thing we need to do is, you guessed it correctly: Installing Squeak on your system. Squeak has been ported to everything, from handhelds to mainframes, or even game systems like the PS2. Not all of the ports are kept alive for all releases, but for a common system like Linux, MacOS, and that-which-shallnot-be-named there should be no problem.

So go to squeak.org and download Squeak for your system and unpack. The files we will need for running the demo are:

• SqueakV3.sources: The source code. All in one big lump.

• Squeak.exe / Squeak.app / squeak: This is the virtual machine. that's it. And the files from the 21c2 demo:

• 21c3.image: all the Objects that make our demo, dumped into a file • 21c3.changes: additional source code You can dowload these here: http://squeak-ev.de/21c3

Just put these files in a directory, and you are ready to start.

Start Up

Now we need to start Squeak. For that, just open the "image" file with the help of the vm. For linux, that would be something like:

./squeak 21c3.image MacOS/Win: drag-n-drop the image on the vm. Now the Squeak virtual machine will start and load the image back into memory. The image is really an image: It's just a snapshot of the whole memory that the vm had allocated. It will start up exactly the way it was when I saved it. So if I, e.g., have a editor open with the courser blinking at a certain spot, bang: It's blinking right there. And this is portable across all systems: I saved on a mac, you load on Linux. Write once, run everywhere (but with Squeak, this really works! Not write once, debug everywhere like with that other system).

So, I saved the demo image in a way that you can start to look at the slides right now: When the window opens, it's around 1024x768 large, and shows a friendly mouse in the middle.

Navigating the Slides

At the lower right corner you see a thing called "Thread Navigator". This handy Object allows for easy navigation in the slides of the talk. Just click on the arrow, and the next slide appears. The Tread Navigator object will follow to the next slide. (It will really travel with you: It deletes itself from the old slide and hops over. So make sure not to loose him).

Each slide is a Squeak Project. These projects are a bit like virtual desktops, but they can be saved to disk or send over the net.

You can make graphical links to projects, clicking on those will make the linked project active. To go back were you came from, you need to click on the background: A Menu appears, with items for going back and lots of other entries, e.g. for opening tools.

5 Squeak -What's that? Good Question. And not simple to answer. With most other Open Source projects that question is trivial: Mono, that's a free version of .Net. Gimp is a free Photoshop. But for Squeak, there is just nothing that is like it.

Squeak has features from a lot of different domains and well known programs. e.g. it has lots of features for media authoring, it is a programming language, it is a kid's programming system, it's (in a sense) it's on Operating System, it's a development environment... So let's go to the slide "What is Squeak", (should be the fourth). There you'l find links to projects for each of these aspects. Follow them, play around. Keep in mind that these slides are all "living". You may be used to the fact that a slide is all pictures, but in Squeak, that's not true.

The examples are all live. In the "Development" project, the Class Browser is showing the system that you are interacting with. Same with the "Inspector", the grey smaller window. It shows the inside of the Object that is the background, and from that especially the list of all other graphical objects that are in the slide.

So if you click on the background, the menu will appear and the Inspector will be updated.

Play a bit, we will revisit some topics later.

Squeak -The History

The History of the Squeak Project is nothing but Amazing (with capital A!), When I stumbled across Squeak, I knew nothing about the people involved, and somehow I was expecting that it would be some student somewhere (or something like that, like it was with Linux). But then I realised that those guys were a bit older. And bolder: I read on the Squeak.org website (it's even there today):

Our number one commitment is to an exquisite personal computing environment. Imagine a system as immediate and tactile as a sketch pad, in which you can effortlessly mingle writing, drawing, painting, and all of the structured leverage of computer science. Moverover imagine that every aspect of that system is described in itself and equally amenable to examination and composition. Perhaps this system also extends out over the Internet, including and leveraging off the work of others. You get the -it's the Holy Grail of computer science.

Who can write something like that? Seriously! Holy Grail. Sure So let's see.... The hero of our story is named Alan, the time is somewhere at the end of the sixties. Great time for being a computer science researcher, as the US military just pumped huge amounts of cash into basic computer research with the ARPA program. Lots of cool stuff was invented in that time, e.g. packet switching networks (ArpaNet), and Alan got to see some cool stuff: The first prototype of a flat panel display, one of the first handwriting recognizers and the drawing program SketchPad (according to some the most important program ever written). Papert's LOGO programing language for kids. And Moores Law.

So, he got an idea. A crazy one: Why not build a computer that is small enough to be carried around. It should have the size of a notebook, be around 2 pounds. It should have a graphical display, have enough memory to store a couple of books (It even could have a harddisc. A small one). A true "Personal Computer". Build for Kids. Codename: Dynabook.

Today, this sounds a bit obvious, but back then, it was completely crazy. The best way to predict the future is to invent it.

But the technical aspect is not the only interesting one: The idea was to build a computer for kids in the way that it would be a new kind of medium. For fun and learning. Not a word-processor, but an idea processor.

So the goal was to make this crazy dream a reality. Moores law gave the deadline: A sufficiently fast computer would fit, according to Moores law, inside the required space in 1980. So Alan started to think about the Software, at Xerox PARC.

The Operating System, GUI and development environment for the Dynabook was called Smalltalk. It was the first fully Object Oriented System, and the first GUI with real, overlapping windows. The famous story is that Steve Jobs did get a demo of that system.... And Squeak is that Smalltalk System from the seventies, dusted off. And those strange Squeakers are the inventors of Smalltalk, Alan Kay of course, and Dan Ingalls and Ted Kaehler, both from the original Xerox PARC team.

Squeak was started in 1996, while the Squeak Team was at Apple. They moved on to Disney from there, and today, Alan is at HP Labs.

Squeak for Kids

So, now go forward some slides to the Squeak for Kids project.

There is a good tutorial on the Squeakland website about how to build a car yourself: http://squeakland.org/school/drive_a_car/html/Drivecar12.html

The Lunar Lander is an example of how far you can go with eToys: This was not done by a child, but with some guidance older kids could build such a game (and learn a lot).

There are a some other examples for eToy projects in the third (the right) project.

8 Squeak for Professional Development eToy is great for kids (and even for adults to learn programming). But the real hacker needs something that is a bit different. Squeak is completely written in itself, and for making that easy, it provides a object oriented programming language and a development environment.

The IDE provides a class browser for easy coding and a really good debugger. (with edit-and-continue, something that is starting to get a hot topic for both Java and .Net).

Squeak is actually used both in research and in industry to do real stuff. This is no toy! (Even if it looks like one).

The Language

The language of Squeak is really simple. But it's a bit different then the other ones you might know. The slide has all the syntax of the language. That's it. In the slide, you can execute and print a statement by selecting it and pressing Alt-p or Apple-p on the Mac.

The basic idea is that everything is an object, and you can make object do something by sending a message to them. What an object does when receiving a message is described in a method. The method is defined in the class of the object.

So if you write:

1 sin then you have an object (the number 1) and you send a message (sin). The object 1 is of class SmallInteger, and in SmallInteger there is a method sin.

A real smalltalk introduction is outside of the scope of this paper, see http://www.iam.unibe.ch/~ducasse/FreeBooks.html for some books.

And there is a good introduction slide-show in the current 3.7 or 3.8 Squeak release images.

Seaside

Seaside is quite interesting. Avi Bryant was using Ruby for doing web development. Then he met some Squeakers at OOPSLA (the OO Conference). And so he jumped ship from Ruby to Squeak and invented Seaside.

Seaside is very interesting, as it solves the problems that any web developer faces in novel ways. The target for Seaside are web applications, that is fairly complicated interactive websites (e.g. the typical banking site), not static pages.

Seaside allows the programmer to write the web application just the way she would write a normal GUI application. Let's see what Avi writes:

Seaside is a framework for developing sophisticated web applications in Smalltalk.

Its most unique feature is its approach to session management: unlike servlet models which require a separate handler for each page or request, Seaside models an entire user session as a continuous piece of code, with natural, linear control flow -pages can call and return to each other like subroutines, complex sequences of forms can be managed from a single method, objects are passed by reference rather than marshalled into URLs or hidden fields -while fully supporting the backtracking and parallelism inherent to the web browser.

Seaside also features a callback-based event model, a "transaction" system for auto-expiring pages, strictly compliant XHTML generation, a system of reusable and embeddable UI components, and handy web-based development tools.

The Squeak image that drives the slides has a complete seaside installation. Yes, everything is there. Just point your browser to http://localhost:9090/seaside/presentation for a Seaside demo written in Seaside.

The Counter/MultiCounter are here: http://localhost:9090/seaside/counter http://localhost:9090/seaside/multi And a small shop example: http://localhost:9090/seaside/store A short article about seaside: http://homepage.mac.com/svc/ADayAtTheBeach/ It ends with:

We 'discovered' Seaside only recently. After just one day of experimenting with it we were convinced about the dramatic improvement in abstraction and productivity it offers. We were absolutely amazed at how easy it was to do the examples described here: much, much easier than it would be in any other framework that we know of. We believe Seaside could be a killer application for (Squeak) Smalltalk.

Seaside is cool, yes. But we can do even better. Enter Croquet.

Open Croquet

So. Now to the really interesting "latest and greatest" in Squeak. As with Squeak itself, we need a good quote from the developers. Or better two: WHAT IF... ...we were to create a new operating system and user interface knowing what we know today, how far could we go? What kinds of decisions would we make that we might have been unable to even consider 20 or 30 years ago, when the current set of operating systems were first created? ...we could collaborate with one another in an online dimension to create or simulate anything we wanted to? ...we had the robustness of a 3D immersive technology, the diversity of the Internet, and the degree of social interaction we have in the real world?

The second quote:

Existing operating systems are like the castles that were owned by their respective Lords in the Middle Ages. They were the centers of power, a way to control the population and threaten the competition. Sometimes, a particular Lord would become overpowering, and he would declare himself as King. This was great for the King. And not too bad for the rest of the nobles, but in the end -technology progressed and people started blowing holes in the sides of the castles. The castles were eventually abandoned -David A. Smith Croquet is work-in-progress. But there is a pre-release available for download. If you have a fast computer with a good 3D graphics card, give it a try.

http://squeak.org http://squeakland.org http://squeakersfilm.org http://croquetproject.org


Marcus Denker

Orla Greevy

Michele Lanza

Higher Abstractions for Dynamic Analysis

Keywords: Dynamic Analysis, Behavioral Reflection, Meta Programming, Tracing

The developers of tools for dynamic analysis are faced with choosing from the many approaches to gathering runtime data. Typically, dynamic analysis involves instrumenting the program under investigation to record its runtime behavior. Current approaches for byte-code based systems like Java and Smalltalk rely often on inserting byte-code into the program under analysis. However, detailed knowledge of the target programming language or virtual machine is required to implement dynamic analysis tools. Obtaining and exploiting this knowledge to build better analysis tools is cumbersome and often distracts the tool builder from the actual goal, which is the analysis of the runtime behavior of a system.

In this paper, we argue that we need to adopt a higher level view of a software system when considering the task of abstracting runtime information. We focus on objectoriented virtual machine based languages. We want to be able to deal with the runtime system as a collection of reified first-class entities. We propose to achieve this by introducing a layer of abstraction, i.e., a behavioral middle layer. This has the advantage that the task of collecting dynamic information is not concerned with low level details of a specific language or virtual machine. The positive effect of such a behavioral middle layer is twofold: on the one hand it provides us with a standard API for all dynamic analysis based tools to use, on the other hand it allows the tool developer to abstract from the actual implementation technique.

INTRODUCTION

In recent years there has been a revival of interest in dynamic analysis [START_REF] Hamou-Lhadj | The concept of trace summarization[END_REF]. System analysis of runtime behavior is vital for performance analysis to detect hotspots of activity and bottlenecks of execution or memory allocation problems such as unnecessary object retention. In a reverse engineering context, dynamic analysis is used is to extract high-level views about the behavior of low-level components to facilitate the comprehension of the system [START_REF] Greevy | Correlating features and code using a compact two-sided trace analysis approach[END_REF][START_REF] Hamou-Lhadj | A survey of trace exploration tools and techniques[END_REF][START_REF] Zaidman | Managing trace data volume through a heuristical clustering process based on event execution frequency[END_REF]. The focus of analysis determines the relevance and level of detail of the information captured during dynamic analysis. In the field of reverse engineering, there is no consensus on the type or level of granularity of runtime information that is necessary for a particular analysis. An inherent requirement of such tools is that they be easily extensible as the requirements and the research focus evolves.

Dynamic analysis yields precise information about the runtime behavior of systems [START_REF] Ball | The concept of dynamic analysis[END_REF]. However, the task of writing tools to abstract runtime data is not trivial. Developers of tools are faced with many options as there are numerous techniques that address the task of collecting runtime data. The approach to tool development and the abstraction of dynamic data is therefore not standardized. Each individual tool adopts a specific technique and focuses on low-level details of the chosen technique to achieve its goals.

This leads to recurrent problems of all approaches and techniques:

• all clients need to re-implement large parts of the code responsible for gathering the runtime data, and

• the abstraction level is too low in the sense that clients need to know too much about the implementation side.

In this paper we propose the introduction of an abstraction layer based on behavioral reflection to facilitate the design and development of tools for dynamic analysis. We introduce our reflection framework and identify its strengths and shortcomings.

Structure of the paper. In the next section we identify some typical applications of dynamic analysis. In this context we outline the state of the art in gathering dynamic data at runtime. Section 3 then shows problems and shortcomings associated with the current approaches. In Section 4 we give an overview of reflection frameworks. In Section 5 we introduce our reflection framework and identify how it can be used to solve the problems shown, and we identify what is missing from our implementation with the intention of initiating a discussion and obtaining feedback. Section 7 outlines our conclusions and future work.

DYNAMIC ANALYSIS TECHNIQUES

Dynamic analysis typically involves instrumenting the program under investigation to examine or record certain aspects of its runtime behavior. Code instrumentation is a mechanism that allows insertion of code at runtime to monitor and track the runtime behavior of a system. In this section we review the techniques currently available for abstracting the runtime behavior of a system. The underlying concepts behind dynamic analysis tools are currently limited to using these techniques for extracting dynamic information [START_REF] Hamou-Lhadj | A survey of trace exploration tools and techniques[END_REF].

The granularity and amount of behavioral data extracted during the execution of a system varies depending on the specific focus of a particular analysis tool. Dynamic analysis implies vast amounts of data. A simple execution of a system's functionality can result in a large number of events [START_REF] Ducasse | High-level polymetric views of condensed run-time information[END_REF]. Typically, dynamic analysis tools employ filtering and compression techniques to limit the amount of dynamic data collected depending on a specific focus of the analysis. For example, if the goal of the analysis is feature location [START_REF] Eisenbarth | Locating features in source code[END_REF], this requires that a relationship between the external functionalities of a system and the parts of the code that implement this functionality is established. Therefore, it is usually sufficient to extract trace events representing the method calls performed during the execution of a specific functionality [START_REF] Antoniol | Feature identification: a novel approach and a case study[END_REF][START_REF] Greevy | Correlating features and code using a compact two-sided trace analysis approach[END_REF]. An example of trace representation is given by Richner and Ducasse [START_REF] Richner | Using dynamic information for the iterative recovery of collaborations and roles[END_REF]. Each line records the class of the sender, the identity of the sender, the class of the receiver, the identity of the receiver and the method invoked. The order of the calls is maintained.

Analysis techniques that focus on monitoring the state of objects at runtime require a more detailed analysis to extract information about variable access. This level of granularity is required if the focus of the analysis is to infer program invariants [START_REF] Michael | Dynamically discovering likely program invariants to support program evolution[END_REF]. Performance analysis tools generally focus on object creation and deletion and the correct memory allocation details. Thus the requirements of dynamic analysis tools vary depending on their specific focus. This is a drawback, because the analysis goals should not restrict the type of information to be collected. We want to extract as much dynamic data as possible and then depending on the requirements of a particular analysis, extract and use a appropriate subset of the dynamic data.

There are various approaches and language-specific frameworks that support the extraction of dynamic information. We describe the details of the underlying mechanisms used by dynamic analysis tools in the following paragraphs.

Source code modification. One way to control message passing is to instrument the code via source code modification and recompilation. The main drawback of this technique is that all controlled methods have to be reparsed and recompiled. Furthermore, another recompilation is needed to reinstall the original methods.

Bytecode modification. Another way to control message passing is to directly insert byte-code into the byte-code of the compiled methods. The introduced byte-code controls the message passing. However, this technique relies heavily on profound knowledge of the bytecode instructions used by the virtual machines.

Another potential danger of this technique is that these codes are not standardized and can change.

Instrumenting the Virtual Machine.

A technique for collecting runtime information is instrumenting the runtime environment in which the system runs. For example, the Java Virtual Machine can be instrumented to generate events of interest. The advantage of this technique is that it does not require modification of the source code.

The Java Virtual Machine Profiling interface (JVMPI) [START_REF]profiler interface (jvmpi)[END_REF] provides a set of hooks to the JVM to signal interesting events, such as thread starts or object allocations. JVMTI [START_REF]Sun microsystems, inc. jvm tool interface (jvmti)[END_REF] is the sucessor to JVMPI and provides both a way to inspect the state and to control the execution of applications running in the Java virtual machine. It provides additional facilities for bytecode instrumentation. Profilers based on JVMPI or JVMTI interfaces implement profiling agents to intercept various events, such as method invocations. Unfortunately these profiling agents have to be written in platform native code, contradicting the Java motto of "write once run anywhere". Binder developed Komorium, a novel sampling profiler written purely in Java that directly instruments the bytecode of Java programs [START_REF] Binder | A portable and customizable profiling framework for Java based on bytecode instruction counting[END_REF]. Another pure Java solution is the Java Interactive Profiler (JIP) is based on JVMTI and provides control to turn on and off profiling at runtime (see http://jiprof.sourceforge.net/).

Method Wrappers. Brant et al, describe a code in-

strumenting technique for Smalltalk based on method wrappers [START_REF] Brant | Wrappers to the rescue[END_REF]. Wrappers are mechanisms for introducing new behavior that is executed before and/or after, and perhaps instead of, an existing method. Rather than changing method lookup, they modify the method objects that the processes return. Wrappers are easy to build for Smalltalk as it was designed with reflective facilities that allow programmers to intervene in the lookup process, while the same is not true for Java which only supports introspection.

Debuggers. It is possible to run a system under the control of the debugger. In this case, breakpoints are set at locations of interest (e.g., entry and exit of a method). This technique has the advantage of not modifiying the source code and the environment. However it slows down the execution of a system considerably, and the instrumentation itself can be cumbersome. This can be done on the source level before compilations, or on bytecode at load time (Java) or runtime (Smalltalk). The abstraction layers we deal with are either those of the program text or those of bytecode.

Logging Services. Logging can be used to track the state of a running system at various points in time. A good framework for doing this with Java is provided by log4j (see http://logging.apache.org/). The drawback is again that this implies modifying the source code.

CHALLENGES

As we have seen, there are multiple implementation techniques for gathering runtime data. The key problem is that every new client application has to re-implement large parts of the runtime data gathering code depending on the language and runtime environment. Furthermore, the abstraction is too low level, resulting in clients that are concerned with manipulating too many implementation details.

In the following sections we elaborate on the main problems of the current approaches.

Instrumentation re-implemented

Most projects that require to access runtime data typically re-implement the data gathering mechanism. Instrumenta-tion code is inserted at all places of interest in the code (e.g., at message sends). In the case of bytecode manipulation techniques, the actual modification of the bytecode is achieved using libraries (e.g., Javassist [START_REF] Chiba | Load-time structural reflection in Java[END_REF][START_REF] Chiba | An easy-to-use toolkit for efficient Java bytecode translators[END_REF] or Bytesurgeon [START_REF] Denker | Runtime bytecode transformation for Smalltalk[END_REF]). Bytecode manipulation provides a very low level of abstraction and requires detailed knowledge of the bytecode of the programming language. Moreover, it is prone to language evolution, i.e., the specification of the VM may change.

The positive effect of the low level approach is of course that we build a very specific implementation, tailored exactly towards the information needed for a specific task. The drawback is that the instrumentation logic is tightly coupled with the application that requires the dynamic data, thus in most cases we will have to re-implement the instrumentation logic for each new task. Figure 1 shows an example: We have two projects that are interested in gathering runtime data (Tracer1 and Tracer2). Although both run on a standard virtual machine, both independently implement the code for bytecode instrumentation. We have seen this happen often in our research, for example both the trace debugger Unstuck [START_REF] Hofer | Design and implementation of a backward-in-time debugger[END_REF] and a test coverage tool both utilized the same byte-code manipulation library (ByteSurgeon), but they did not share any instrumentation code.

Implementation Specific Designs

Implementors of tools that gather runtime data are faced with the decision on which implementation technique to adopt. Subsequently, they design a tool based on specific knowledge of the target language and runtime environment. The resulting tool inevitably is forced to encode implementation issues into the design of the tool. Thus, the result is a tool that is tightly coupled with a particular runtime environment.

This approach has obvious drawbacks. It is very difficult to change the adopted implementation technique: e.g., bytecode manipulation is portable, but a specialized virtual machine might be faster. When the implementation technique is closely tied to a particular virtual machine, we are bound to this one implementation, we cannot switch to a byte-code based implementation on a case-to-case basis. Figure 1 shows that for a special virtual machine, we need to re-implement our system.

BEHAVIORAL REFLECTION

Systems like Smalltalk and CLOS model their own structures (classes, methods) as first class objects.

The term introspection defines the ability to query the system about this information, whereas we talk about intercession when changes to these structures directly change the structure of the system itself. Systems that provide both are called reflective.

Structural reflection is concerned with reification of the program and its abstract types. Behavioral reflection, on the other hand, is concerned with the ability of the language to provide complete reification of its own semantics and implementation as well as complete reification of the data and implementation of the runtime system.

Popular object oriented languages provide different degrees of introspection or reflective capabilities. Smalltalk is, to some extent, a reflective system [START_REF] Foote | Reflective facilities in Smalltalk-80[END_REF][START_REF] Bergel | Prototyping languages, related constructs and tools with Squeak[END_REF]: Classes and methods are objects, we can change those objects to change the structure of the system. Java and .NET on the other hand, have only introspective features (i.e., allows for querying an object for its class, a class for its methods and constructors, query the details of those methods and constructors, and tell those methods to execute), and partial intercession (intercession is limited to method invocation and attribute manipulation) [START_REF] Cazzola | Smartreflection: Efficient introspection in java[END_REF].

Languages that facilitate the description of methods as first class objects inherently support dynamic analysis. The method wrappers technique exploits the first class nature of methods in Smalltalk for providing a way to intercept method execution [START_REF] Brant | Wrappers to the rescue[END_REF]. Examples of dynamic analysis tools built on the method wrapper technique are Greevy and Ducasse's TraceScraper tool for feature analysis [START_REF] Greevy | Correlating features and code using a compact two-sided trace analysis approach[END_REF] and John Brant's Interaction Diagram and Coverage Tools [START_REF] Brant | Wrappers to the rescue[END_REF]. However method execution is just an aspect of runtime information. For a complete dynamic analysis we need to focus on other runtime events such as e.g., message sends between object instances or instance variable access. Thus, we recognize the need to define a reflective meta representation that describes all behavioral aspects of systems. We want a system that can reify those events on demand, providing a system with full behavioral reflection.

In both Java and Smalltalk, the reflection mechanisms provided are concerned mostly with structure. They do not provide an easy way to change the semantics of the runtime model: Message sends, instance variable access are not modeled with objects. A true behavioral reflective system models behavior in a way that it is first class and changes are possible: e.g., we are able to define our own version of what a message send is.

Looking back into the history of object oriented systems, we can find that there has been extensive research on behavioral reflective systems, e.g., the work done around Meta Object Protocols [START_REF] Kiczales | The Art of the Metaobject Protocol[END_REF] for CLOS. The meta object protocol provides all operations (e.g., method activation or variable access) to be reified and re-defined.

In systems like Java and Smalltalk, behavioral reflection can be realised via special virtual machines or bytecode manipulation, with the latter being portable. Examples for the virtual machine approach are Iguana/J [START_REF] Redmond | Supporting unanticipated dynamic adaptation of application behaviour[END_REF], Metaxa [START_REF] Golm | Jumping to the meta level: Behavioral reflection can be fast and flexible[END_REF], or Guarana [START_REF] Olivia | The design and implementation of Guaraná[END_REF]. The prime example for a bytecode modification based meta object protocol is Reflex [START_REF] Tanter | Partial behavioral reflection: Spatial and temporal selection of reification[END_REF]. Reflex provides a model for behavioral reflection that allows for a very fine grained selection of when and what to reify.

THE BEHAVIORAL FRAMEWORK

The drawbacks we have identified with current approaches lead us to suggest that the solution would be to introduce an additional layer of abstraction to our system, which we refer to as a behavioral framework.

We now analyze how a behavioral reflection framework could be used to tackle and solve the problems of previous approaches to gathering runtime information.

A Shared API

With the existence of a behavioral layer, all tools could use it to hook into runtime events. The individual tools are no longer concerned with a specific code insertion implementation. Instead, they just leverage the abstractions provided by the behavioral layer framework.

In Figure 2 we see again our two tools that are interested in dynamic information. Now both tools just use the behavioral layer, thus they do not need to implement the byte-code modification code themselves, but share it.

A Pluggable Implementation

Another important requirement of an abstraction layer is to provide a high degree of flexibility, but at the same time retain the same interface for clients. The proposed behavioral framework should make it possible to have a pluggable implementation (the backend): it can be realized via editing byte-code, a changed virtual machine or other means.

Figure 2 shows how we now can use both programs on the modified virtual machine, without having to implement the logic ourselves: All tools using the abstraction layer will work on both the standard virtual machine and any specialized virtual machine that the abstraction layer supports.

Requirements

In the following we identify a list of requirements for a behavioral framework to tackle the challenges we identified previously.

Runtime installation:

We need to introduce behavior dynamically at runtime. When we are done with the analysis, it should be possible to revert to the original state of the system.

Unanticipated use:

The behavioral change should be possible at any time in the deployed system, without the need to prepare the system in any way at startup.

Fine-Grained Selection:

The operation occurrences we are interested in are different depending on what we analyze. We want to be able to select the entities up to the level of the single occurrence in the code.

Implementation Hiding: From a dynamic analysis perspective, we are not interested in the underlying mechanisms of obtaining runtime information. The fundamental goal of a behavioral layer is to allow us to abstract from the details of a specific implementation technique (e.g., VM change, byte-code extension, bytecode modification) used to extract behavioral information from an application at runtime.

Performance: To make the framework usable for analyzing real work applications, we need a framework with low overhead. The best case would be a system where we pay exactly the same overhead as if we were to annotate the code with profiling calls by hand.

Implementation

We have realized a framework for partial behavioral reflection for Squeak (a dialect of Smalltalk) called Geppetto [START_REF] Röthlisberger | Unanticipated partial behavioral reflection[END_REF]. Geppetto uses the runtime byte-code transformation framework ByteSurgeon [START_REF] Denker | Runtime bytecode transformation for Smalltalk[END_REF] and follows the model of partial behavioral reflection as pioneered by Reflex [START_REF] Tanter | Partial behavioral reflection: Spatial and temporal selection of reification[END_REF]. Unlike Reflex, which is constrained by the underlying model of the Java language, our Geppetto implementation can be used completely unanticipated: code does not need to be prepared at load or compile time, reflection can be enabled at runtime and completely retracted when not needed.

Geppetto allows for reifying message sending, method execution and variable access (read and write) for both instance variables and temporary variables. Selection is very finegrained: per package, class, object, method, operation and operation occurrence. Geppetto can be used in any Squeak program, without the need to adapt it at load or start time. Installation happens transparently at runtime.

Geppetto uses ByteSurgeon to insert small peaces of code, so called hooks into the bytecode where a selected operation (e.g. message send) occurs. Figure 3 shows the model in detail. Hooks are grouped to hooksets, which are bound to a metaobject by a link. The link defines the protocol between the base and the meta layer. Links can be enabled or disabled based on an activation condition. For a complete description of the Gepetto behavioral reflection framework, see [START_REF] Röthlisberger | Unanticipated partial behavioral reflection[END_REF].

Usage

The behavioral reflection framework provides a general API: the reification of runtime events triggers calls to meta objects, which are instances of normal classes. The tool developer thus is free to use the framework as needed by specifying which concepts to reify and which information to pass on to the meta object. The framework does not provide a model of the data obtained (e.g., a trace), instead it provides a model for obtaining data. It can be either stored for later use as a trace or processed and reacted on at runtime. The latter has lately become an active topic of research with systems like PQL [START_REF] Martin | Finding application errors and security flaws using pql: a program query language[END_REF].

DISCUSSION

We now analyze our behavioral framework with respect to the requirements defined in the preceding section and define future work. Then we briefly discuss the relationship to aspect oriented programming and the usefulness of providing scoping abstractions as part of the framework.

Next Steps

The implementation as described in section 5.4, already fulfills some of the requirements stated: It can install (and retract) behavioral changes at runtime, provides fine-grained spatial and temporal selection by implementing the Reflex model [START_REF] Tanter | Partial behavioral reflection: Spatial and temporal selection of reification[END_REF] and supports unanticipated use.

Two requirements are not yet fulfilled:

1. Geppetto needs to be extended to support pluggable backends. We are working on providing a backend based on annotated abstract syntax trees.

2. We need to verify the real world usability: first benchmarks show good performance characteristics, but Geppetto needs to be validated with real world usage. We plan to move the tools and experiments done that currently use ByteSurgeon to use Geppetto instead.

Aspects

This paper presents the solution from the perspective of behavioral reflection. Another point of view can be that of Aspect Oriented Programming. The proposed abstraction layer could use, as a backend, an existing dynamic aspects implementation. In this case, the aspect framework would be used as a high-level replacement for byte-code manipulation.

Another possibility would be to formulate the middle layer in terms of a dynamic aspect framework instead of meta objects. The problem here is that most aspect systems (e.g., AspectJ [START_REF] Kiczales | An overview of AspectJ[END_REF]) are static: weaving happens at compile or load time. Pure runtime Aspects are not yet very common and those that exist are based themselves in some cases on behavioral reflection facilities, for example AspectS [START_REF] Hirschfeld | AspectS -aspect-oriented programming with Squeak[END_REF] and aspect systems based on Reflex [START_REF] Tanter | A versatile kernel for multi-language AOP[END_REF].

Scope Abstractions

Modern implementations like Reflex provide very finegrained spatial and temporal selection of reification. Here we can select what and where, in a temporal and spacial way.

This means we can scope the reification towards collections of classes (like modules and packages) or single instances, a single methods of a class, or even to one certain occurrence of a behavioral event. Temporal selection means that we can switch reifications on and off at will, thus we can make the gathering of runtime data be controlled by runtime events.

Another idea of scoping is that of scoping-towards-theclient: We might be interested in events generated only if our package under test is called from a certain other package. This can be useful to limit the amount of unnecessary data when e.g., analysing system classes like Smalltalks collections.

CONCLUSION

In this paper we addressed a fundamental problem that faces the developers of tools that exploit runtime information of an application. We propose an new approach to designing dynamic analysis tools for virtual machine based languages that interact with a layer of abstraction, namely a behavioral layer. The behavioral layer should provide a framework for tool developers that encapsulate typical object oriented language constructs at runtime such as object instantiation, message sends and instance variable access. Thus the developer has access to reified first class entities of runtime behavior and focuses on these high level abstractions when designing a specific tool. The main advantage of this layer of abstraction is that the resulting tool should easily portable to use with other virtual machines as the reified entities are independent of the underlying implementation details and byte-codes. Moreover the developer is not concerned with low level details that are specific to a particular virtual machine.

In this paper we provided a short overview of the available technologies and approaches to extract runtime data. We identified problems inherent to these approaches. This motivates our argument that there is a need to introduce a layer of abstraction between low level implementation details and the tools analysing the data.

To better understand the underlying motivation of a behavioral layer we provided a short overview of some of the applications of dynamic analysis. In the field of program comprehension and reverse engineering dynamic analysis approaches are becoming more prevalent. However there is no standard approach to extracting runtime data nor is it clear which type of runtime information to extract. Therefore such tools need to be extensible, as requirements change.

We identified a list of requirements for a behavioral layer. We describe our current implementation of a behavioral layer and illustrate how it can be used to address the problems. We show how we simplify the task of implementing dynamic analysis tools.

Figure 1 :

 1 Figure 1: Trace tool today

Figure 2 :

 2 Figure 2: A common abstraction layer

Figure 3 :

 3 Figure 3: Hooksets, Links and Metaobjects in Geppetto

Acknowledgments. We gratefully acknowledge the financial support of the Swiss National Science Foundation for the projects "Analyzing, capturing and taming software change" (SNF Project No. 200020-113342, Oct. 2006 -Sept. 2008)) and "NOREX -Network of Reengineering Expertise" (SNF SCOPES Project No. IB7320-110997).


Oscar Nierstrasz

Marcus Denker

Supporting Software Change in the Programming Language *

Keywords: sofware evolution, languages, traits, classboxes

Introduction

Software changes.

Software systems are constantly modified and extended. Versions are split and sometimes merged. Software is refactored and occasionally reengineered.

Programming languages, however, provide little support for software change. Pretty well every mainstream language (and the exotic ones too) adopt the viewpoint that a program specifies a single, consistent viewpoint of a software system. The fact that this system will change over time is not, and cannot be a part of this specification. Furthermore, support for dynamic change is typically limited to idioms and design patterns that encode run time flexibility, rather than by representing it directly in the program specification.

We are by now used to the response; "that's not a language issue." Indeed, this response has considerable merit -it is much easier to reason about programs and about the semantics of the programming language itself if we assume a consistent world-view for any given program, and defer issues of program change to the meta-level of programming tools and environments that manipulate these programs.

But let us suspend our disbelief for a moment and ask ourselves, What would a programming language look like that offered support for software change?

In this paper we briefly review various kinds of software changes and the issues that arise from them. As a consequence, we propose research into programming languages with explicit support for representing first-class changes, and for manipulating and merging multiple viewpoints of evolving software systems.

Kinds of Changes

Software systems undergo different forms of change. These range from routine, day-to-day changes, to more radical kinds of change. Let us briefly survey the broad categories of change and the kinds of problems they pose for programmers [START_REF] Lientz | Software Maintenance Management[END_REF][START_REF] Demeyer | Object-Oriented Reengineering Patterns[END_REF].

• Bug fixes: Even mundane bugs pose the problem -"Will fixing this bug cause something else to break?" Programming languages do not help programmers keep track of implicit dependencies (which is why they are implicit in the first place). More deep-seated bugs may be hard to fix because they are a sign of architectural problems. Fixing them either entails a "hack" -which leads to further maintenance problems -or entails reengineering towards a better architecture.

• New features: Many changes concern user requests for new features. The difficult features to add are those that cross-cut components of the existing system, impacting the entire architecture.

• Split and adapt: Entire applications or portions thereof are often cloned and adapted to meet the needs of new clients. Although this can be an effective way to deliver results quickly, the code base quickly gets out of hand, leading to maintenance difficulties. Programming languages do not really help to keep track of the relationships between separate projects. Attempts to factor out libraries and frameworks of common components can be frustrated by large numbers of minor differences between the various applications.

• Merge and integrate: New features developed for one client may need to be merged and integrated into applications for other clients. This is inverse to Split and Adapt: after splitting, the system needs to be integrated back into a consistent body of code.

• Refactoring: In an ideal world, bad code smells are routinely eliminated through refactoring steps [FBB + 99]. As with routine bug fixes, how do we know that refactorings will not break other parts of the system? Unit testing is a well-established practice to help solve this problem, but programming languages do not offer much help for maintaining code and the corresponding tests. Many tools exist, but perhaps more could be offered at the language level?

• Reengineering: Here we are concerned with much more radical reworkings of applications, due to architectural drift, or radically new kinds of requirements [START_REF] Demeyer | Object-Oriented Reengineering Patterns[END_REF]. Reengineering entails many smaller kinds of refactoring steps, and may intail porting to new environments or migration to a new architecture. Here too, programming languages offer little in the way of managing the correspondence between the old and the new system.

Clearly there is quite a range of issues from the very low-level to the high-level.

• Implicit architecture: One of the biggest hurdles in most programming languages, and especially in object-oriented languages, is that the run-time architecture is not apparent from the source code. This makes many kinds of changes difficult to understand, assess and realize.

• Implicit dependencies: A slightly different point is that dependencies in general may be hard to identify, understand and assess, for example, because many kinds of dependencies are built up at run-time, and are therefore not apparent in the source code. Not all dependencies are at an architectural level, but any kind of dependency can introduce fragility in the face of change. files which have no connection to the entities that are described.

• Multiple viewpoints: Many kinds of change reflect shifting viewpoints of the code. "Glue code" is a symptom of inconsistent viewpoints colliding. Difficulties in realizing certain kinds of change (such "merge and integrate", or porting to a new platform) have to do with reconciling these different viewpoints.

• Third party software changes: An additional level of difficulty is introduced by changes to software developed by a third party. Changes between versions can affect client code in unexpected ways, when interfaces or contracts are changed or deprecated.

• Sealed components: Worse, it may be impossible to make changes to third party software. When it is possible, we may have difficulty propagating these changes back to the supplier. Alternatively, we may have the additional burden of propagating our changes to future versions of the software.

• Crosscutting: Implementing a single new feature or fixing one specific bug often leads to changes that are spread amongst different parts of the program. So all these changes are connected, yet there is no way to record or encode this connection in the program.

• Component granularity and shape: When we identify reusable abstractions, we may be frustrated from realizing the needed component in code due to the lack of suitable abstraction mechanisms. Reusable synchronization policies are a well-known example of an abstraction difficult or impossible to implement in mainstream languages [START_REF] Achermann | Language support for feature mixing[END_REF].

3 Programming Language Support for Change

Existing programming languages offer only limited support for change. Let us briefly review the state of the art.

• Modularity: Pretty well every mainstream language offers some mechanism for packaging modules [START_REF] David | A technique for software module specification with examples[END_REF], however modules tend to have second-class status.

• Namespaces: Increasingly we are seeing explicit namespaces being added to mainstream languages like C++, but namespaces are also typically second-class. Piccola is an experimental language with first-class namespaces [START_REF] Achermann | Explicit Namespaces[END_REF].

• Explicit architecture: Some recent languages support the specification of explicit component models [AN01, ACN02, MFH01, Zen02].

• Aspects provide a way to describe and change crosscutting concerns [KLM + 97].

• Classboxes offer a packaging mechanism for class extensions with local rebinding, which means that extensions are only visible to the parts of an application that directly or indirectly import those extensions [START_REF] Bergel | Classboxes: Controlling visibility of class extensions[END_REF].

• Traits [START_REF] Schärli | A browser for incremental programming[END_REF] provide composable units of behavior. Common behaviors can be factored into traits and then be used by multiple classes. So traits (like mixins) provide an abstraction that is larger than a method and smaller than a class.

• OLE versioning: Microsoft's OLE provides versioned interfaces to components. By using this, the programmer can specify if the interface will stay compatible after a change. This provides a first step into making change explicit, but the OLE versionen components are not integrated into a programing language (e.g. the language can't provide real type-checking based on version information).

• Perspectives and Layers in PIE: The PIE System [START_REF] Goldstein | A layered approach to software design[END_REF] was an experiment to merge the features found in frame-based knowlede representation languages with Smalltalk. The system provided a new object-model based on objects with multiple views. PIE was described using itself and thus provided a language that treats its code as objects with multiple views. Single views of objects are combined into layers, which describe one version of the code. PIE provided the programmer with a way of having multiple concurrent versions of the system available and enabled merging these versions. PIE did not allow two layers describing different versions of a system to be active at the same time.

Research Directions

We propose to develop a programming language which facilitates experimentation with features to support software change. Since the language should facilitate evolution, it should also support its own evolution. For such a language it is important that parts of the existing system (both language and tools) can be used and adapted for building the new language. We are building a prototype (based on Squeak [IKM + 97]) that will enable multiple, different language kernels to be active at the same time. With this, we want to develop a minimal language kernel. Having such a pluggable kernel will enable experimentation that will allow us to understand what kind of mechanisms for supporting change of the language itself are needed.

Concretely, we plan to experiment with:

• Combining traits and classboxes -we can use classboxes to encapsulate sets of related traits.

• Leveraging traits and classboxes at the level of the language kernel.

• Providing versions and changes as first class objects.

• Providing viewpoint operators -viewpoints extend classboxes with run-time operations. Multiple, inconsistent viewpoints representing different change sets can be simultaneously active. By moving the boundary of a viewpoint, we can gradually extend the scope of changes to different parts of a running system.

• Making reflection pluggable. Start with a minimal non-reflective language kernel and then add reflection and a meta object protocol in a modular way.

• Leveraging this pluggable API for building the developer tools.

Acknowledgments

We gratefully acknowledge the financial support of the Swiss National Science Foundation for the project "Tools and Techniques for Decomposing and Composing Software" (SNF Project No. 2000-067855.02, Oct. 2002 -Sept. 2004).


Marcus Denker

Juni

Installing the LinuxTag Demo

The first thing we need to do is installing Squeak on your system. Squeak has been ported to nearly everything, from handhelds to mainframes, or even game systems like the PS2. Not all of the ports are kept alive for all releases, but for a common system like Linux, MacOS or that-which-shall-not-be-named there should be no problem.

So go to squeak-ev.org and download Squeak for your system and unpack. The files we will need for running the demo are:

• SqueakV3.sources: The source code. All in one big lump.

• Squeak.exe / Squeak.app / squeak: This is the virtual machine.

The distribution files will contain two other files: .changes and .image. To get the contents of the LinuxTag Squeak Demo, we need to get the special LinuxTag version of these two files. They are available at <http://www.squeak-ev.de/LinuxTag05>

After uncompressing the LinuxTag05.zip, you will find these two files:

• LinuxTag.image: all the Objects that make our demo, dumped into a file • LinuxTag.changes: additional source code Put these files in the directory with the other Squeak files, and you are ready to start.

Start Up

Now we need to start Squeak. For that, just open the image file with the help of the vm. For linux, that would be something like:

./squeak LinuxTag05.image MacOS/Win: drag-n-drop the image on the vm. Now the Squeak virtual machine will start and load the image back into memory. The image is really a image of the memory: Itquotes just a snapshot of the whole memory that the vm had allocated. It will start up exactly the way it was when I saved it.

So if I, e.g., have a editor open with the courser blinking at a certain spot, itquotes blinking right there. And this is portable across all systems: I saved on a mac, you load on Linux. Write once, run everywhere (but with Squeak, this really works! Not write once, debug everywhere like with that other system).

First slide of the demo I saved the demo image in a way that you can start to look at the slides right now: When the window opens, itquotes around 1024x768 large, and shows a friendly mouse in the middle.

Navigating the Slides

At the lower right corner you see a thing called Thread Navigator. This handy object allows for easy navigation in the slides of the talk. Just click on the arrow, and the next slide appears. The Thread Navigator object will follow to the next slide. (He will really travel with you: He deletes himself from the old slide and hops over. So make sure not to loose him!).

Each slide is a Squeak Project. These projects are a bit like virtual desktops, but they can be saved to disk or send over the net.

You can make graphical links to projects, clicking on those will make the linked project active. To go back were you came from, you need to click on the background: A menu appears, with items for going back and lots of other entries, e.g. for opening tools.

So, now we are ready to explore Squeak.

What is Squeak

This question sounds simpler to answer than it is: Most Open Source projects try to recreate existing systems: Linux is Unix, Open Office is MS Office, Gimp is Photoshop... all of course much better and open. But it makes the goals of these project quite simple to describe: We want to build a free version of X.

Squeak is different: Once, there is not yet anything like it, the other problem: Squeak is lots of things at the same time. It's a programming language like Java, an IDE like Emacs or Eclipse, a media authoring system or a language for kids, depending on how you look at it.

The goal of Squeak is to create a true personal computing environment, for users of all ages, from kids in school, to students or researchers at universities , to normal " down to earth" developers.

Our number one commitment is to an exquisite personal computing environment. Imagine a system as immediate and tactile as a sketch pad, in which you can effortlessly mingle writing, drawing, painting, and all of the structured leverage of computer science. Moverover imagine that every aspect of that system is described in itself and equally amenable to examination and composition. Perhaps this system also extends out over the Internet, including and leveraging off the work of others. You get the idea -itquotes the Holy Grail of computer science. Where is Squeak Headed? -From squeak.org

History

The hero of our story is named Alan, the time is somewhere at the end of the sixties. Great time for being a computer science researcher, as the US military just pumped huge amounts of cash into basic computer research with the ARPA program. Lots of cool stuff was invented in that time, e.g. packet switching networks (ArpaNet), and Alan got to see some cool stuff: The first prototype of a flat panel display, one of the first handwriting recognizers and the drawing program SketchPad (according to some the most important program ever written). Papertquotes LOGO programing language for kids. And Moores Law.

So, he got an idea. A crazy one: Why not build a computer that is small enough to be carried around. It should have the size of a notebook, weighting around two pounds. It should have a graphical display, have enough memory to store a couple of books. It even could have a harddisc. A small one. Keep in mind that harddiscs at that time had the size of a refrigerator. A true Personal Computer. Build for kids. Codename: Dynabook. Kids using the Dynabook (ca. 1968) Today, this sounds a bit obvious, but back then, it was completely crazy. Indeed, the best way to predict the future is to invent it.

But the technical aspect is not the only interesting one: The idea was to build a computer for kids in the way that it would be a new kind of medium. For fun and learning. Not a word-processor, but an idea-processor.

The goal was to make this crazy dream a reality. Moores law gave the deadline: A sufficiently fast computer would fit, according to Moores law, inside the required space in 1980. So Alan started to think about the software, at Xerox PARC.

The Operating System, GUI and development environment for the Dynabook was called Smalltalk. It was the first fully Object Oriented System, and the first GUI with real, overlapping windows. The famous story is that Steve Jobs did get a demo of that system.... Squeak is that Smalltalk System from the seventies, dusted off. And the Squeakers are the inventors of Smalltalk, Alan Kay of course, and Dan Ingalls and Ted Kaehler, both from the original Xerox PARC team.

Squeak was started in 1996, while the Squeak Team was at Apple. They moved on to Disney from there, and today, Alan is at HP Labs.

Squeak for Kids

So, now go forward some slides to the Squeak for Kids project. A typical example of a project that kids will build with Squeak is the Car: A small painted car is programmed to be griven by a steering wheel and later, even has the ability to follow the road all by itself.

A Squeak Car

There is a good tutorial on the Squeakland website about how to build a car yourself: <http://squeakland.org/school/drive_a_car/html/Drivecar12.html>

The Lunar Lander is an example of how far you can go with eToys: This was not done by a child, but with some guidance older kids could build such a game (and learn a lot).

Lunar Lander in eToys

There are a some other examples for eToy projects in the Linux image, many more can be found at http://squeakland.org. <http://squeakland.org/> 4 Squeak for Professional Development eToy is great for kids (and even for adults to learn programming). But the real hacker needs something that is a bit different. Squeak is completely written in itself, and for making that easy, it provides a object oriented programming language and a development environment.

The IDE provides a class browser for easy coding and a really good debugger. (With editand-continue, something that is starting to get a hot topic for both Java and .Net).

Squeak is actually used both in research and in industry to do real stuff. This is no toy! (Even if it looks like one).

The Language

The language of Squeak is really simple. But itquotes a bit different than the other ones you might know. This slide has all the syntax of the language: Syntax of Squeak Thatquotes it. In the slide, you can execute and print a statement by selecting it and pressing Alt-p (or Apple-p on the Mac).

The basic idea is that everything is an object, and you can make an object do something by sending a message to it. What an object does when receiving a message is described in a method. The method is defined in the class of the object.

So if you write:

1 sin then you have an object (the number 1) and you send a message (sin). The object 1 is of class SmallInteger, and those SmallIntegers know how to calculate the sinus.

A real smalltalk introduction is outside of the scope of this paper, see <http://www.iam.unibe.ch/˜ducasse/FreeBooks.html> for some books.

There is a good short introduction slide-show in the current 3.7 or 3.8 Squeak release images.

Seaside

Seaside is quite interesting. Avi Bryant was using Ruby for doing web development. Then he met some Squeakers at OOPSLA (the OO Conference).

And so he jumped ship from Ruby to Squeak and invented Seaside. Seaside is interesting, as it solves the problems that any web developer faces in novel ways. The target for Seaside are web applications, that is fairly complicated interactive websites (e.g. the typical banking site), not static pages.

Seaside allows the programmer to write the web application just the way she would write a normal GUI application. Letquotes see what Avi writes:

Seaside is a framework for developing sophisticated web applications in Smalltalk. Its most unique feature is its approach to session management: unlike servlet models which require a separate hand ler for each page or request, Seaside models an entire user session as a continuous piece of code, with natural, linear control flow -pages can call and return to each other like subroutines, complex sequences of forms can be managed from a single method, objects are passed by reference rather than marshalled into URLs or hidden fields -while fully supporting the backtracking and parallelism inherent to the web browser.

Seaside also features a callback-based event model, a transaction system for auto-expiring pages, strictly compliant XHTML generation, a system of reusable and embeddable UI components, and handy web-based development tools.

The Squeak image that drives the slides has a complete seaside installation. Yes, everything is there. Just point your browser to <http://localhost:9090/seaside/presentation> for a Seaside demo written in Seaside.

The Counter/MultiCounter are here: <http://localhost:9090/seaside/counter> <http://localhost:9090/seaside/multi> A short article about seaside: <http://homepage.mac.com/svc/ADayAtTheBeach/> It ends with:

We quotediscoveredquote Seaside only recently. After just one day of experimenting with it we were convinced about the dramatic improvement in abstraction and productivity it offers. We were absolutely amazed at how easy it was to do the examples described here: much, much easier than it would be in any other framework that we know of. We believe Seaside could be a killer application for Squeak.

For more information about Seaside, see http://seaside.st <http://seaside.st/>

OpenCroquet

Now to the really interesting latest and greatest in Squeak. As with Squeak itself, we need a good quote from the developers: WHAT IF... ...we were to create a new operating system and user interface knowing what we know today, how far could we go? What kinds of decisions would we make that we might have been unable to even consider 20 or 30 years ago, when the current set of operating systems were first created? ...we could collaborate with one another in an online dimension to create or simulate anything we wanted to? ...we had the robustness of a 3D immersive technology, the diversity of the Internet, and the degree of social interaction we have in the real world?

The LinuxTag demo image does not contain a croquet installation. Croquet is (up to now) build on a slightly older version of Squeak than the one used to build the demo.

Croquet is work-in-progress. But there is a pre-release available for download. If you have a fast computer with a good 3D graphics card, give it a try.

All the needed files and a good introduction are available at http://coquetproject.org <http: //coquetproject.org/>

Links

• http://squeak.org <http://squeak.org/> -the main Developer Site

• http://squeak-ev.de <http://squeak-ev.de/> -German Squeak Association

•

  http://squeakland.org <http://squeakland.org/> -Squeak for Kids • http://croquetproject.org <http://croquetproject.org/> -Croquet • http://seaside.st <http://seaside.st/> -Seaside 6 Books <http://www.iam.unibe.ch/˜ducasse/FreeBooks.html>

http://squeakersfilm.org <http://squeakersfilm.org/> -Documentation about Squeak


Alexandre Bergel

Marcus Denker

Prototyping Languages Related Constructs and Tools with Squeak *

Prototyping new programming languages is often assimilated as a task requiring heavy expertise in parsing and compilation. This paper argues that choosing as a host platform a language having advanced reflective capabilities helps in reducing the effort and time spent on developing new language related constructs and tools.

The Squeak Smalltalk implementation provides very expressive reflective facilities. In this paper we focus on having methods as first class entities, enabling methods manipulation as plain standard objects and reification of method execution. Powerful language related tools and efficient new programming constructs can be quickly implemented. ByteSurgeon, a bytecode manipulation library, and FacetS, an aspect mechanism, serve as illustrations.

Introduction

Traditionally, developing a new programming language is a task that usually requires knowledge of complex techniques like lexical parsing and syntactic analysis, and compilation toward native or virtual machine code. Although these steps are commonly adopted when new languages are developed, this pro-cess is heavy and necessitates significant efforts which hamper experimentation.

Smalltalk has long offered powerful reflective capabilities [START_REF] Ducasse | Evaluating message passing control techniques in Smalltalk[END_REF] such as a metaclass hierarchy and first class entities for most of the elements of the language such as classes, method dictionaries and methods. Moreover, a powerful Smalltalk environment implementation offers a compiler, debugger and others tools that can be easily adapted. Smalltalk is therefore a natural choice to experiment and prototype new programming languages [START_REF] Bergel | Prototalk: an environment for teaching, understanding, designing and prototyping object-oriented languages[END_REF][START_REF] Bouraqadi | Concern oriented programming using reflection[END_REF][START_REF] Briot | Actalk: A testbed for classifying and designing actor languages in the Smalltalk-80 environment[END_REF][START_REF] Cointe | The ClassTalk system: A laboratory to study reflection in smalltalk[END_REF].

Squeak [START_REF] Ingalls | Back to the future: The story of Squeak, A practical Smalltalk written in itself[END_REF][START_REF]Squeak home[END_REF] is a Smalltalk implementation that brings reflection a step further. Whereas it handles methods as first class entities that can be modified and replaced on the fly, it also allows for method execution reification, exposing dynamic information related to method execution as objects.

This paper first describes how bytecode is stored as plain compiled method objects. This object defines a method and is associated with a name within a method dictionary. Each class is associated with a method dictionary. CompiledMethod and MethodDictionary are two classes present in most of the Smalltalk implementations (including Squeak), and allow for easy and powerful bytecode manipulation. This is illustrated by ByteSurgeon [START_REF] Denker | Runtime bytecode transformation for Smalltalk[END_REF], a bytecode transformation framework.

Compiled methods contain bytecode and are directly interpretable by the Squeak virtual machine. However, if another object stands for a compiled method in a method dictionary, the virtual machine (VM) detects it and instead of directly interpreting it, the VM sends the message run: methodName with: listOfArguments in: receiver to this object. We call this mechanism method execution reification. This mechanism is used to implement FacetS, a dynamic aspect system with just three classes.

This paper claims that choosing a reflective language as a platform reduces effort and time spent in developing new syntactical language constructs and language related tools. The contributions of this paper are:

• Description of a runtime environment that supports methods as first class entity.

• Presentation of the method execution reification mechanism.

• Illustrations of this concepts with Byte-Surgeon, a high level bytecode transformation framework, and FacetS, a minimal dynamic aspect system.

First, Section 2 describes the two reflective mechanisms of Squeak: methods as first class entities (Section 2.1) and reification of method execution (Section 2.2). Then in Section 3 the use of first class entity methods is illustrated with ByteSurgeon, and Section 4 illustrates with FacetS reification of method execution. And finally in Section 6 the conclusion is presented.

Reflective Capabilities of Squeak

Programming languages such as Smalltalk [START_REF] Goldberg | Smalltalk-80: The Language[END_REF], CLOS [START_REF] Bobrow | Common lisp object system specification[END_REF], Ruby [START_REF] Thomas | Programming Ruby[END_REF], Self [START_REF] Ungar | Self: The power of simplicity[END_REF] are often classified as dynamic languages referring to their dynamic type system, advanced reflective features, use of metaclasses and their interactivity with the programmer. Squeak [START_REF] Ingalls | Back to the future: The story of Squeak, A practical Smalltalk written in itself[END_REF][START_REF]Squeak home[END_REF] is an open-source Smalltalk dialect that offers expressive reflective features related to methods like reification of method and method execution.

Methods as Objects

Reification of Methods Classes encode the structure of instances: variables, superclass, subclass relationships and methods. In Squeak, both classes and methods are represented by first class objects that can be accessed and even changed at runtime.

Compiled methods are objects in Squeak that describe the executable part of methods. These contain a pointer to the sourcecode and the code executed by the virtual machine, the bytecode. These methods are stored in a dictionary (a method dictionary), keyed by their names. We can access the method dictionary of a class by sending the message method-Dict to this class. For instance, executing ExampleClass methodDict return the methods dictionary of the class ExampleClass.

This dictionary then provides an interface for adding or replacing methods. When a new method is added from a programming tool (e.g., a Smalltalk code browser) in essence the environment performs the following:

ExampleClass methodDict at: #myMethod put: aCompiledMethod

A compiled method (aCompiledMethod) is added to the method dictionary of the class ExampleClass under the name myMethod. The effect is the addition of a new method.

Objects as Methods

Reification of Method Execution When a message named m is sent to an object, the corresponding method is searched along the single inheritance link of the class of the object. Once the method named m is found in one of the superclass (i.e., its method dictionary contains an entry for m), then the corresponding value associated with m is fetched from the method dictionary by the VM. Now the method gets invoked by the VM. One of two cases happens: either this method is a compiled method (i.e., list of bytecode), or it is an object method (a plain object). If this value is a compiled method (an instance of the class CompiledMethod), then the VM directly interprets the bytecode. If this value is not a compiled method, then the VM performs a reification of the method execution.

This method execution reification is performed by the VM when sending the message run: methodName with: listOfArguments in: receiver to this object method. In such a case, methodName contains the name of the method currently invoked, listOfArguments contains the list of arguments provided, and receiver a reference to the receiver to the message.

For instance, let assume two classes, C and Wrapper:

Object subclass: #C instanceVariableNames: " classVariableNames: " poolDictionaries: " category: 'Example'.

Object subclass: #Wrapper instanceVariableNames: " classVariableNames: " poolDictionaries: " category: 'Example'.

The class Wrapper contains a method named run:with:in: that takes three arguments, a name (methodName), an array of objects (listOfArguments), and an object reference (receiver):

Wrapper ≫run: methodName with: listOfArguments in: receiver "We first display some info on the standard output stream" Transcript show: 'Method ', methodName, ' arguments: ', listOfArguments printString, ' receiver: ', receiver printString.

"Then we return the first element of the provided list" ˆlistOfArguments first

Prior to returning the first elements of listOfArguments, some information is written to the standard output stream.

For instance, a method foo: can be added to the class C by evaluating: As similarly shown in Section 2.1, the last line above adds an entry named foo: to the method dictionary of C. Instance of C therefore understand messages named foo:. Because of the method execution reification mechanism, evaluating c foo: 10 is in fact evaluated by the VM as:

w run: #foo: with: # [START_REF] Hirschfeld | AspectS -Aspect-Oriented Programming with Squeak[END_REF]

in: c

The result is 10, and displays the following on the standard output stream:

Method foo: arguments: #(10) receiver: a C

Case Study: Bytecode Transformation

We have seen that replacing CompiledMethod objects is simple to do in Squeak. But sometimes, the granularity of change needed is not that of a method. We might want to modify a method by just adding or replacing some parts.

Examples for cases where this is useful are e.g., adding hooks into bytecode for tracing and profiling. Bytecode transformation has a number of advantages over using other representations. Program text is not required and the performance of transformation is better: We are already working on the lowest level and thus skip the costly code generation phase of a full compiler.

Bytecode transformation is not limited to Squeak, it has been implemented before in the Java world [START_REF] Chiba | An easy-to-use toolkit for efficient Java bytecode translators[END_REF]. But Squeak has one advantage: We can change methods at runtime, whereas Java is limited to do purely load-time transformations.

The following contains a short introduction of ByteSurgeon. More detailed description can be found in our previous work [START_REF] Denker | Runtime bytecode transformation for Smalltalk[END_REF].

ByteSurgeon Overview

Before explaining how ByteSurgeon works, we will look at an example. Our goal is to edit bytecode inside a method by inserting new bytecodes before the send bytecode: The user of ByteSurgeon deals with methods: The method that should be edited is sent the instrument: message. This takes as an argument a block that is then executed for each bytecode in the method. ByteSurgeon takes care to do all decoding, it provides objects describing a bytecode, not raw numbers, as the parameter for the block.

With the bytecode objects the following operations can be performed: insertion before, after or replacement. The code to be inserted is described using a string of standard Smalltalk code.

The example thus will insert code for incrementing a counter in front of every virtual machine instruction send bytecode in the method #aMethod of the ExampleClass.

ByteSurgeon provides other, more advanced fea-

The user can access certain values that turn out to be interesting, but hard to get to. For example, when replacing a VM instruction send bytecode, the receiver and the arguments of that send have been pushed on the stack. ByteSurgeon can provide access to these values, when needed, using so called meta variables. As a simple example, the following code provides a tracer with the receiver object of all sends: ByteSurgeon takes care to generate code for saving the needed value for access in the inlined code.

Implementation

ByteSurgeon uses the backend of a Smalltalk source-to-bytecode compiler. This compiler provides an intermediate form called intermediate representation (IR) that abstracts from the specific bytecode details.

we use the compiler backend to decompile the method object into the IR, then ByteSurgeon transforms the IR, and the codegenerator then generates a new compiled method (see figure 1).

Projects using ByteSurgeon

ByteSurgeon has been used to implement Geppetto, a complete, fine-grained dynamic Meta Object Protocol [START_REF] Kiczales | The Art of the Metaobject Protocol[END_REF] based on the design of Reflex [START_REF] Tanter | Partial behavioral reflection: Spatial and temporal selection of reification[END_REF]. As Reflex is based on Java, it can only provide reflective facilities when the bytecode has been transformed at loadtime. Gepetto on the other hand allows for completely unanticipated use.

Another application of ByteSurgeon is a tracelibrary for Squeak that is used in a number of contexts: Feature Analysis based on dynamic runtime traces and an ongoing project to implement an Omniscient Debugger [START_REF] Lewis | Debugging backwards in time[END_REF] for Squeak.

Case Study: Dynamic Aspects with FacetS

Aspect-oriented programming (AOP) [START_REF] Kiczales | Aspect-oriented programming: A position paper from the Xerox PARC aspect-oriented programming project[END_REF] holds the promise of composing softwares out of orthogonal concerns. AOP promotes code insertion (i.e., advices) at some particular locations in the source code (i.e., join point1 ). These advices are executed when the control flow reaches a join point. AOP is useful to separate non-functional cross cutting concerns from a base system like security, logging or persistence [START_REF] Kiczales | Aspect-oriented programming: A position paper from the Xerox PARC aspect-oriented programming project[END_REF].

In this section, we describe the implementation of a dynamic aspect mechanism, called FacetS, made in Squeak. In order to keep the description short, we restricted the number of supported join points to two: before and after a method invocation.

Before describing how FacetS is implemented, we first present a small example that counts the number of call of a method. To compute factorial, the Integer class has a method named factorial that does a self recursion. The following code defines a temporary variable nbOfCalls initialized with 0 and an advice composed of a piece of code (that increments the variable) and a pointcut which is a predicate identifying join point: The code above means that the increment specified in the block will be executed before the method factorial defined in the class Integer. An aspect, composed of a set of advices is created by: as := Aspect new. as addAdvice: ad.

This aspect is then installed on the class Integer with: as installOn: Integer. Evaluating 10 factorial returns 3628800 and increment the nbOfCalls to 11. The aspect can be removed with: as remove.

Aspect. As we previously mentioned, an aspect is a set of advices that can be applied to a set of classes. The class Aspect has two instance variables, a method installOn: and a method remove. It is therefore defined as: Advice. An advice contains

• a list of pointcuts, i.e., locations within the source code. some piece of code intended to be executed if the pointcuts are activated.

• a modifier (i.e., before, after, or around ).

• the list of affected methods by this advice necessary for removal.

The definition of the class Advice is the following:

Object subclass: #Advice instanceVariableNames: 'modifier pointcuts code methodsAffected' classVariableNames: " poolDictionaries: " category: 'FacetS' Installation of an advice is performed through the method installOn: taking a list of classes sent to an advice instance: We first iterate over all the classes on which an aspect is installed. For each of these, we iterate overs its list of method names, and check if the pointcut is activated or not (i.e., if the block that defines a pointcut is true when evaluated with the class and a method name). If it is the case, then we keep track of the affected method, and replace the method with a wrapper (discussed further in this section).

Removing a method is simply done by iterating over the affected methods and replacing the wrapper with its corresponding compiled method. Wrapper. A wrapper is an object intended to be inserted within a method dictionary in order for a method to be instrumented with an advice. A wrapper contains a reference to the advice from which it has been produced from and a reference to the compiled method that it instruments.

Object subclass: #Wrapper instanceVariableNames: 'advice compiledMethod' classVariableNames: " poolDictionaries: " category: 'FacetS'

As shown in the installOn: method of the class Advice, when a method is instrumented, its compiled method is replaced by a wrapper that contains a reference to this compiled method and to an advice.

Sending a message for which a compiled method is not associated with triggers the method execution reification mechanism described in Section 2.2. When a method instrumented with a wrapper is invoked, the method run:with:in: defined on the wrapper is executed: Minimal AOP mechanism. This section fully describes a dynamic aspect mechanism consisting of 3 classes and 5 methods. Aspects can be installed and removed dynamically. The key point of this design is the method run:with:in: that execute some instrumentation before or after a method. This method is triggered by the VM, using the method execution reification mechanism.

Related Work

Section 2 presents two reflective mechanisms, however many others exist. This section gives a short description of the reification mechanisms provided by some other systems. For space reasons, we can not give a complete overview of related work.

Smalltalk. Few message passing control techniques other than the one presented in Section 2 are offered by Smalltalk [START_REF] Ducasse | Evaluating message passing control techniques in Smalltalk[END_REF] (and thus Squeak):

• By embedding a compiler in the Smalltalk environment, methods' source code can be easily modified. Methods can be recompiled on the fly.

• Error handling can be easily specialized. The idea is to specialize the doesNotUnderstand: method invoked when an object does not understand a message.

• Introduction of anonymous subclass into the inheritance hierarchy allows message defined in upper classes to be intercepted.

MetaclassTalk. An extension of Smalltalk named MetaclassTalk [START_REF] Bouraqadi | Concern oriented programming using reflection[END_REF] provides explicit metaclasses and allows the method evaluation process to be transparently controlled and redefined. Within MetaclassTalk, classes play the role of meta objects which define execution mechanisms for their instance.

CLOS. Common Lisp has long offered an object model, CLOS. It is one of the few class based languages to offer the ability to define instance specific methods [START_REF] Bobrow | Common lisp object system specification[END_REF]. Moreover CLOS is also one of the rare languages to provide a meta object protocol in which message passing control is an entry point [START_REF] Kiczales | The Art of the Metaobject Protocol[END_REF].

Java. The package java.lang.reflect has been distributed since the version 1.1 of Java. It provides few mechanisms to allows limited information about classes and object to be reified. However, it does not allow methods and classes to be modified at runtime. Reflex [START_REF] Tanter | Reflex -towards an open reflective extension of Java[END_REF] is an extension of Java that offers a full meta object protocol using bytecode modification. As Java allows not to change methods at runtime, these modifications need to be done in advance at load time. Reflex. In the context of Java, Reflex [START_REF] Tanter | A versatile kernel for multi-language AOP[END_REF] provides building blocks for facilitating the implementation of different aspect-oriented languages so that it is easier to experiment with new AOP concepts and languages, and it is also possible to compose aspects written in different AOP languages. It is built around a flexible intermediate model, derived from reflection, of (point)cuts, links, and metaobjects, to be used as an intermediate target for the implementation of aspect-oriented languages.

AspectS. The first AOP system designed for Squeak is AspectS [START_REF] Hirschfeld | AspectS -Aspect-Oriented Programming with Squeak[END_REF]. AspectS and FacetS differ regarding the aspect construction. With AspectS a new aspect is created by subclassing the class Aspect. An advice is then associated to a method.

With FacetS, an aspect is created by instantiating the class Aspect and by providing pointcuts and advices. FacetS supports incremental definition of aspects.

Conclusion

This paper presents and illustrates two reflective features of Squeak. First, methods are first class entities. As plain objects, methods can be replaced and modified on the fly. Tools such as ByteSurgeon, a high level bytecode transformation framework, are easily implemented. Most of Smalltalk systems support methods as first class entity. This is not a characteristic of Squeak, but we believe it is an important mechanism that is not widely known or accepted in the language community. The second reflective feature presented is method execution reification: the VM emits a plain message when a method that is not compiled into bytecode has to be executed. This message sent contains information regarding the current method execution. This feature is a characteristic of Squeak. This mechanism is used to develop FacetS, a minimal dynamic AOP systems consisting of 3 classes.

Each programming language has its own specificity, having therefore a limited domain of applicability. Prototyping new programming language allows for experimentation with new constructs where results have to be quickly produced. This paper argues that a language having extended reflective features constitutes a powerful host platform.

"

  We create an instance of Wrapper" w := Wrapper new. "We create an instance of C" c := C new. "We add a new method named foo: to C" C methodDict at: #foo: put: w.

(

  Example>> #aMethod) instrument: [:instr | instr isSend ifTrue: [instr insertBefore: 'Counter inc'] ].

(

  ExampleClass>> #aMethod) instrument: [:instr | instr isSend ifTrue: [ instr insertBefore: 'Tracer traceSendTo: <meta: #receiver> '] ].

Figure 1 :

 1 Figure 1: ByteSurgeonFor a more detailed description and benchmarking results see[START_REF] Denker | Runtime bytecode transformation for Smalltalk[END_REF].

  |nbOfCalls ad as | nbOfCalls := 0. ad := Advice new. ad code: [:receiver :methodName :args | nbOfCalls := nbOfCalls + 1]. ad addPointcut: [:cls :methodName | (cls name = #Integer) & (methodName = #factorial)]. ad modifier: #before.

Advice

  >> installOn: aCollectionOfClasses methodsAffected := OrderedCollection new. aCollectionOfClasses do: [:c | c methodDict keys do: [:m | self pointcuts do: [:p | (p value: c value: m) ifTrue: [ |cm wrapper | cm := c methodDict at: m. methodsAffected add: (MethodReference class: c selector: m). wrapper := Wrapper advice: self compiledMethod: cm. c methodDict at: m put: wrapper]]]]

  Advice >> remove methodsAffected do: [:mref | |c m w | c := mref actualClass. m := mref methodSymbol. w := c methodDict at: m. c methodDict at: m put: w compiledMethod]

Wrapper

  >> run: aSymbol with: args in: rec |code modifier argsForCode | code := advice code. modifier := advice modifier. argsForCode := rec . aSymbol. args. (modifier isNil or: [modifier == #before]) ifTrue: [code valueWithArguments: argsForCode. ˆcompiledMethod valueWithReceiver: rec arguments: argsForCode]. (modifier isNil or: [modifier == #after]) ifTrue: [|v | v := compiledMethod valueWithReceiver: rec arguments: argsForCode. code valueWithArguments: argsForCode. ˆv].

For the sake of simplicity, we do stick to the terminology usually used in the AOP community by making no distinction between join point and join point shadow.

Acknowledgments. We would like to thank Andrew Jackson and Yong Wang for their valuable comments and Andreas Raab for designing and implementing Squeak's method execution reification.

We gratefully acknowledge the Science Foundation Ireland, Lero -the Irish Software Engineering Research Centre and the the financial support of the Swiss National Science Foundation for the project "A Unified Approach to Composition and Extensibility" (SNF Project No. 200020-105091/1, Oct. 2004 -Sept. 2006).