88
Opal Compiler Jorge Ressia Thursday, March 10, 2011

Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

  • Upload
    others

  • View
    4

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Opal Compiler

Jorge Ressia

Thursday, March 10, 2011

Page 2: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Roadmap

> The Pharo compiler> Introduction to Smalltalk bytecode> Generating bytecode with IRBuilder> ByteSurgeon

Original material by Marcus Denker

2

Thursday, March 10, 2011

Page 3: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Roadmap

> The Pharo compiler> Introduction to Smalltalk bytecode> Generating bytecode with IRBuilder> ByteSurgeon

3

Thursday, March 10, 2011

Page 4: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

The Pharo Compiler

> Default compiler— very old design — quite hard to understand— hard to modify and extend

4

Thursday, March 10, 2011

Page 5: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

© Oscar Nierstrasz

What qualities are important in a compiler?

> Correct code > Output runs fast > Compiler runs fast > Compile time proportional to program size > Support for separate compilation > Good diagnostics for syntax errors > Works well with the debugger > Good diagnostics for flow anomalies > Consistent, predictable optimization

5

Thursday, March 10, 2011

Page 6: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Why do we care?

> ByteSurgeon — Runtime Bytecode Transformation for Smalltalk

> ChangeBoxes — Modeling Change as a first-class entity> Reflectivity — Persephone, Geppetto and the rest> Helvetia — Context Specific Languages with

Homogeneous Tool Integration> Albedo — A unified approach to reflection.

6

Thursday, March 10, 2011

Page 7: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Opal Compiler

> Opal Compiler for Pharo— http://scg.unibe.ch/research/OpalCompiler

7

Thursday, March 10, 2011

Page 8: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Opal Compiler

> Fully reified compilation process:— Scanner/Parser (RBParser)

– builds AST (from Refactoring Browser)— Semantic Analysis: OCASTSemanticAnalyzer

– annotates the AST (e.g., var bindings)— Translation to IR: OCASTTranslator

– uses IRBuilder to build IR (Intermediate Representation) — Bytecode generation: IRTranslator

– uses OCBytecodeGenerator to emit bytecodes

8

Thursday, March 10, 2011

Page 9: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Compiler: Overview

code AST ASTScanner/ Parser

SemanticAnalysis BytecodeCode

Generation

AST IRBuildIR BytecodeBytecode

Generation

OCASTTranslatorIRBuilder

IRTranslatorOCBytecodeGenerator

Code generation in detail

9

Thursday, March 10, 2011

Page 10: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Compiler: Design Decisions

> Every building block of the compiler is implemented as a visitor on the representation.

> The AST is never changed

10

Thursday, March 10, 2011

Page 11: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Compiler: AST

> AST: Abstract Syntax Tree— Encodes the Syntax as a Tree— No semantics yet! — Uses the RB Tree:

– Visitors– Transformation (replace/add/delete)– Pattern-directed TreeRewriter – PrettyPrinter

RBProgramNode! RBDoItNode! RBMethodNode! RBReturnNode! RBSequenceNode! RBValueNode! ! RBArrayNode! ! RBAssignmentNode! ! RBBlockNode! ! RBCascadeNode! ! RBLiteralNode! ! RBMessageNode! ! RBOptimizedNode! ! RBVariableNode

11

Thursday, March 10, 2011

Page 12: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Compiler: Syntax

> Before: SmaCC: Smalltalk Compiler Compiler— Similar to Lex/Yacc— SmaCC can build LARL(1) or LR(1) parser

> Now: RBParser

> Future: PetitParser

12

Thursday, March 10, 2011

Page 13: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

A Simple Tree

RBParser parseExpression: '3+4' NB: explore it

15

Thursday, March 10, 2011

Page 14: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

A Simple Visitor

RBProgramNodeVisitor new visitNode: tree

Does nothing except walk through the tree

16

Thursday, March 10, 2011

Page 15: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

TestVisitorRBProgramNodeVisitor 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)17

Thursday, March 10, 2011

Page 16: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Compiler: Semantics

> We need to analyze the AST— Names need to be linked to the variables according to the

scoping rules

> OCASTSemanticAnalyzer 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

13

Thursday, March 10, 2011

Page 17: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Scope Analysis

testBlockTemp! | block block1 block2 |! block := [ :arg | [ arg ] ].! block1 := block value: 1.! block2 := block value: 2.

17

Thursday, March 10, 2011

Page 18: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Scope Analysis

testBlockTemp! | block block1 block2 |! block := [ :arg | [ arg ] ].! block1 := block value: 1.! block2 := block value: 2.

17

OCClassScopeOCInstanceScopeOCMethodScope 2OCBlockScope 3OCBlockScope 4

Thursday, March 10, 2011

Page 19: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Compiler: Semantics

> OCASTClosureAnalyzer— Eliotʼs Closure analysis: copying vs. tempvector

14

Thursday, March 10, 2011

Page 20: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Closures

counterBlock        | count |        count := 0.        ^[ count := count + 1].

31

Thursday, March 10, 2011

Page 21: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Closures

> Break the dependency between the block activation and its enclosing contexts for accessing locals

32

Thursday, March 10, 2011

Page 22: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Contexts

inject: thisValue into: binaryBlock! | nextValue |  nextValue := thisValue.  self ! ! do: [:each | ! ! ! ! nextValue := binaryBlock ! ! ! ! ! ! ! ! value: nextValue value: each].

  ^nextValue

33

Thursday, March 10, 2011

Page 23: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

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

34

Thursday, March 10, 2011

Page 24: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

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: !!!!!! (Array with: binaryBlock with: indirectTemps)). ^indirectTemps at: 1

35

Thursday, March 10, 2011

Page 25: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Closures Analysis

! | a |! a := 1.! [ a ]

17

Thursday, March 10, 2011

Page 26: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Closures Analysis

! | a |! a := 1.! [ a ]

17

a is copied

Thursday, March 10, 2011

Page 27: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Closures Analysis

! | index block collection |! index := 0.! block := [ ! ! collection add: [ index ].! ! index := index + 1 ].! [ index < 5 ] whileTrue: block.

17

Thursday, March 10, 2011

Page 28: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Closures Analysis

! | index block collection |! index := 0.! block := [ ! ! collection add: [ index ].! ! index := index + 1 ].! [ index < 5 ] whileTrue: block.

17

index is remote

Thursday, March 10, 2011

Page 29: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

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 OCASTTranslator: — AST Visitor— Uses IRBuilder

18

Thursday, March 10, 2011

Page 30: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Compiler: Intermediate Representation

! IRBuilder new! ! pushLiteral: 34;! ! storeInstVar: 2;! ! popTop;! ! pushInstVar: 2;! ! returnTop;! ! ir.

17

17 <20> pushConstant: 3418 <61> popIntoRcvr: 119 <01> pushRcvr: 120 <7C> returnTop

Thursday, March 10, 2011

Page 31: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Compiler: Bytecode Generation

> IR needs to be converted to Bytecode — IRTranslator: Visitor for IR tree— Uses OCBytecodeGenerator to generate Bytecode— Builds a compiledMethod — Details to follow next section

testReturn1! | iRMethod aCompiledMethod |! iRMethod := IRBuilder new! ! pushLiteral: 1;!! ! !! ! returnTop;! ! ir.

aCompiledMethod := iRMethod compiledMethod.self should:! [(aCompiledMethod! ! valueWithReceiver: nil! ! arguments: #() ) = 1].

19

Thursday, March 10, 2011

Page 32: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Roadmap

> The Pharo compiler> Introduction to Smalltalk bytecode> Generating bytecode with IRBuilder> ByteSurgeon

20

Thursday, March 10, 2011

Page 33: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

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

21

Thursday, March 10, 2011

Page 34: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

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

> Squeak VM: Implemented in Slang — Slang: Subset of Smalltalk. (“C with Smalltalk Syntax”)— Translated to C

22

Thursday, March 10, 2011

Page 35: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Bytecode in the CompiledMethod

> CompiledMethod format:

Number of temps, literals...

Array of all Literal Objects

Pointer toSource

Header

Literals

Bytecode

Trailer

(Number methodDict at: #asInteger) inspect

(Number>>#asInteger) inspect

23

Thursday, March 10, 2011

Page 36: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

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

Type Offset4 bits 4 bits

24

Thursday, March 10, 2011

Page 37: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

> Smalltalk code:

> Symbolic Bytecode

Example: Number>>asInteger

Number>>asInteger! "Answer an Integer nearest! the receiver toward zero."

! ^self truncated

9 <70> self10 <D0> send: truncated11 <7C> returnTop

25

Thursday, March 10, 2011

Page 38: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Example: Step by Step

> 9 <70> self— The receiver (self) is pushed on the stack

> 10 <D0> 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 <7C> returnTop— return the object on top of the stack to the calling method

26

Thursday, March 10, 2011

Page 39: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

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

27

Thursday, March 10, 2011

Page 40: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Stack Bytecodes

> Push values on the stack— e.g., temps, instVars, literals— e.g: 16 - 31: push instance variable

> Push Constants— False/True/Nil/1/0/2/-1

> Push self, thisContext> Duplicate top of stack> Pop

28

Thursday, March 10, 2011

Page 41: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

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)

29

Thursday, March 10, 2011

Page 42: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

> Control Flow inside one method— Used to implement control-flow efficiently— Example:

Jump Bytecodes

9 <76> pushConstant: 110 <77> pushConstant: 211 <B2> send: <12 <99> jumpFalse: 1513 <20> pushConstant: 'true'14 <90> jumpTo: 1615 <73> pushConstant: nil16 <7C> returnTop

^ 1<2 ifTrue: ['true']

30

Thursday, March 10, 2011

Page 43: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

> 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

36

Thursday, March 10, 2011

Page 44: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Roadmap

> The Pharo compiler> Introduction to Smalltalk bytecode> Generating bytecode with IRBuilder> ByteSurgeon

37

Thursday, March 10, 2011

Page 45: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Generating Bytecode

> IRBuilder: A tool for generating bytecode— Part of the OpalCompiler

> Like an Assembler for Pharo

38

Thursday, March 10, 2011

Page 46: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

IRBuilder: Simple Example

> Number>>asInteger

iRMethod := IRBuilder new! pushReceiver; ! "push self"! send: #truncated;! returnTop;! ir.

aCompiledMethod := iRMethod compiledMethod.

aCompiledMethod valueWithReceiver:3.5! ! ! ! ! ! arguments: #()

3

39

Thursday, March 10, 2011

Page 47: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

IRBuilder: Stack Manipulation

> popTop— remove the top of stack

> pushDup— push top of stack on the stack

> pushLiteral: > pushReceiver

— push self> pushThisContext

40

Thursday, March 10, 2011

Page 48: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

IRBuilder: Symbolic Jumps

> Jump targets are resolved: > Example:

iRMethod := IRBuilder new! 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’]

41

Thursday, March 10, 2011

Page 49: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

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! ! pushLiteral: 2;! ! storeInstVar: 1;! ! pushReceiver; "self"! ! returnTop;! ! ir.! !aCompiledMethod := iRMethod compiledMethod.aCompiledMethod valueWithReceiver: 1@2 arguments: #()

2@2

42

Thursday, March 10, 2011

Page 50: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

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! ! addTemps: #(a b);! ! pushLiteral: 1;!! ! storeTemp: #a;! ! pushLiteral: 2;!! ! storeTemp: #b;! ! pushTemp: #a;! ! returnTop;! ! ir.

43

Thursday, March 10, 2011

Page 51: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

> 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;

44

Thursday, March 10, 2011

Page 52: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

IRBuilder: Example

OCInstanceVar>>emitStore: methodBuilder! methodBuilder storeInstVar: index

41

Thursday, March 10, 2011

Page 53: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

IRBuilder: Example

OCInstanceVar>>emitStore: methodBuilder! methodBuilder

pushReceiver;pushLiteral: index;send: #instVarAt

41

Thursday, March 10, 2011

Page 54: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

IRBuilder: Example

OCInstanceVar>>emitStore: methodBuilder! methodBuilder

pushReceiver;pushLiteral: index;send: #instVarAt:

41

This is global and we do not have much control

Thursday, March 10, 2011

Page 55: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Roadmap

> The Pharo compiler> Introduction to Pharo bytecode> Generating bytecode with IRBuilder> ByteSurgeon

45

Thursday, March 10, 2011

Page 56: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

ByteSurgeon

> Library for bytecode transformation in Smalltalk> Full flexibility of Smalltalk Runtime > Provides high-level API > For Pharo, but portable

> Runtime transformation needed for — Adaptation of running systems — Tracing / debugging — New language features (MOP, AOP)

46

Thursday, March 10, 2011

Page 57: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Example: Logging

> Goal: logging message send.> First way: Just edit the text:

47

Thursday, March 10, 2011

Page 58: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Logging with ByteSurgeon

> Goal: Change the method without changing program text

> Example:

48

Thursday, March 10, 2011

Page 59: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Logging: Step by Step

49

Thursday, March 10, 2011

Page 60: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Logging: Step by Step

> instrumentSend: — takes a block as an argument — evaluates it for all send bytecodes

50

Thursday, March 10, 2011

Page 61: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Logging: Step by Step

> The block has one parameter: send > It is executed for each send bytecode in the method

51

Thursday, March 10, 2011

Page 62: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Logging: Step by Step

> Objects describing bytecode understand how to insert code — insertBefor — insertAfter — replace

52

Thursday, March 10, 2011

Page 63: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Logging: Step by Step

> The code to be inserted.> Double quoting for string inside string

– Transcript show: ʼsending #testʼ

53

Thursday, March 10, 2011

Page 64: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Inside ByteSurgeon

> Uses IRBuilder internally

> Transformation (Code inlining) done on IR

54

Thursday, March 10, 2011

Page 65: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

ByteSurgeon Usage

> On Methods or Classes:

> Different instrument methods: — instrument: — instrumentSend: — instrumentTempVarRead:— instrumentTempVarStore: — instrumentTempVarAccess: — same for InstVar

55

Thursday, March 10, 2011

Page 66: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Advanced ByteSurgeon

> Goal: extend a send with after logging

56

Thursday, March 10, 2011

Page 67: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Advanced ByteSurgeon

> With ByteSurgeon, something like:

> How can we access the receiver of the send? > Solution: Metavariable

57

Thursday, March 10, 2011

Page 68: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Advanced ByteSurgeon

> With Bytesurgeon, something like:

> How can we access the receiver of the send? > Solution: Metavariable

58

Thursday, March 10, 2011

Page 69: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Implementation Metavariables

> Stack during send:

> Problem I: After send, receiver is not available> Problem II: Before send, receiver is deep in the stack

59

Thursday, March 10, 2011

Page 70: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Implementation Metavariables

> Solution: ByteSurgeon generates preamble— Pop the arguments into temps — Pop the receiver into temps — Rebuild the stack — Do the send— Now we can access the receiver even after the send

60

Thursday, March 10, 2011

Page 71: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Implementation Metavariables

61

Thursday, March 10, 2011

Page 72: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Why do we care?

> Helvetia — Context Specific Languages with Homogeneous Tool Integration

> Reflectivity — Unanticipated partial behavioral reflection.

> Albedo — A unified approach to reflection.

6

Thursday, March 10, 2011

Page 73: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Helvetia

6

Rules

<parse> <transform> <attribute>

SourceCode

SmalltalkParser

SemanticAnalysis

BytecodeGenerator

ExecutableCode

Traditional Smalltalk Compiler

Pidgin

CreoleArgot

Thursday, March 10, 2011

Page 74: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Helvetia

6

Rules

<parse> <transform> <attribute>

SourceCode

SmalltalkParser

SemanticAnalysis

BytecodeGenerator

ExecutableCode

Traditional Smalltalk Compiler

Pidgin

CreoleArgot

Thursday, March 10, 2011

Page 75: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Helvetia

6

Rules

<parse> <transform> <attribute>

SourceCode

SmalltalkParser

SemanticAnalysis

BytecodeGenerator

ExecutableCode

Traditional Smalltalk Compiler

Pidgin

CreoleArgot

Thursday, March 10, 2011

Page 76: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Helvetia

6

Rules

<parse> <transform> <attribute>

SourceCode

SmalltalkParser

SemanticAnalysis

BytecodeGenerator

ExecutableCode

Traditional Smalltalk Compiler

Pidgin

CreoleArgot

Thursday, March 10, 2011

Page 77: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Helvetia

6

HelvetiaRenggli 2010

Rules

<parse> <transform> <attribute>

SourceCode

SmalltalkParser

SemanticAnalysis

BytecodeGenerator

ExecutableCode

Traditional Smalltalk Compiler

Pidgin

CreoleArgot

Thursday, March 10, 2011

Page 78: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Reflectivity

6

source code

(AST)

meta-object

activation

condition

links

Thursday, March 10, 2011

Page 79: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Reflectivity

6

source code

(AST)

meta-object

activation

condition

links

Thursday, March 10, 2011

Page 80: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Reflectivity

6

source code

(AST)

meta-object

activation

condition

links

Thursday, March 10, 2011

Page 81: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Reflectivity

6

source code

(AST)

meta-object

activation

condition

links

Thursday, March 10, 2011

Page 82: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Reflectivity

6

source code

(AST)

meta-object

activation

condition

links

Reflectivity

Denker 2008

Thursday, March 10, 2011

Page 83: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Albedo

6

Source code(AST)

Meta-objects

Thursday, March 10, 2011

Page 84: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Albedo

6

Source code(AST)

Meta-objects

Thursday, March 10, 2011

Page 85: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Albedo

6

Source code(AST)

Meta-objects

Thursday, March 10, 2011

Page 86: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Albedo

6

Source code(AST)

Meta-objects

Thursday, March 10, 2011

Page 87: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Albedo

6

AlbedoRessia 2010

Source code(AST)

Meta-objects

Thursday, March 10, 2011

Page 88: Opal Compiler - Inria€¦ · Roadmap > The Pharo compiler > Introduction to Smalltalk bytecode > Generating bytecode with IRBuilder > ByteSurgeon Original material by Marcus Denker

Opal Compiler

64

http://scg.unibe.ch/research/OpalCompiler

Thursday, March 10, 2011