#Pharo Days 2016 Reflectivity

56
Reflection in Pharo: Beyond Smalltak Marcus Denker http://www.pharo.org

Transcript of #Pharo Days 2016 Reflectivity

Page 1: #Pharo Days 2016 Reflectivity

Reflection in Pharo: Beyond SmalltakMarcus Denker http://www.pharo.org

Page 2: #Pharo Days 2016 Reflectivity

Everything is an Object

Page 3: #Pharo Days 2016 Reflectivity

Classes

Page 4: #Pharo Days 2016 Reflectivity

Methods

Page 5: #Pharo Days 2016 Reflectivity

The Stack

Page 6: #Pharo Days 2016 Reflectivity

Everything is an Object

Page 7: #Pharo Days 2016 Reflectivity

Code?

Page 8: #Pharo Days 2016 Reflectivity

AST: Abstract Syntax Tree

Page 9: #Pharo Days 2016 Reflectivity

AST in Pharo5• AST of the Refactoring browser

• Transformation

• Visitors

• Annotations (properties)

• Deeper integrated:

• Pretty Printing, Syntax Highlight, Suggestions

• Compiler uses RB AST

Page 10: #Pharo Days 2016 Reflectivity

AST in Pharo5

• Easy access

• #ast

• Demo: method and block

Page 11: #Pharo Days 2016 Reflectivity

DEMO

(OrderedCollection>>#do:) ast.

[ 1 + 2 ] sourceNode == thisContext method ast blockNodes first

• ASTCache: as twice, get the same answer (flushed on image save for now)

Page 12: #Pharo Days 2016 Reflectivity

AST + Tools

Page 13: #Pharo Days 2016 Reflectivity

Opal Compiler

• Uses RB AST

• Based on Visitors

Text AST AST+vars IR CM

Parser Semantic Analysis

AST Translator+ IRBuilder

BytecodeBuilder+ Encoder

Page 14: #Pharo Days 2016 Reflectivity

Opal: API

• All staged are Pluggable

• e.g Semantic Analyzer or Code Generator can be changed.

• compiler options

Page 15: #Pharo Days 2016 Reflectivity

Opal: Bytecode editing

• IR can be used to manipulate methods on a bytecode level

Text AST AST+vars IR CM

Parser Semantic Analysis

AST Translator+ IRBuilder

BytecodeBuilder+ Encoder

Page 16: #Pharo Days 2016 Reflectivity

Too complicated

Page 17: #Pharo Days 2016 Reflectivity

Too low level

Page 18: #Pharo Days 2016 Reflectivity

Can we do better?

Page 19: #Pharo Days 2016 Reflectivity

AST Meta Annotation

• We have an AST with properties

• We have Opal with Pluggable API

Page 20: #Pharo Days 2016 Reflectivity

Can’t we use that?

Page 21: #Pharo Days 2016 Reflectivity

Basis: the Evil Twin

CompiledMethod ReflectiveMethod

Know each other

Bytecode AST

Page 22: #Pharo Days 2016 Reflectivity

Basis: the Evil Twin

ReflectiveMethod

AST

run: aSelector with: anArray in: aReceiver self installCompiledMethod. self recompileAST. self installCompiledMethod. ^compiledMethod

valueWithReceiver: aReceiver arguments: anArray

Page 23: #Pharo Days 2016 Reflectivity

Demo: Morph

• Morph methods do: #createTwin

• Morph methods do: #invalidate

• inspect “Morph methods”

Page 24: #Pharo Days 2016 Reflectivity

Putting it together

• Annotate the AST

• Create Twin if needed

• Invalidate method

• Next call: generate code changed by annotation

Page 25: #Pharo Days 2016 Reflectivity

Annotations?

Page 26: #Pharo Days 2016 Reflectivity

MetaLink

Page 27: #Pharo Days 2016 Reflectivity

DEMO: Simple Linknode := (ReflectivityExamples>>#exampleMethod) ast. link := MetaLink new metaObject: (Object new); selector: #halt.

node link: link.

ReflectivityExamples new exampleMethod

Page 28: #Pharo Days 2016 Reflectivity

Meta Link

• When setting link:

• create twin if needed

• install reflective method

• On execution

• generate code and execute, install CM

Page 29: #Pharo Days 2016 Reflectivity

Twin Switch

CompiledMethod ReflectiveMethod

Know each other

Bytecode AST

Page 30: #Pharo Days 2016 Reflectivity

Link: metaobject

The object to send a message to

link := MetaLink new metaObject: [self halt]

Page 31: #Pharo Days 2016 Reflectivity

Link: selector

The selector to send

link := MetaLink new ….. selector: #value

Page 32: #Pharo Days 2016 Reflectivity

Link: control

before, after, instead

link := MetaLink new ….. control: #after

Page 33: #Pharo Days 2016 Reflectivity

Link: control

after: #ensure: wrap

link := MetaLink new ….. control: #after

Page 34: #Pharo Days 2016 Reflectivity

Link: control

instead: last link wins (for now no AOP around)

link := MetaLink new ….. control: #instead

Page 35: #Pharo Days 2016 Reflectivity

Link: condition

boolean or block

link := MetaLink new ….. condition: [self someCheck]

Page 36: #Pharo Days 2016 Reflectivity

Link: arguments

what to pass to the meta?

Page 37: #Pharo Days 2016 Reflectivity

Reifications

• Every operation has data that it works on

• Send: #arguments, #receiver, #selector

• Assignment: #newValue, #name

• All: #node, #object, #context

Page 38: #Pharo Days 2016 Reflectivity

Link: arguments

what to pass to the meta?

link := MetaLink new ….. arguments: #(name newValue)

Page 39: #Pharo Days 2016 Reflectivity

Reifications: condition

link := MetaLink new condition: [: object | object == 1];

Page 40: #Pharo Days 2016 Reflectivity

Virtual meta

• Reifications can be the meta object

link := MetaLink new metaObject: #receiver; selector: #perform:withArguments:; arguments: #(selector arguments).

Page 41: #Pharo Days 2016 Reflectivity

Statement Coverage

link := MetaLink new metaObject: #node; selector: #tagExecuted.

“set this link on all the AST nodes" (ReflectivityExamples>>#exampleMethod) ast

nodesDo: [:node | node link: link].

Page 42: #Pharo Days 2016 Reflectivity

Users

• BreakPoints Pharo5

• Coverage Kernel

• ….

Page 43: #Pharo Days 2016 Reflectivity

Everything is an Object

Page 44: #Pharo Days 2016 Reflectivity

Everything is an object?

SmalltalkImage classVarNamed: #CompilerClass ==> returns value

Object binding class ==> Association

Page 45: #Pharo Days 2016 Reflectivity

Why not an Object?

Page 46: #Pharo Days 2016 Reflectivity

Globals/ClassVariables

• We are close: bindings are associations

• Add sublass “LiteralVariable”

• Sublasses GlobalVariable, ClassVariable

• Enhance API

Page 47: #Pharo Days 2016 Reflectivity

Globals/ClassVariables

SmalltalkImage classVariableNamed: #CompilerClass

Object binding class

Page 48: #Pharo Days 2016 Reflectivity

Globals: Reflective APiglobal := SmalltalkImage classVariableNamed: #CompilerClass

global read global write: someObject

+ helper methods + compatibility methods

Page 49: #Pharo Days 2016 Reflectivity

Everything is an object?

• Point instanceVariables

• 5@3 instVarNamed: ‘x’

• 5@3 instVarNamed: ‘y’ put: 6

Page 50: #Pharo Days 2016 Reflectivity

Why not an Object?

Page 51: #Pharo Days 2016 Reflectivity

Slots

Point slots

(Point slotNamed: #x) read: (3@4)

(Point slotNamed: #x) write: 7 to: (3@4)

Page 52: #Pharo Days 2016 Reflectivity

Variables+MetaLink

• Helper methods

• But: can’t we annotate variables directly?

Point assignmentNodes

Page 53: #Pharo Days 2016 Reflectivity

Variables + Links

• Object binding link: myMetaLink

• (Point slotNamed: #x) link: myMetaLink

(not yet in Pharo5)

Page 54: #Pharo Days 2016 Reflectivity

Class Template

Object subclass: #MyClass slots: { #x => WeakSlot } classVariables: { } category: 'Example'

Page 55: #Pharo Days 2016 Reflectivity

Future

• Can’t we model bit patterns and bind them to named virtual slots?

• How to model Array-like layouts better?

Page 56: #Pharo Days 2016 Reflectivity

Questions ?