20
University of Oviedo Computer Science Department Francisco Ortin Juan Manuel Cueva The nitrO Reflective The nitrO Reflective Platform Platform International Conference International Conference on Software Engineering on Software Engineering Research and Practice Research and Practice (SERP) (SERP) Session on Adaptable Session on Adaptable Software Architectures Software Architectures (ASA) (ASA)

University of Oviedo Computer Science Department Francisco OrtinJuan Manuel Cueva The nitrO Reflective Platform International Conference on Software Engineering

  • View
    215

  • Download
    1

Embed Size (px)

Citation preview

University of Oviedo Computer Science Department

Francisco OrtinJuan Manuel Cueva

The nitrO Reflective PlatformThe nitrO Reflective Platform

International Conference on International Conference on Software Engineering Research Software Engineering Research

and Practice (SERP)and Practice (SERP)

Session on Adaptable Software Session on Adaptable Software Architectures (ASA)Architectures (ASA)

Francisco OrtinJuan Manuel Cueva

AdaptabilityAdaptability

• Adaptable software systems and architectures give the programmer the ability to create applications that might be customized to runtime-emerging requirements (unpredictable at design time)

• An adaptable platform should give its applications the opportunity to customize their structure and behavior at runtime

Francisco OrtinJuan Manuel Cueva

ReflectionReflection

• Reflection is a programming language technique that achieves dynamic application adaptability

• Taking what system’s feature can be customized as a classification criterion, we can distinguish:

Introspection: Application’s structure might be inspected but not modified (e.g. Java reflect package used in the JavaBeans architecture)

Structural Reflection: Application’s structure might be inspected as well as modified (e.g. Smalltalk and Python ability to modify objects’ structure at runtime)

Computational Reflection: The whole system semantics can be adapted (e.g. modifying the message passing mechanism to create a system’s logger)

Francisco OrtinJuan Manuel Cueva

Meta-Object ProtocolsMeta-Object Protocols

• Most runtime computational-reflective systems are based on Meta-Object Protocols (MOP)

• A MOP specifies the way an application (base level) may access its object-model implementation (meta-level) in order to adapt its behavior and structure at runtime

Interpreter

Runs

User ObjectsUser’sApplication

SemanticsOverriding

Meta-ObjectProtocol

Meta-Object

BaseLevel

Meta-Level

MetaXaExample

MetaObject

attachObject(Object)eventMethodEnter()

System class used to modify the applications semantics

Trace Trace class that overrides the message- passing mechanism

Attaching objects to the meta-object (attachObject) implies behavior adaptation

Francisco OrtinJuan Manuel Cueva

MOP RestrictionsMOP Restrictions

1. The way a MOP is defined restricts the way amount of features that can be customized: if the is not a “create object” meta-object, we will not be able to adapt this system behavior

2. Enhancing the MOP implies different interpreter and language versions Previous code could result deprecated

3. System semantics customization is expressed by method overriding: a richer mechanism to express the adaptation would be needed

4. Meta-level and base-level programming language are the same: the do not offer runtime adaptability in a language-independent way

Francisco OrtinJuan Manuel Cueva

Theoretical ConceptTheoretical Concept

• The theoretical concept of reflection uses the notion of a reflective tower of interpreters:

An interpreter (hardware or software) runs an application

A reflective computation is a computation about its computation: a computation that accesses the interpreter

• If the application would be able to access its interpreter at runtime, it would

Inspect its running objects Introspection Modify its own structure Structural Reflection Customize the language semantics

Computational Reflection

Francisco OrtinJuan Manuel Cueva

System ArchitectureSystem Architecture

• We have developed a Generic Interpreter that: Is capable of interpreting any programming

language by previously reading its specification Separates every language-specific representation

from the interpreter implementation (grammar and semantics)

Separates every application structure from the interpreter implementation (dynamic application’s symbol-table)

Gives the programmer the ability to access every: Application Structure Programming Language Specification

Francisco OrtinJuan Manuel Cueva

System ArchitectureSystem Architecture

GenericInterpreter

Application = “Sample App”Language = “Sample Lang”

Class MyClass {// * App code...

}

User’s Application

1) A user program is about to be run

...

SampleLang.ML

2) The language specification file is found in the system

Language-SpecificationObjects Structure

3) The language specification is translated into a objects structure

4) The user’s application starts running

6) If the application reads its symbol-table, introspection is achieved

7) If the application modifies its symbol-table, structural reflection is achieved

8) If the application modifies the language semantics, computational reflection is achieved

5) While the application is running, a symbol-table is used by the interpreter

Application’sSymbol-Table

Francisco OrtinJuan Manuel Cueva

Computational JumpComputational Jump

• How can an application access to its interpreter computational environment?

• We have selected the Python programming language to implement the nitrO platform because of its:

Introspection capabilities: At runtime, the every application may inspect its variables, objects, attributes, methods and modules

Structural reflection capabilities: The previously-mentioned features an application has might be dynamically modified

Dynamic evaluation of code represented as strings: The exec function can dynamically evaluate code created at runtime

Francisco OrtinJuan Manuel Cueva

The The reifyreify Statement Statement

• Not needing to specify it, every language has the reify statement

• Inside a reify statement, Python code can be placed

• The generic interpreter recognizes every reify statement regardless the programming language being analyzed

• The generic interpreter will not process a reify statement as the rest of the code; it will:

The Python code inside the reify statement is taken as a string

This code is passed as an argument to the exec function The Python code is evaluated at the interpreter computational environment!

Francisco OrtinJuan Manuel Cueva

Non-Restrictive ReflectionNon-Restrictive Reflection

• Using Python introspection and structural reflection, application’s symbol-tables and language’s specification can be inspected/adapted

GenericInterpreter

User’s Application

Language-Specification

Application’sSymbol-

Table

a=10*2; b=a/-18; Reify <# write(str(vars)) vars["a"]=2 #> a; b; Reify <# code=“...” language["assignment"]. actions.append(code) #> a=10*2;

Specific language

Pythonlanguage

write(str(vars))vars["a"]=2

1) Introspection2) Structural Reflection

code=“...”language["assignment"]. actions.append(code)

3) Computational Reflection

Ap

plicati

on

Com

pu

tati

on

al En

vir

on

men

t

Inte

rpre

ter

Com

pu

tati

on

al

En

vir

on

men

t

Python becomes a1.- runtime2.- non-restrictive3.- language-neutral4.- three-levels-reflectivemeta-language

Francisco OrtinJuan Manuel Cueva

Language SpecificationLanguage Specification

• Language-Specification files describe: Scanner and parser rules with context-free

grammar rules Semantic specifications by means of Python code

MetaPython.ML describes a subset of the Python programming language:

Language = MetaPython

Scanner = { "Digit Token" digit -> "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9" ;

"Integer Token" INTEGER -> digit moreDigits ;

"Float Token" FLOAT -> INTEGER "." INTEGER ;

"Zero or more digits token" moreDigits -> digit moreDigits | ;

"Character Token" char -> "a"|"b"|"c"|"d"|"e"|"f"|"g"|"h"|"i"|"j"| "k"|"l"|"m"|"n"|"ñ"|"o"|"p"|"q"|"r"|"s"|"t"|"u"|"v"|"w"|"x"|"y"|"z"| "á"|"é"|"í"|"ó"|"ú"| "A"|"B"|"C"|"D"|"E"|"F"|"G"|"H"|"I"|"J"|"K"|"L"|"M"|"N"|"Ñ"|"O"|"P"| "Q"|"R"|"S"|"T"|"U"|"V"|"W"|"X"|"Y"|"Z"|"Á"|"É"|"Í"|"Ó"|"Ú"|"_” ;...

Francisco OrtinJuan Manuel Cueva

Syntactic and Semantic SpecSyntactic and Semantic SpecParser = {

"Initial Free-Context Rule" S -> statement moreStatements <## Initial Code Needed in the Application Executionglobal classes,functionsclasses={} # Classes Symbol Tablefunctions={} # Function Symbol Tablenodes[1].execute()nodes[2].execute()#> ;

"Zero or more statements" moreStatements -> statement moreStatements <#nodes[1].execute()nodes[2].execute()#> | ;

"Python Statement" statement -> class <#nodes[1].execute() # Inserts the class into the ST#>

| function <#nodes[1].execute() # Inserts the class into the ST#>

| if | while | import | assignment | functionCall ;

"Class Spec." class -> CLASS ID OPENCURLYBRACE classBody CLOSECURLYBRACE...

Skip = { "\t"; "\n"; " "; }NotSkip = { }

Semantic actions

Syntactic rules(semantic rules derivatively suppressed)

Tokens automatically skipped

Tokens automatically appended

Francisco OrtinJuan Manuel Cueva

Sample ApplicationSample ApplicationApplication = "Sample App"Language = "MetaPython"

import string;import random; class MyClass {

def init(self) {self.calls=0;self.nestingLevel=1;}

def call(self) {self.calls=self.calls+1;}

def nestedCall(self) {self.calls=self.calls+1;temp=random.random()-(1.0-self.nestingLevel/10.0);if temp<0.5 {

self.nestingLevel=self.nestingLevel+1;self.nestedCall();self.nestingLevel=self.nestingLevel-1;}

}

}

object=MyClass();object.init();while 1 {

object.call();object.nestedCall();

}

Application and Language Description

Francisco OrtinJuan Manuel Cueva

Application ExecutionApplication Execution

• The platform offers a nitrO object, representing the system applications and languages (Facade)

• When the application execution takes place in the nitrO platform:

An application object is created in the nitrO.apps dictionary (with the key “Sample App”)

The MetaPython.ml language specification-file is located The language specification is translated into a object

structure; this is saved into the language application-object attribute

At runtime, the application symbol-table is located on its applicationGlobalContext attribute

Language Spec

language

Symbol Table

applicationGlobalContext

nitrO nitrO.apps[“Sample App”]apps

Francisco OrtinJuan Manuel Cueva

Application AdaptationApplication Adaptation

• Every application executed in the nitrO platform may access the nitrO “Facade” object and dynamically adapt:

An application symbol-table Introspection and Structural Reflection

A language specification Computational Reflection

• without any MOP-restrictive protocol!• in a language-independent way!

Francisco OrtinJuan Manuel Cueva

Dynamic Application WeavingDynamic Application WeavingApplication = "Time Aspect"Language = <# Language = JustAReifyStatement Scanner = {} Parser = { "Initial Free-Context Rule" S -> _REIFY_ <# nodes[1].execute() #> ; } Skip={ "\t"; "\n"; " "; } NotSkip = { } #>

reify <#def weave(app,nitrO): # Function that weaves an application if nitrO.apps.has_key(app): # This is just a MetaPython aspect if nitrO.apps[app].language.name=="MetaPython": codeBefore="""... """ codeAfter="""... """ actions=nitrO.apps[app].language.syntacticSpec["functionCall"].options[1].actions # Had the aspect been weaved? hadBeenWeaved=... if not(hadBeenWeaved): # Inserts the monitoring code actions.insert(0,SemanticAction(codeBefore)) actions.append(SemanticAction(codeAfter)) else: # Removes the monitoring code length=len(actions) for i in range(length): action=actions[length-i-1] if action.action==codeBefore or action.action==codeAfter: actions.remove(action) nitrO.shell.write("Application unweaved.")...nitrO.apps["Time Aspect"].weave=weave # Creates an application aspect-weaver#>

Language Specification inside the application file(just a reify statement)

Time-execution method-call monitoring

Removes the monitoring routines

# Application time-monitoring weavernitrO.executeFile(nitrO.dir+”time/timeAspect.na”)write(nitrO.describe())

nitrO.apps["Time Aspect"].weave("Sample App",nitrO)

Francisco OrtinJuan Manuel Cueva

Platform BenefitsPlatform Benefits

• No MOP-restrictions: the real computational jump overcomes the MOP-based adaptation limitations

• Language independence: The generic interpreter can interpreter any

previously-specified language The reify statement is part of every language

• What can be adapted: introspection, structural reflection and computational reflection

• Application interoperability: any application may access and reflectively modify another program being executed –whatever its language would be

• Expressiveness improvement: the way behavior is customized is not restricted to a framework that relies in method overriding; a complete meta-language (Python) might be used to adapt any other language’s feature

Francisco OrtinJuan Manuel Cueva

Runtime PerformanceRuntime Performance

• Runtime performance penalties are caused by the interpretation of every programming language

• However, many interpreted languages (Java, C# or even Python) are commercially employed due to optimization techniques such as JIT compilation

• As we always translate any language into Python code, a way of speeding up the execution of our platform’s applications in the following versions is using the interface of a Python-JIT compiler implementation

Platform download at:www.di.uniovi.es/reflection/lab/prototypes.html#nrrs

University of Oviedo Computer Science Department

Francisco OrtinJuan Manuel Cueva

The nitrO Reflective PlatformThe nitrO Reflective Platform

International Conference on International Conference on Software Engineering Research Software Engineering Research

and Practice (SERP)and Practice (SERP)

Session on Adaptable Software Session on Adaptable Software Architectures (ASA)Architectures (ASA)