11. Working with Bytecode. © Oscar Nierstrasz ST — Working with Bytecode 11.2 Roadmap  The Pharo compiler  Introduction to Pharo bytecode  Generating.

Slides:



Advertisements
Similar presentations
Dynamic Object-Oriented Programming with Smalltalk 1. Introduction Prof. O. Nierstrasz.
Advertisements

8. Static Single Assignment Form Marcus Denker. © Marcus Denker SSA Roadmap  Static Single Assignment Form (SSA)  Converting to SSA Form  Examples.
1 Lecture 10 Intermediate Representations. 2 front end »produces an intermediate representation (IR) for the program. optimizer »transforms the code in.
7. Optimization Prof. O. Nierstrasz Lecture notes by Marcus Denker.
1 Compiler Construction Intermediate Code Generation.
8. Introduction to Denotational Semantics. © O. Nierstrasz PS — Denotational Semantics 8.2 Roadmap Overview:  Syntax and Semantics  Semantics of Expressions.
Introduction to Software Engineering 7. Modeling Behaviour.
Semantic analysis Parsing only verifies that the program consists of tokens arranged in a syntactically-valid combination, we now move on to semantic analysis,
11. A bit of Smalltalk. © O. Nierstrasz P2 — A bit of Smalltalk 11.2 A bit of Smalltalk Overview  Some history  Smalltalk syntax & object model  The.
11. Working with Bytecode. © Oscar Nierstrasz ST — Working with Bytecode 11.2 Roadmap  The Squeak compiler  Introduction to Squeak bytecode  Generating.
George Blank University Lecturer. CS 602 Java and the Web Object Oriented Software Development Using Java Chapter 4.
2. Smalltalk Basics. © Oscar Nierstrasz ST — Smalltalk Basics 2.2 Roadmap  Everything is an Object  Syntax on a Postcard  Three Kinds of Messages 
12. Summary, Trends, Research. © O. Nierstrasz PS — Summary, Trends, Research Roadmap  Summary: —Trends in programming paradigms  Research:...
7. Understanding Classes and Metaclasses. © Oscar Nierstrasz ST — Understanding Classes and Metaclasses 7.2 Roadmap  Metaclasses in 7 points  Indexed.
© Oscar Nierstrasz ST — Smalltalk Basics 2.1 Change sets  Make sure your changes are logged to a new change set.
ESE Einführung in Software Engineering X. CHAPTER Prof. O. Nierstrasz Wintersemester 2005 / 2006.
Stéphane Ducasse 1 The Taste of Smalltalk.
13. A bit of Smalltalk. © Oscar Nierstrasz 2 Roadmap  The origins of Smalltalk  What is Smalltalk?  Syntax in a nutshell  Seaside — web development.
Dynamic Object-Oriented Programming with Smalltalk 1. Introduction Prof. O. Nierstrasz Summer Semester 2006.
13. Traits. Selected literature  Cook. Interfaces and Specifications for the Smalltalk-80 Collection Classes. OOPSLA 1992  Taivalsaari. On the Notion.
Metamodeling Seminar X. CHAPTER Prof. O. Nierstrasz Spring Semester 2008.
2. Smalltalk Basics. © Oscar Nierstrasz ST — Smalltalk Basics 2.2 Roadmap  Everything is an Object  Syntax on a Postcard  Three Kinds of Messages 
© Oscar Nierstrasz ST — Smalltalk Basics 2.1 Change sets  Make sure your changes are logged to a new change set.
N. XXX Prof. O. Nierstrasz Thanks to Jens Palsberg and Tony Hosking for their kind permission to reuse and adapt the CS132 and CS502 lecture notes.
Compiler Summary Mooly Sagiv html://
9. Understanding Classes and Metaclasses. Birds-eye view © Oscar Nierstrasz ST — Introduction 1.2 Reify your metamodel — A fully reflective system models.
7. Fixed Points. © O. Nierstrasz PS — Fixed Points 7.2 Roadmap  Representing Numbers  Recursion and the Fixed-Point Combinator  The typed lambda calculus.
© Oscar Nierstrasz ST — Introduction ST 1.1 The Smalltalk Compiler.
Object-oriented programming and design 1 Smalltalk in a Nutshell Objects & classes Messages & methods Inheritance & metaclasses.
Stéphane Ducasse5.1 Smalltalk in a Nutshell OO Model in a Nutshell Syntax in a Nutshell.
12. A bit of Smalltalk. © O. Nierstrasz P2 — A bit of Smalltalk 11.2 Roadmap  Some history  Smalltalk syntax & object model  The Smalltalk environment.
12. eToys. © O. Nierstrasz PS — eToys 12.2 Denotational Semantics Overview:  … References:  …
Stéphane Ducasse 1 Smalltalk in a Nutshell.
11. Working with Bytecode. © Oscar Nierstrasz ST — Working with Bytecode 11.2 Roadmap  The Squeak compiler  Introduction to Squeak bytecode  Generating.
S.Ducasse Stéphane Ducasse 1 The Taste of Smalltalk.
1.3 Executing Programs. How is Computer Code Transformed into an Executable? Interpreters Compilers Hybrid systems.
COP4020 Programming Languages
Chapter 1 Introduction Dr. Frank Lee. 1.1 Why Study Compiler? To write more efficient code in a high-level language To provide solid foundation in parsing.
1 Semantic Analysis Aaron Bloomfield CS 415 Fall 2005.
CS 326 Programming Languages, Concepts and Implementation Instructor: Mircea Nicolescu Lecture 2.
CMPS 211 JavaScript Topic 1 JavaScript Syntax. 2Outline Goals and Objectives Goals and Objectives Chapter Headlines Chapter Headlines Introduction Introduction.
CS 147 June 13, 2001 Levels of Programming Languages Svetlana Velyutina.
1 COMP 3438 – Part II-Lecture 1: Overview of Compiler Design Dr. Zili Shao Department of Computing The Hong Kong Polytechnic Univ.
Interpretation Environments and Evaluation. CS 354 Spring Translation Stages Lexical analysis (scanning) Parsing –Recognizing –Building parse tree.
1. 2 Preface In the time since the 1986 edition of this book, the world of compiler design has changed significantly 3.
Chapter 1 Introduction Study Goals: Master: the phases of a compiler Understand: what is a compiler Know: interpreter,compiler structure.
Introduction CPSC 388 Ellen Walker Hiram College.
CS412/413 Introduction to Compilers and Translators Spring ’99 Lecture 11: Functions and stack frames.
1 Compiler & its Phases Krishan Kumar Asstt. Prof. (CSE) BPRCE, Gohana.
S.Ducasse Marcus Denker 1 Working with Bytecodes: IRBuilder and InstructionStream.
S.Ducasse Stéphane Ducasse 1 Smalltalk in a Nutshell.
S.Ducasse Stéphane Ducasse savoie.fr e/ e/ 1 Smalltalk in a Nutshell.
Compiler Construction CPCS302 Dr. Manal Abdulaziz.
Programming Language Concepts (CIS 635) Elsa L Gunter 4303 GITC NJIT,
COP4020 Programming Languages Introduction Prof. Robert van Engelen (modified by Prof. Em. Chris Lacher)
LLVM IR, File - Praakrit Pradhan. Overview The LLVM bitcode has essentially two things A bitstream container format Encoding of LLVM IR.
Smalltalk Implementation Harry Porter, October 2009 Smalltalk Implementation: Optimization Techniques Prof. Harry Porter Portland State University 1.
Design issues for Object-Oriented Languages
Open Source Compiler Construction (for the JVM)
Lecture 9 Symbol Table and Attributed Grammars
Smalltalk Implementation
Chapter 1 Introduction.
Introduction to Compiler Construction
Compiler Construction (CS-636)
Compilers Principles, Techniques, & Tools Taught by Jing Zhang
Chapter 1 Introduction.
Compiler Lecture 1 CS510.
Programming Language Concepts (CIS 635)
CSE401 Introduction to Compiler Construction
COP4020 Programming Languages
Presentation transcript:

11. Working with Bytecode

© Oscar Nierstrasz ST — Working with Bytecode 11.2 Roadmap  The Pharo compiler  Introduction to Pharo bytecode  Generating bytecode with IRBuilder  Parsing and Interpreting bytecode Original material by Marcus Denker

© Oscar Nierstrasz ST — Working with Bytecode 11.3 Roadmap  The Pharo compiler  Introduction to Pharo bytecode  Generating bytecode with IRBuilder  Parsing and Interpreting bytecode

© Oscar Nierstrasz ST — Working with Bytecode 11.4 The Pharo Compiler  Default compiler —very old design —quite hard to understand —impossible to modify and extend  New compiler for Pharo — —adds support for true block closures (optional)

© Oscar Nierstrasz ST — Working with Bytecode 11.5 The Pharo Compiler  Fully reified compilation process: —Scanner/Parser (built with SmaCC) – builds AST (from Refactoring Browser) —Semantic Analysis: ASTChecker – annotates the AST (e.g., var bindings) —Translation to IR: ASTTranslator – uses IRBuilder to build IR (Intermediate Representation) —Bytecode generation: IRTranslator – uses BytecodeBuilder to emit bytecodes

© Oscar Nierstrasz ST — Working with Bytecode 11.6 Compiler: Overview codeAST Scanner / Parser Semantic Analysis Bytecode Code Generation ASTIR Build IR Bytecode Generation ASTTranslator IRBuilder IRTranslator BytecodeBuilder Code generation in detail

© Oscar Nierstrasz ST — Working with Bytecode 11.7 Compiler: Syntax  SmaCC: Smalltalk Compiler Compiler —Similar to Lex/Yacc —SmaCC can build LARL(1) or LR(1) parser  Input: —Scanner definition: regular expressions —Parser: BNF-like grammar —Code that builds AST as annotation  Output: —class for Scanner (subclass SmaCCScanner) —class for Parser (subclass SmaCCParser)

© Oscar Nierstrasz ST — Working with Bytecode 11.8 Scanner

© Oscar Nierstrasz ST — Working with Bytecode 11.9 Parser

© Oscar Nierstrasz ST — Working with Bytecode Calling Parser code

© Oscar Nierstrasz ST — Working with Bytecode Compiler: AST  AST: Abstract Syntax Tree —Encodes the Syntax as a Tree —No semantics yet! —Uses the RB Tree: – Visitors – Backward pointers in ParseNodes – Transformation (replace/add/delete) – Pattern-directed TreeRewriter – PrettyPrinter RBProgramNode RBDoItNode RBMethodNode RBReturnNode RBSequenceNode RBValueNode RBArrayNode RBAssignmentNode RBBlockNode RBCascadeNode RBLiteralNode RBMessageNode RBOptimizedNode RBVariableNode

© Oscar Nierstrasz ST — Working with Bytecode Compiler: Semantics  We need to analyse the AST —Names need to be linked to the variables according to the scoping rules  ASTChecker implemented as a Visitor —Subclass of RBProgramNodeVisitor —Visits the nodes —Grows and shrinks scope chain —Methods/Blocks are linked with the scope —Variable definitions and references are linked with objects describing the variables

© Oscar Nierstrasz ST — Working with Bytecode A Simple Tree RBParser parseExpression: '3+4' NB: explore it

© Oscar Nierstrasz ST — Working with Bytecode A Simple Visitor RBProgramNodeVisitor new visitNode: tree Does nothing except walk through the tree

© Oscar Nierstrasz ST — Working with Bytecode TestVisitor RBProgramNodeVisitor subclass: #TestVisitor instanceVariableNames: 'literals' classVariableNames: '' poolDictionaries: '' category: 'Compiler-AST-Visitors' TestVisitor>>acceptLiteralNode: aLiteralNode literals add: aLiteralNode value. TestVisitor>>initialize literals := Set new. TestVisitor>>literals ^literals tree := RBParser parseExpression: '3 + 4'. (TestVisitor new visitNode: tree) literals a Set(3 4)

© Oscar Nierstrasz ST — Working with Bytecode Compiler: Intermediate Representation  IR: Intermediate Representation —Semantic like Bytecode, but more abstract —Independent of the bytecode set —IR is a tree —IR nodes allow easy transformation —Decompilation to RB AST  IR is built from AST using ASTTranslator: —AST Visitor —Uses IRBuilder

© Oscar Nierstrasz ST — Working with Bytecode Compiler: Bytecode Generation  IR needs to be converted to Bytecode —IRTranslator: Visitor for IR tree —Uses BytecodeBuilder to generate Bytecode —Builds a compiledMethod —Details to follow next section testReturn1 | iRMethod aCompiledMethod | iRMethod := IRBuilder new numRargs: 1; addTemps: #(self);"receiver and args declarations" pushLiteral: 1; returnTop; ir. aCompiledMethod := iRMethod compiledMethod. self should: [(aCompiledMethod valueWithReceiver: nil arguments: #() ) = 1].

© Oscar Nierstrasz ST — Working with Bytecode Roadmap  The Pharo compiler  Introduction to Pharo bytecode  Generating bytecode with IRBuilder  Parsing and Interpreting bytecode

© Oscar Nierstrasz ST — Working with Bytecode Reasons for working with Bytecode  Generating Bytecode —Implementing compilers for other languages —Experimentation with new language features  Parsing and Interpretation: —Analysis (e.g., self and super sends) —Decompilation (for systems without source) —Printing of bytecode —Interpretation: Debugger, Profiler

© Oscar Nierstrasz ST — Working with Bytecode The Pharo Virtual Machine  Virtual machine provides a virtual processor —Bytecode: The “machine-code” of the virtual machine  Smalltalk (like Java): Stack machine —easy to implement interpreters for different processors —most hardware processors are register machines  Pharo VM: Implemented in Slang —Slang: Subset of Smalltalk. (“C with Smalltalk Syntax”) —Translated to C

© Oscar Nierstrasz ST — Working with Bytecode Bytecode in the CompiledMethod  CompiledMethod format: Number of temps, literals... Array of all Literal Objects Pointer to Source Header Literals Bytecode Trailer (Number methodDict at: #asInteger) inspect (Number>>#asInteger) inspect

© Oscar Nierstrasz ST — Working with Bytecode Bytecodes: Single or multibyte  Different forms of bytecodes: —Single bytecodes: – Example: 120: push self —Groups of similar bytecodes – 16: push temp 1 – 17: push temp 2 – up to 31 —Multibyte bytecodes – Problem: 4 bit offset may be too small – Solution: Use the following byte as offset – Example: Jumps need to encode large jump offsets TypeOffset 4 bits

© Oscar Nierstrasz ST — Working with Bytecode  Smalltalk code:  Symbolic Bytecode Example: Number>>asInteger Number>>asInteger "Answer an Integer nearest the receiver toward zero." ^self truncated 9 self 10 send: truncated 11 returnTop

© Oscar Nierstrasz ST — Working with Bytecode Example: Step by Step  9 self —The receiver (self) is pushed on the stack  10 send: truncated —Bytecode 208: send litereral selector 1 —Get the selector from the first literal —start message lookup in the class of the object that is on top of the stack —result is pushed on the stack  11 returnTop —return the object on top of the stack to the calling method

© Oscar Nierstrasz ST — Working with Bytecode Pharo Bytecode  256 Bytecodes, four groups: —Stack Bytecodes – Stack manipulation: push / pop / dup —Send Bytecodes – Invoke Methods —Return Bytecodes – Return to caller —Jump Bytecodes – Control flow inside a method

© Oscar Nierstrasz ST — Working with Bytecode Stack Bytecodes  Push values on the stack —e.g., temps, instVars, literals —e.g: : push instance variable  Push Constants —False/True/Nil/1/0/2/-1  Push self, thisContext  Duplicate top of stack  Pop

© Oscar Nierstrasz ST — Working with Bytecode Sends and Returns  Sends: receiver is on top of stack —Normal send —Super Sends —Hard-coded sends for efficiency, e.g. +, -  Returns —Return top of stack to the sender —Return from a block —Special bytecodes for return self, nil, true, false (for efficiency)

© Oscar Nierstrasz ST — Working with Bytecode  Control Flow inside one method —Used to implement control-flow efficiently —Example: Jump Bytecodes 9 pushConstant: 1 10 pushConstant: 2 11 send: < 12 jumpFalse: pushConstant: 'true' 14 jumpTo: pushConstant: nil 16 returnTop ^ 1<2 ifTrue: ['true']

© Oscar Nierstrasz ST — Working with Bytecode Closures

© Oscar Nierstrasz ST — Working with Bytecode Closures  Break the dependency between the block activation and its enclosing contexts for accessing locals

© Oscar Nierstrasz ST — Working with Bytecode Contexts inject: thisValue into: binaryBlock | nextValue | nextValue := thisValue. self

© Oscar Nierstrasz ST — Working with Bytecode Contexts inject: thisValue into: binaryBlock | indirectTemps | indirectTemps := Array new: 1. indirectTemps at: 1 put: thisValue. " was nextValue := thisValue." self do: [:each | indirectTemps at: 1 put: (binaryBlock value: (indirectTemps at: 1) value: each)]. ^indirectTemps at: 1

© Oscar Nierstrasz ST — Working with Bytecode Contexts inject: thisValue into: binaryBlock | indirectTemps | indirectTemps := Array new: 1. indirectTemps at: 1 put: thisValue. self do: (thisContext closureCopy: [:each | binaryBlockCopy indirectTempsCopy | indirectTempsCopy at: 1 put: (binaryBlockCopy value: (indirectTempsCopy at: 1) value: each)] copiedValues:

© Oscar Nierstrasz ST — Working with Bytecode  138 Push (Array new: k)/Pop k into: (Array new: j)  140 Push Temp At k In Temp Vector At: j  141 Store Temp At k In Temp Vector At: j  142 Pop and Store Temp At k In Temp Vector At: j  143 Push Closure Num Copied l Num Args k BlockSize j Closure Bytecode

© Oscar Nierstrasz ST — Working with Bytecode Roadmap  The Pharo compiler  Introduction to Pharo bytecode  Generating bytecode with IRBuilder  Parsing and Interpreting bytecode

© Oscar Nierstrasz ST — Working with Bytecode Generating Bytecode  IRBuilder: A tool for generating bytecode —Part of the NewCompiler —Pharo: Install packages AST, NewParser, NewCompiler  Like an Assembler for Pharo

© Oscar Nierstrasz ST — Working with Bytecode IRBuilder: Simple Example  Number>>asInteger iRMethod := IRBuilder new numRargs: 1; "receiver” addTemps: #(self); "receiver and args" pushTemp: #self; send: #truncated; returnTop; ir. aCompiledMethod := iRMethod compiledMethod. aCompiledMethod valueWithReceiver:3.5 arguments: #() 3

© Oscar Nierstrasz ST — Working with Bytecode IRBuilder: Stack Manipulation  popTop —remove the top of stack  pushDup —push top of stack on the stack  pushLiteral:  pushReceiver —push self  pushThisContext

© Oscar Nierstrasz ST — Working with Bytecode IRBuilder: Symbolic Jumps  Jump targets are resolved:  Example: iRMethod := IRBuilder new numRargs: 1; addTemps: #(self); "receiver" pushLiteral: false; jumpAheadTo: #false if: false; pushLiteral: 'true';"ifTrue: ['true']" jumpAheadTo: #end; jumpAheadTarget: #false; pushLiteral: 'false';"ifFalse: ['false']" jumpAheadTarget: #end; returnTop; ir. false ifTrue: [’true’] ifFalse: [’false’]

© Oscar Nierstrasz ST — Working with Bytecode IRBuilder: Instance Variables  Access by offset  Read: pushInstVar: —receiver on top of stack  Write: storeInstVar: —value on stack  Example: set the first instance variable to 2 iRMethod := IRBuilder new numRargs: 1; addTemps: #(self); "receiver and args" pushLiteral: 2; storeInstVar: 1; pushTemp: #self; returnTop; ir. aCompiledMethod := iRMethod compiledMethod. aCompiledMethod valueWithReceiver: arguments: #()

© Oscar Nierstrasz ST — Working with Bytecode IRBuilder: Temporary Variables  Accessed by name  Define with addTemp: / addTemps:  Read with pushTemp:  Write with storeTemp:  Example: —set variables a and b, return value of a iRMethod := IRBuilder new numRargs: 1; addTemps: #(self); "receiver" addTemps: #(a b); pushLiteral: 1; storeTemp: #a; pushLiteral: 2; storeTemp: #b; pushTemp: #a; returnTop; ir.

© Oscar Nierstrasz ST — Working with Bytecode  normal send  super send —The second parameter specifies the class where the lookup starts. IRBuilder: Sends builder pushLiteral: ‘hello’ builder send: #size; … builder send: #selector toSuperOf: aClass;

© Oscar Nierstrasz ST — Working with Bytecode Roadmap  The Pharo compiler  Introduction to Pharo bytecode  Generating bytecode with IRBuilder  Parsing and Interpreting bytecode

© Oscar Nierstrasz ST — Working with Bytecode Parsing and Interpretation  First step: Parse bytecode —enough for easy analysis, pretty printing, decompilation  Second step: Interpretation —needed for simulation, complex analyis (e.g., profiling)  Pharo provides frameworks for both: —InstructionStream/InstructionClient (parsing) —ContextPart (Interpretation)

© Oscar Nierstrasz ST — Working with Bytecode The InstructionStream Hierarchy InstructionStream ContextPart BlockContext MethodContext Decompiler InstructionPrinter InstVarRefLocator BytecodeDecompiler

© Oscar Nierstrasz ST — Working with Bytecode InstructionStream  Parses the byte-encoded instructions  State: —pc: program counter —sender: the method (bad name!) Object subclass: #InstructionStream instanceVariableNames: 'sender pc' classVariableNames: 'SpecialConstants' poolDictionaries: '' category: 'Kernel-Methods'

© Oscar Nierstrasz ST — Working with Bytecode  Generate an instance:  Now we can step through the bytecode with:  Calls methods on a client object for the type of bytecode, e.g. —pushReceiver —pushConstant: value —pushReceiverVariable: offset Usage instrStream := InstructionStream on: aMethod instrStream interpretNextInstructionFor: client

© Oscar Nierstrasz ST — Working with Bytecode InstructionClient  Abstract superclass —Defines empty methods for all methods that InstructionStream calls on a client  For convenience: —Clients don’t need to inherit from this class Object subclass: #InstructionClient instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Kernel-Methods'

© Oscar Nierstrasz ST — Working with Bytecode Example: A test InstructionClientTest>>testInstructions "just interpret all of methods of Object" | methods client scanner| methods := Object methodDict values. client := InstructionClient new. methods do: [:method | scanner := (InstructionStream on: method). [scanner pc <= method endPC] whileTrue: [ self shouldnt: [scanner interpretNextInstructionFor: client] raise: Error. ].

© Oscar Nierstrasz ST — Working with Bytecode Example: Printing Bytecode  InstructionPrinter: —Print the bytecodes as human readable text  Example: —print the bytecode of Number>>asInteger: String streamContents: [:str | (InstructionPrinter on: Number>>#asInteger) printInstructionsOn: str ] '9 self 10 send: truncated 11 returnTop '

© Oscar Nierstrasz ST — Working with Bytecode InstructionPrinter  Class Definition: InstructionClient subclass: #InstructionPrinter instanceVariableNames: 'method scanner stream indent' classVariableNames: '' poolDictionaries: '' category: 'Kernel-Methods'

© Oscar Nierstrasz ST — Working with Bytecode InstructionPrinter  Main Loop: InstructionPrinter>>printInstructionsOn: aStream "Append to the stream, aStream, a description of each bytecode in the instruction stream." | end | stream := aStream. scanner := InstructionStream on: method. end := method endPC. [scanner pc <= end] whileTrue: [scanner interpretNextInstructionFor: self]

© Oscar Nierstrasz ST — Working with Bytecode InstructionPrinter  Overwrites methods from InstructionClient to print the bytecodes as text  e.g. the method for pushReceiver InstructionPrinter>>pushReceiver "Print the Push Active Context's Receiver on Top Of Stack bytecode." self print: 'self'

© Oscar Nierstrasz ST — Working with Bytecode Example: InstVarRefLocator InstructionClient subclass: #InstVarRefLocator instanceVariableNames: 'bingo' classVariableNames: '' poolDictionaries: '' category: 'Kernel-Methods' InstVarRefLocator>>interpretNextInstructionUsing: aScanner bingo := false. aScanner interpretNextInstructionFor: self. ^bingo InstVarRefLocator>>popIntoReceiverVariable: offset bingo := true InstVarRefLocator>>pushReceiverVariable: offset bingo := true InstVarRefLocator>>storeIntoReceiverVariable: offset bingo := true

© Oscar Nierstrasz ST — Working with Bytecode InstVarRefLocator  Analyse a method, answer true if it references an instance variable CompiledMethod>>hasInstVarRef "Answer whether the receiver references an instance variable." | scanner end printer | scanner := InstructionStream on: self. printer := InstVarRefLocator new. end := self endPC. [scanner pc <= end] whileTrue: [ (printer interpretNextInstructionUsing: scanner) ifTrue: [^true]. ]. ^false

© Oscar Nierstrasz ST — Working with Bytecode InstVarRefLocator  Example for a simple bytecode analyzer  Usage:  (has reference to variable testSelector)  (has no reference to a variable) aMethod hasInstVarRef (TestCase>>#debug) hasInstVarRef (Integer>>#+) hasInstVarRef true false

© Oscar Nierstrasz ST — Working with Bytecode ContextPart: Semantics for Execution  Sometimes we need more than parsing —“stepping” in the debugger —system simulation for profiling InstructionStream subclass: #ContextPart instanceVariableNames: 'stackp' classVariableNames: 'PrimitiveFailToken QuickStep' poolDictionaries: '' category: 'Kernel-Methods'

© Oscar Nierstrasz ST — Working with Bytecode Simulation  Provides a complete Bytecode interpreter  Run a block with the simulator: (ContextPart runSimulated: [3 factorial]) 6

© Oscar Nierstrasz ST — Working with Bytecode Profiling: MessageTally  Usage:  Other example: MessageTally tallySends: [3 factorial] MessageTally tallySends: [’3’ + 1] This simulation took 0.0 seconds. **Tree** 1 SmallInteger(Integer)>>factorial

© Oscar Nierstrasz ST — Working with Bytecode What you should know!  What are the problems of the old compiler?  How is the new Pharo compiler organized?  What does the Pharo semantic analyzer add to the parser-generated AST?  What is the format of the intermediate representation?  What kind of virtual machine does the Pharo bytecode address?  How can you inspect the bytecode of a particular method?

© Oscar Nierstrasz ST — Working with Bytecode Can you answer these questions?  What different groups of bytecode are supported?  Why is the SmaCC grammar only BNF-“like”?  How can you find out what all the bytecodes are?  What is the purpose of IRBuilder?  Why do we not generate bytecode directly?  What is the responsibility of class InstructionStream?  How would you implement a statement coverage analyzer?

© Oscar Nierstrasz ST — Introduction 1.62 Attribution-ShareAlike 3.0 Unported You are free: to Share — to copy, distribute and transmit the work to Remix — to adapt the work Under the following conditions: Attribution. You must attribute the work in the manner specified by the author or licensor (but not in any way that suggests that they endorse you or your use of the work). Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under the same, similar or a compatible license. For any reuse or distribution, you must make clear to others the license terms of this work. The best way to do this is with a link to this web page. Any of the above conditions can be waived if you get permission from the copyright holder. Nothing in this license impairs or restricts the author's moral rights. License