Building run-time analysis tools by
 means of pluggable interpreters
Contents


    Introduction
    Method wrappers
    Interpreter
    Compatiblity issues
    Demo
    References
Introduction


  Need for tools
    Coverage
       Methods, blocks, arguments, variables
    Run-time typing informat...
Introduction


  Smalltalk language
     Simple semantics
  Interpreter
     Declarative feel
     Easier to understa...
Method wrappers


  Intercept method activations
    Smalltalk reflection
         Localized ‘tricks’
    Easy to exte...
Interpreter


  Recursive descent
    Abstract grammar
       Parse tree
    Eval method
  Smalltalk = run-time engin...
Abstract grammar


  Expression tree
  Expression ()
            Assignment ('variable' 'value')
            Code ('argum...
Contexts


  Contexts
  CodeContext ()
            BlockContext ('outerContext' 'level')
            MethodContext ('rece...
Evaluation


  Method wrappers
  valueWithReceiver: anObject arguments: arrayOfObjects
            "Evaluate the method b...
Evaluation


  Method expressions
  contextWithReceiver: anObject arguments: arrayOfObjects
            ”Answer a context...
Evaluation


  Literal expressions
  eval: aContext
            ”Answer the value.”

             ^ value



  Pseudo-va...
Evaluation


  Shared variables
  eval: aContext
            ”Answer the value bound to the variable.”

             ^ bi...
Evaluation


  Instance variables
  eval: aContext
            ”Answer the value bound to the variable.”

             ^ ...
Evaluation


  Local variables
  eval: aContext
            ”Answer the value bound to the variable.”

             ^ (aC...
Evaluation


  Assignment expressions
  eval: aContext
            ”Bind the value to the variable. Answer the value.”

 ...
Evaluation


  Block expressions
  eval: aContext
            ”Build a block closure for this context. Answer the closure...
Evaluation


  Wrapping block closures in ‘native’ closures
  asNativeBlockClosure
            ”Wrap the receiver in a na...
Evaluation


  Message expressions
  eval: aContext
            ”Evaluate receiver and arguments. Do the actual lookup an...
Evaluation


  Message expressions
  perform: sel receiver: rcvr arguments: args class: aBehavior
               ”Retriev...
Evaluation


  Message expressions
  lookupMethod: selector in: aClass
                   sel in: aBehavior
             ...
Compatibility issues


  BlockClosure
    copied values, ...
  Pseudo-variables
    thisContext
  No saveguards
    ...
Demo


  Tools
    Coverage tool
       Updating number of activations in #eval: methods
    Gathering run-time typing...
References

  Method wrappers
       http://st-www.cs.uiuc.edu/~brant
Upcoming SlideShare
Loading in...5
×

Runtime Tools

539

Published on

Michel Tilman: Building run-time analysis tools by means of pluggable interpreters (ESUG 2000, Southampton)

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
539
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
2
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Runtime Tools

  1. 1. Building run-time analysis tools by means of pluggable interpreters
  2. 2. Contents   Introduction   Method wrappers   Interpreter   Compatiblity issues   Demo   References
  3. 3. Introduction   Need for tools   Coverage   Methods, blocks, arguments, variables   Run-time typing information   …   Current tools   Smalltalk reflection   Low-level, hard to understand, operational   Bytecodes, processes, ….
  4. 4. Introduction   Smalltalk language   Simple semantics   Interpreter   Declarative feel   Easier to understand   Selective   Per method   Embedded interpreter
  5. 5. Method wrappers   Intercept method activations   Smalltalk reflection   Localized ‘tricks’   Easy to extend   Usage   Before-after methods   Build interaction diagrams   ...   Activate interpreter
  6. 6. Interpreter   Recursive descent   Abstract grammar   Parse tree   Eval method   Smalltalk = run-time engine   Garbage collection   Primitives   Include methods supporting interpreter implementation   Unwinding stack   ….
  7. 7. Abstract grammar   Expression tree Expression () Assignment ('variable' 'value') Code ('arguments' 'temporaries') Block ('level') Method ('mclass' 'selector') Literal ('value') MessageExpression ('receiver' 'selector' 'arguments’ ‘methodCache’) PseudoVariable ('isSuper') Return ('value') Variable () InstanceVariable ('index' 'class') LocalVariable ('name' 'level' 'index') SharedVariable ('binding')
  8. 8. Contexts   Contexts CodeContext () BlockContext ('outerContext' 'level') MethodContext ('receiver' 'method' 'returnHandler')   Block closures BlockClosure ('block' 'outerContext')
  9. 9. Evaluation   Method wrappers valueWithReceiver: anObject arguments: arrayOfObjects "Evaluate the method by invoking the interpreter.” ^ self methodExpression valueWithReceiver: anObject arguments: arrayOfObjects   Method expressions valueWithReceiver: anObject arguments: arrayOfObjects ”Create a suitable context. Evaluate the method with given receiver and arguments in this context. Answer the result.” | context | context := self contextWithReceiver: anObject arguments: arrayOfObjects. ^ self valueInContext: context
  10. 10. Evaluation   Method expressions contextWithReceiver: anObject arguments: arrayOfObjects ”Answer a context for evaluating the receiver. Install a return handler block.” ^ MethodContext on: self receiver: anObject arguments: arrayOfObjects returnHandler: [ :value | ^ value ]   Method (Code) expressions valueInContext: aMethodContext ”Evaluate the statements for side effects. Answer the result of the last evaluation.” | answer | self statements do: [ :stat | answer := stat eval: aMethodContext ]. ^ answer
  11. 11. Evaluation   Literal expressions eval: aContext ”Answer the value.” ^ value   Pseudo-variables (“self”, “super”) eval: aContext ”Answer the receiver.” ^ aContext receiver
  12. 12. Evaluation   Shared variables eval: aContext ”Answer the value bound to the variable.” ^ binding value   Shared variables bind: anObject context: aContext ”Bind the object to the variable.” binding value: anObject. ^ anObject
  13. 13. Evaluation   Instance variables eval: aContext ”Answer the value bound to the variable.” ^ aContext receiver instVarAt: index   Instance variables bind: anObject context: aContext ”Bind the object to the variable.” ^ aContext receiver instVarAt: index put: anObject
  14. 14. Evaluation   Local variables eval: aContext ”Answer the value bound to the variable.” ^ (aContext contextAt: level) at: index   Local variables bind: anObject context: aContext ”Bind the object to the variable.” ^ (aContext contextAt: level) at: index put: anObject
  15. 15. Evaluation   Assignment expressions eval: aContext ”Bind the value to the variable. Answer the value.” ^ variable bind: (value eval: aContext) context: aContext   Return expressions eval: aContext ”Evaluate the value expression. Return the answer as the return value of the method that ‘defines’ this return expression.” aContext returnHandler value: (value eval: aContext)
  16. 16. Evaluation   Block expressions eval: aContext ”Build a block closure for this context. Answer the closure.” ^ BlockClosure block: self outerContext: aContext   Executing block closures value ”Execute the block (closure) without arguments. Answer the result.” ^ block numTemps = 0 ifTrue: [ block valueInContext: outerContext ] ifFalse: [ block valueInContext: (BlockContext outerContext: outerContext level: block level + 1 size: numTemps)]
  17. 17. Evaluation   Wrapping block closures in ‘native’ closures asNativeBlockClosure ”Wrap the receiver in a native block closure. Note: this is self-modifying code.” | numArgs | (numArgs := block numArgs) = 0 ifTrue: [ ^ [ self value ]]. numArgs = 1 ifTrue: [ ^ [ :arg1 | self value: arg1 ]]. numArgs = 2 ifTrue: [ ^ [ :arg1 :arg2 | self value: arg1 value: arg2 ]]. numArgs = 3 ifTrue: [ ^ [ :arg1 :arg2 :arg3 | self value: arg1 value: arg2 value: arg3 ]]. numArgs = 4 ifTrue: [ ^ [ :arg1 :arg2 :arg3 :arg4 | | args | args := Array new: 4. args at: 1 put: arg1. args at: 2 put: arg2. args at: 3 put: arg3. args at: 4 put: arg4. self valueWithArguments: args ]]. self generateUpTo: numArgs. ^ self asNativeBlockClosure
  18. 18. Evaluation   Message expressions eval: aContext ”Evaluate receiver and arguments. Do the actual lookup and execute the method found.” | rcvr args behavior | rcvr := receiver eval: aContext . args := arguments collect: [ :arg | arg eval: aContext ]. behavior := receiver isSuper ifTrue: [ aContext methodClass superclass ] ifFalse: [ rcvr class ]. ^ self perform: selector receiver: rcvr arguments: args class: behavior
  19. 19. Evaluation   Message expressions perform: sel receiver: rcvr arguments: args class: aBehavior ”Retrieve the method for given selector, starting the lookup in the class. Execute the method and return the result if successful. Otherwise fail with a #doesNotUnderstand: message. Note that executing a #perform: in the false branche instead of executing the method will acutally be faster. The lookup is only relevant in so far we are interested in keeping track of the different method invocations at the call site.” | method | ^ (method := self lookupMethod: sel in: aBehavior) isNil ifTrue: [ rcvr doesNotUnderstand: (Message selector: sel arguments: args)] ifFalse: [ method valueWithReceiver: rcvr arguments: args ]
  20. 20. Evaluation   Message expressions lookupMethod: selector in: aClass sel in: aBehavior ” Search for an appropriate method. First perform a lookup in the local cache. Upon failure do a regular lookup and cache the result.” ^ cache at: aClass ifAbsentPut: [ self basicLookupMethod: selector in: sel in: ] methodCache at: aBehavior ifAbsentPut: [ self basicLookupMethod: aClass aBehavior]   Message expressions basicLookupMethod: sel in: aBehavior "Search for a method in the class hierarchy. Answer nil upon failure." ^ (array := aBehavior findSelector: sel) isNil ifTrue: [ nil ] ifFalse: [ array at: 2 ]
  21. 21. Compatibility issues   BlockClosure   copied values, ...   Pseudo-variables   thisContext   No saveguards   Primitives   ‘Kernel’ methods
  22. 22. Demo   Tools   Coverage tool   Updating number of activations in #eval: methods   Gathering run-time typing   Remembering types in #eval: methods •  Variables •  Method invocations at call site   Fine-grained   Disjoint lexical occurrences of same variable
  23. 23. References   Method wrappers   http://st-www.cs.uiuc.edu/~brant
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×