Points-to Analysis for Context-
Oriented JavaScript Programs
Sergio Cardenas, Paul Leger, Hiroaki Fukuda, Nicolás Cardozo
Systems an Computing Engineering - Universidad de los Andes, Bogotá - Colombia
Universidad Católica del Norte, Coquimbo - Chile
Shibaura Institute of Technology, Tokyo - Japan
se.cardenas@uniandes.edu.co, pleger@ucn.cl, hiroaki@shibaura-it.ac.jp, n.cardozo@uniandes.edu.co
@ncardoz
Formal Techniques for Java-like Programs - 18 / 07 / 2023
Points-to analysis
2
Object first(Object o1, Object o2){
return o1;
}
Object second(Object o1, Object o2){
return first(o2, o1);
}
void f() {
Object o1 = new Object();
Object o2 = new Object();
Object o3 = first(o1, o2);
Object o4 = first(o2, o1);
Object o5 = second(o1, o2);
Object o6 = second(o2, o1);
}
f
Points-to analysis
2
Object first(Object o1, Object o2){
return o1;
}
Object second(Object o1, Object o2){
return first(o2, o1);
}
void f() {
Object o1 = new Object();
Object o2 = new Object();
Object o3 = first(o1, o2);
Object o4 = first(o2, o1);
Object o5 = second(o1, o2);
Object o6 = second(o2, o1);
}
o1 inst1
f
Points-to analysis
2
Object first(Object o1, Object o2){
return o1;
}
Object second(Object o1, Object o2){
return first(o2, o1);
}
void f() {
Object o1 = new Object();
Object o2 = new Object();
Object o3 = first(o1, o2);
Object o4 = first(o2, o1);
Object o5 = second(o1, o2);
Object o6 = second(o2, o1);
}
o1
o2
inst1
inst2
f
Points-to analysis
2
Object first(Object o1, Object o2){
return o1;
}
Object second(Object o1, Object o2){
return first(o2, o1);
}
void f() {
Object o1 = new Object();
Object o2 = new Object();
Object o3 = first(o1, o2);
Object o4 = first(o2, o1);
Object o5 = second(o1, o2);
Object o6 = second(o2, o1);
}
o1
o2
inst1
inst2
o3
f
first
Points-to analysis
2
Object first(Object o1, Object o2){
return o1;
}
Object second(Object o1, Object o2){
return first(o2, o1);
}
void f() {
Object o1 = new Object();
Object o2 = new Object();
Object o3 = first(o1, o2);
Object o4 = first(o2, o1);
Object o5 = second(o1, o2);
Object o6 = second(o2, o1);
}
o1
o2
inst1
inst2
o3
inst1
f
first
Points-to analysis
2
Object first(Object o1, Object o2){
return o1;
}
Object second(Object o1, Object o2){
return first(o2, o1);
}
void f() {
Object o1 = new Object();
Object o2 = new Object();
Object o3 = first(o1, o2);
Object o4 = first(o2, o1);
Object o5 = second(o1, o2);
Object o6 = second(o2, o1);
}
o1
o2
inst1
inst2
o3
inst1
first
inst1
inst2
...
f
first
3
programs need to be more dynamic …
3
programs need to be more dynamic …
… due to complex and
changing requirements
3
programs need to be more dynamic …
… due to complex and
changing requirements
new modularity
abstractions
3
programs need to be more dynamic …
… due to complex and
changing requirements
new modularity
abstractions
changing locations
Context-oriented programming (COP)
4
Msg = {
send: function(msg) {
return msg;
}
};
Context-oriented programming (COP)
4
Msg = {
send: function(msg) {
return msg;
}
};
Encryption = new cop.Context({});
EncryptionBehavior = Trait({
send: function(msg) {
return "<E>" + this.proceed() + "<E>";
}
});
Context-oriented programming (COP)
4
Msg = {
send: function(msg) {
return msg;
}
};
Encryption = new cop.Context({});
EncryptionBehavior = Trait({
send: function(msg) {
return "<E>" + this.proceed() + "<E>";
}
});
Compression = new cop.Context({});
CompressionBehavior = Trait({
send: function(msg) {
return "<C>" + this.proceed() + "<C>";
}
});
Context-oriented programming (COP)
4
Msg = {
send: function(msg) {
return msg;
}
};
Encryption = new cop.Context({});
EncryptionBehavior = Trait({
send: function(msg) {
return "<E>" + this.proceed() + "<E>";
}
});
Compression = new cop.Context({});
CompressionBehavior = Trait({
send: function(msg) {
return "<C>" + this.proceed() + "<C>";
}
});
Encryption.adapt(Msg, EncryptionBehavior);
Compression.adapt(Msg, CompressionBehavior);
Context-oriented programming (COP)
4
Msg = {
send: function(msg) {
return msg;
}
};
Encryption = new cop.Context({});
EncryptionBehavior = Trait({
send: function(msg) {
return "<E>" + this.proceed() + "<E>";
}
});
Compression = new cop.Context({});
CompressionBehavior = Trait({
send: function(msg) {
return "<C>" + this.proceed() + "<C>";
}
});
Encryption.adapt(Msg, EncryptionBehavior);
Compression.adapt(Msg, CompressionBehavior);
Encryption.activate();
Context-oriented programming (COP)
4
Msg = {
send: function(msg) {
return msg;
}
};
Encryption = new cop.Context({});
EncryptionBehavior = Trait({
send: function(msg) {
return "<E>" + this.proceed() + "<E>";
}
});
Compression = new cop.Context({});
CompressionBehavior = Trait({
send: function(msg) {
return "<C>" + this.proceed() + "<C>";
}
});
Encryption.adapt(Msg, EncryptionBehavior);
Compression.adapt(Msg, CompressionBehavior);
Encryption.activate();
Compression.activate();
Context-oriented programming (COP)
5
msg = Msg();
msg.send(42);
Context-oriented programming (COP)
5
Msg = {
send: function(msg) {
return msg;
}
};
Encryption = new cop.Context({});
EncryptionBehavior = Trait({
send: function(msg) {
return "<E>" + this.proceed() + "<E>";
}
});
Compression = new cop.Context({});
CompressionBehavior = Trait({
send: function(msg) {
return "<C>" + this.proceed() + "<C>";
}
});
msg = Msg();
msg.send(42);
6
Base analysis precise and efficient
to determine different properties
about dynamic programs in COP
Analyzing COP programs
7
COP program
Analyzing COP programs
7
COP program
Context.adapt(object1, trait1)
Context.adapt(object2, trait1)
Context.adapt(objectn, traitm)
…
1. tuple extraction
⟨ctx, trait, obj⟩
Analyzing COP programs
7
COP program
Context.adapt(object1, trait1)
Context.adapt(object2, trait1)
Context.adapt(objectn, traitm)
…
1. tuple extraction
⟨ctx, trait, obj⟩ 2. Code transformation
Analyzing COP programs
7
COP program
Context.adapt(object1, trait1)
Context.adapt(object2, trait1)
Context.adapt(objectn, traitm)
…
1. tuple extraction
⟨ctx, trait, obj⟩ 2. Code transformation 3. Field-sensitive correlation
tracking analysis
Context identification and transformation
8
Encryption.adapt(Msg, EncryptionBehavior);
Encryption.activate();
Encryption = new cop.Context({});
EncryptionBehavior = Trait({
send: function(msg) {
return "<E>" + this.proceed() + "<E>";
}
});
Context identification and transformation
9
Encryption.adapt(Msg, EncryptionBehavior);
Encryption.activate();
Encryption = new cop.Context({});
EncryptionBehavior = Trait({
send: function(msg) {
return "<E>" + this.proceed() + "<E>";
}
});
Context identification and transformation
9
Encryption.adapt(Msg, EncryptionBehavior);
Encryption.activate();
Encryption = new cop.Context({});
EncryptionBehavior = Trait({
send: function(msg) {
return "<E>" + this.proceed() + "<E>";
}
});
o = {
send: function() {
return "<E>" + this.proceed() + “<E>";
}
}
EncryptionBehavior = Trait(o);
EncryptionBehavior.obj = o;
Context identification and transformation
10
Encryption.adapt(Msg, EncryptionBehavior);
Encryption.activate();
Encryption = new cop.Context({});
EncryptionBehavior = Trait({
send: function(msg) {
return "<E>" + this.proceed() + "<E>";
}
});
Context identification and transformation
10
Encryption.adapt(Msg, EncryptionBehavior);
Encryption.activate();
Encryption = new cop.Context({});
EncryptionBehavior = Trait({
send: function(msg) {
return "<E>" + this.proceed() + "<E>";
}
});
Encryption.adaptation1 = {
obj: Msg,
trait: EncryptionBehavior
}
Context identification and transformation
11
Encryption.adapt(Msg, EncryptionBehavior);
Encryption.activate();
Encryption = new cop.Context({});
EncryptionBehavior = Trait({
send: function(msg) {
return "<E>" + this.proceed() + "<E>";
}
});
Context identification and transformation
11
Encryption.adapt(Msg, EncryptionBehavior);
Encryption.activate();
Encryption = new cop.Context({});
EncryptionBehavior = Trait({
send: function(msg) {
return "<E>" + this.proceed() + "<E>";
}
});
for(var p in
Encryption.adaptation1.trait.obj) {
(function (prop) {
Encryption.adaptation1.obj[prop] =
Encryption.adaptation1.trait.obj[prop];
})(p);
}
12
Experiments
use four
different
applications
comparing
field-sensitive
analysis and
our extension
hello-world.js
shape-polymorphism.js
video-encoder.js
course-management.js
https://
fl
aglab.github.io/AdaptiveSystemAnalysis/
Precision evaluation
13
Shape = {
b: 2,
h: 3,
type: "shape",
getType: function() { return this.type; },
area: function() { return 'Calling an abstract method area’; },
perimeter: function() { return 'Calling an abstract method perimeter’; },
numberOfSides: function() { return 0; }
};
Triangle = new cop.Context({});
TriangleBehavior = cop.Trait({
getType: function() { return “triangle"; },
area: function() { return this.b * this.h/2; },
perimeter: function() {
return this.b + 2*Math.sqrt(Math.pow(this.h,2) + Math.pow(this.b/2, 2));
},
numberOfSides: function() { return 3; }
});
Triangle.adapt(TShape, TriangleBehavior);
Circle = new cop.Context({});
CircleBehavior = cop.Trait({
getType: function() { return “circle"; },
area: function() { return Math.pow(this.b, 2) * Math.PI; },
perimeter: function() { return this.b * 2* Math.PI; },
numberOfSides: function() {
throw new Error("Number of sides is not defined in a circle");
}
});
Circle.adapt(Shape, CircleBehavior);
baseline ours
r1
r2
r3
r4
r6
r5
r7
r8
r9
Precision evaluation
13
Shape = {
b: 2,
h: 3,
type: "shape",
getType: function() { return this.type; },
area: function() { return 'Calling an abstract method area’; },
perimeter: function() { return 'Calling an abstract method perimeter’; },
numberOfSides: function() { return 0; }
};
Triangle = new cop.Context({});
TriangleBehavior = cop.Trait({
getType: function() { return “triangle"; },
area: function() { return this.b * this.h/2; },
perimeter: function() {
return this.b + 2*Math.sqrt(Math.pow(this.h,2) + Math.pow(this.b/2, 2));
},
numberOfSides: function() { return 3; }
});
Triangle.adapt(TShape, TriangleBehavior);
Circle = new cop.Context({});
CircleBehavior = cop.Trait({
getType: function() { return “circle"; },
area: function() { return Math.pow(this.b, 2) * Math.PI; },
perimeter: function() { return this.b * 2* Math.PI; },
numberOfSides: function() {
throw new Error("Number of sides is not defined in a circle");
}
});
Circle.adapt(Shape, CircleBehavior);
area
baseline ours
r1
r1
r2
r3
r4
r6
r5
r7
r8
r9
Precision evaluation
13
Shape = {
b: 2,
h: 3,
type: "shape",
getType: function() { return this.type; },
area: function() { return 'Calling an abstract method area’; },
perimeter: function() { return 'Calling an abstract method perimeter’; },
numberOfSides: function() { return 0; }
};
Triangle = new cop.Context({});
TriangleBehavior = cop.Trait({
getType: function() { return “triangle"; },
area: function() { return this.b * this.h/2; },
perimeter: function() {
return this.b + 2*Math.sqrt(Math.pow(this.h,2) + Math.pow(this.b/2, 2));
},
numberOfSides: function() { return 3; }
});
Triangle.adapt(TShape, TriangleBehavior);
Circle = new cop.Context({});
CircleBehavior = cop.Trait({
getType: function() { return “circle"; },
area: function() { return Math.pow(this.b, 2) * Math.PI; },
perimeter: function() { return this.b * 2* Math.PI; },
numberOfSides: function() {
throw new Error("Number of sides is not defined in a circle");
}
});
Circle.adapt(Shape, CircleBehavior);
area
baseline ours
r1
r1
r2
r3
r4
r6
r5
r1
r3
r6
r7
r8
r9
area
Precision evaluation
14
Shape = {
b: 2,
h: 3,
type: "shape",
getType: function() { return this.type; },
area: function() { return 'Calling an abstract method area’; },
perimeter: function() { return 'Calling an abstract method perimeter’; },
numberOfSides: function() { return 0; }
};
Triangle = new cop.Context({});
TriangleBehavior = cop.Trait({
getType: function() { return “triangle"; },
area: function() { return this.b * this.h/2; },
perimeter: function() {
return this.b + 2*Math.sqrt(Math.pow(this.h,2) + Math.pow(this.b/2, 2));
},
numberOfSides: function() { return 3; }
});
Triangle.adapt(TShape, TriangleBehavior);
Circle = new cop.Context({});
CircleBehavior = cop.Trait({
getType: function() { return “circle"; },
area: function() { return Math.pow(this.b, 2) * Math.PI; },
perimeter: function() { return this.b * 2* Math.PI; },
numberOfSides: function() {
throw new Error("Number of sides is not defined in a circle");
}
});
Circle.adapt(Shape, CircleBehavior);
baseline ours
r1
r2
r3
r4
r6
r5
r7
r8
r9
Precision evaluation
14
Shape = {
b: 2,
h: 3,
type: "shape",
getType: function() { return this.type; },
area: function() { return 'Calling an abstract method area’; },
perimeter: function() { return 'Calling an abstract method perimeter’; },
numberOfSides: function() { return 0; }
};
Triangle = new cop.Context({});
TriangleBehavior = cop.Trait({
getType: function() { return “triangle"; },
area: function() { return this.b * this.h/2; },
perimeter: function() {
return this.b + 2*Math.sqrt(Math.pow(this.h,2) + Math.pow(this.b/2, 2));
},
numberOfSides: function() { return 3; }
});
Triangle.adapt(TShape, TriangleBehavior);
Circle = new cop.Context({});
CircleBehavior = cop.Trait({
getType: function() { return “circle"; },
area: function() { return Math.pow(this.b, 2) * Math.PI; },
perimeter: function() { return this.b * 2* Math.PI; },
numberOfSides: function() {
throw new Error("Number of sides is not defined in a circle");
}
});
Circle.adapt(Shape, CircleBehavior);
sides
baseline ours
r9
r1
r2
r3
r4
r6
r5
r7
r8
r9
Precision evaluation
14
Shape = {
b: 2,
h: 3,
type: "shape",
getType: function() { return this.type; },
area: function() { return 'Calling an abstract method area’; },
perimeter: function() { return 'Calling an abstract method perimeter’; },
numberOfSides: function() { return 0; }
};
Triangle = new cop.Context({});
TriangleBehavior = cop.Trait({
getType: function() { return “triangle"; },
area: function() { return this.b * this.h/2; },
perimeter: function() {
return this.b + 2*Math.sqrt(Math.pow(this.h,2) + Math.pow(this.b/2, 2));
},
numberOfSides: function() { return 3; }
});
Triangle.adapt(TShape, TriangleBehavior);
Circle = new cop.Context({});
CircleBehavior = cop.Trait({
getType: function() { return “circle"; },
area: function() { return Math.pow(this.b, 2) * Math.PI; },
perimeter: function() { return this.b * 2* Math.PI; },
numberOfSides: function() {
throw new Error("Number of sides is not defined in a circle");
}
});
Circle.adapt(Shape, CircleBehavior);
sides
baseline ours
r9
r1
r2
r3
r4
r6
r5
r8
r7
r9
r7
r8
r9
sides
The road ahead … adaptation completeness
15
Context1 = new cop.Context({});
Behavior1 = cop.Trait({
foo: function() ...
});
Context1.adapt(Object, Behavior1);
Context2 = new cop.Context({});
Behavior2 = cop.Trait({
bar: function(){
baz();
foo();
}
});
Context2.adapt(Object, Behavior2);
Object = {
baz: function() ...
};
The road ahead … adaptation completeness
15
Context1 = new cop.Context({});
Behavior1 = cop.Trait({
foo: function() ...
});
Context1.adapt(Object, Behavior1);
Context2 = new cop.Context({});
Behavior2 = cop.Trait({
bar: function(){
baz();
foo();
}
});
Context2.adapt(Object, Behavior2);
Object = {
baz: function() ...
};
Context1.activate();
Context2.activate();
bar();
1.
The road ahead … adaptation completeness
15
Context1 = new cop.Context({});
Behavior1 = cop.Trait({
foo: function() ...
});
Context1.adapt(Object, Behavior1);
Context2 = new cop.Context({});
Behavior2 = cop.Trait({
bar: function(){
baz();
foo();
}
});
Context2.adapt(Object, Behavior2);
Object = {
baz: function() ...
};
Context1.activate();
Context2.activate();
bar();
Context2.activate();
bar();
1. 2.
The road ahead … adaptation completeness
15
Context1 = new cop.Context({});
Behavior1 = cop.Trait({
foo: function() ...
});
Context1.adapt(Object, Behavior1);
Context2 = new cop.Context({});
Behavior2 = cop.Trait({
bar: function(){
baz();
foo();
}
});
Context2.adapt(Object, Behavior2);
Object = {
baz: function() ...
};
Context1.activate();
Context2.activate();
bar();
Context2.activate();
bar();
1. 2.
Conclusion
16
@ncardoz
COP
analysis framework
Conclusion
16
@ncardoz
COP
analysis framework
First analysis taking into
account the modularity and
dynamic aspects of COP
Conclusion
16
@ncardoz
COP
analysis framework
First analysis taking into
account the modularity and
dynamic aspects of COP
Improved recall for COP
programs (without proceed)

[FTfJP23] Points-to Analysis for Context-oriented Javascript Programs

  • 1.
    Points-to Analysis forContext- Oriented JavaScript Programs Sergio Cardenas, Paul Leger, Hiroaki Fukuda, Nicolás Cardozo Systems an Computing Engineering - Universidad de los Andes, Bogotá - Colombia Universidad Católica del Norte, Coquimbo - Chile Shibaura Institute of Technology, Tokyo - Japan se.cardenas@uniandes.edu.co, pleger@ucn.cl, hiroaki@shibaura-it.ac.jp, n.cardozo@uniandes.edu.co @ncardoz Formal Techniques for Java-like Programs - 18 / 07 / 2023
  • 2.
    Points-to analysis 2 Object first(Objecto1, Object o2){ return o1; } Object second(Object o1, Object o2){ return first(o2, o1); } void f() { Object o1 = new Object(); Object o2 = new Object(); Object o3 = first(o1, o2); Object o4 = first(o2, o1); Object o5 = second(o1, o2); Object o6 = second(o2, o1); } f
  • 3.
    Points-to analysis 2 Object first(Objecto1, Object o2){ return o1; } Object second(Object o1, Object o2){ return first(o2, o1); } void f() { Object o1 = new Object(); Object o2 = new Object(); Object o3 = first(o1, o2); Object o4 = first(o2, o1); Object o5 = second(o1, o2); Object o6 = second(o2, o1); } o1 inst1 f
  • 4.
    Points-to analysis 2 Object first(Objecto1, Object o2){ return o1; } Object second(Object o1, Object o2){ return first(o2, o1); } void f() { Object o1 = new Object(); Object o2 = new Object(); Object o3 = first(o1, o2); Object o4 = first(o2, o1); Object o5 = second(o1, o2); Object o6 = second(o2, o1); } o1 o2 inst1 inst2 f
  • 5.
    Points-to analysis 2 Object first(Objecto1, Object o2){ return o1; } Object second(Object o1, Object o2){ return first(o2, o1); } void f() { Object o1 = new Object(); Object o2 = new Object(); Object o3 = first(o1, o2); Object o4 = first(o2, o1); Object o5 = second(o1, o2); Object o6 = second(o2, o1); } o1 o2 inst1 inst2 o3 f first
  • 6.
    Points-to analysis 2 Object first(Objecto1, Object o2){ return o1; } Object second(Object o1, Object o2){ return first(o2, o1); } void f() { Object o1 = new Object(); Object o2 = new Object(); Object o3 = first(o1, o2); Object o4 = first(o2, o1); Object o5 = second(o1, o2); Object o6 = second(o2, o1); } o1 o2 inst1 inst2 o3 inst1 f first
  • 7.
    Points-to analysis 2 Object first(Objecto1, Object o2){ return o1; } Object second(Object o1, Object o2){ return first(o2, o1); } void f() { Object o1 = new Object(); Object o2 = new Object(); Object o3 = first(o1, o2); Object o4 = first(o2, o1); Object o5 = second(o1, o2); Object o6 = second(o2, o1); } o1 o2 inst1 inst2 o3 inst1 first inst1 inst2 ... f first
  • 8.
    3 programs need tobe more dynamic …
  • 9.
    3 programs need tobe more dynamic … … due to complex and changing requirements
  • 10.
    3 programs need tobe more dynamic … … due to complex and changing requirements new modularity abstractions
  • 11.
    3 programs need tobe more dynamic … … due to complex and changing requirements new modularity abstractions changing locations
  • 12.
    Context-oriented programming (COP) 4 Msg= { send: function(msg) { return msg; } };
  • 13.
    Context-oriented programming (COP) 4 Msg= { send: function(msg) { return msg; } }; Encryption = new cop.Context({}); EncryptionBehavior = Trait({ send: function(msg) { return "<E>" + this.proceed() + "<E>"; } });
  • 14.
    Context-oriented programming (COP) 4 Msg= { send: function(msg) { return msg; } }; Encryption = new cop.Context({}); EncryptionBehavior = Trait({ send: function(msg) { return "<E>" + this.proceed() + "<E>"; } }); Compression = new cop.Context({}); CompressionBehavior = Trait({ send: function(msg) { return "<C>" + this.proceed() + "<C>"; } });
  • 15.
    Context-oriented programming (COP) 4 Msg= { send: function(msg) { return msg; } }; Encryption = new cop.Context({}); EncryptionBehavior = Trait({ send: function(msg) { return "<E>" + this.proceed() + "<E>"; } }); Compression = new cop.Context({}); CompressionBehavior = Trait({ send: function(msg) { return "<C>" + this.proceed() + "<C>"; } }); Encryption.adapt(Msg, EncryptionBehavior); Compression.adapt(Msg, CompressionBehavior);
  • 16.
    Context-oriented programming (COP) 4 Msg= { send: function(msg) { return msg; } }; Encryption = new cop.Context({}); EncryptionBehavior = Trait({ send: function(msg) { return "<E>" + this.proceed() + "<E>"; } }); Compression = new cop.Context({}); CompressionBehavior = Trait({ send: function(msg) { return "<C>" + this.proceed() + "<C>"; } }); Encryption.adapt(Msg, EncryptionBehavior); Compression.adapt(Msg, CompressionBehavior); Encryption.activate();
  • 17.
    Context-oriented programming (COP) 4 Msg= { send: function(msg) { return msg; } }; Encryption = new cop.Context({}); EncryptionBehavior = Trait({ send: function(msg) { return "<E>" + this.proceed() + "<E>"; } }); Compression = new cop.Context({}); CompressionBehavior = Trait({ send: function(msg) { return "<C>" + this.proceed() + "<C>"; } }); Encryption.adapt(Msg, EncryptionBehavior); Compression.adapt(Msg, CompressionBehavior); Encryption.activate(); Compression.activate();
  • 18.
  • 19.
    Context-oriented programming (COP) 5 Msg= { send: function(msg) { return msg; } }; Encryption = new cop.Context({}); EncryptionBehavior = Trait({ send: function(msg) { return "<E>" + this.proceed() + "<E>"; } }); Compression = new cop.Context({}); CompressionBehavior = Trait({ send: function(msg) { return "<C>" + this.proceed() + "<C>"; } }); msg = Msg(); msg.send(42);
  • 20.
    6 Base analysis preciseand efficient to determine different properties about dynamic programs in COP
  • 21.
  • 22.
    Analyzing COP programs 7 COPprogram Context.adapt(object1, trait1) Context.adapt(object2, trait1) Context.adapt(objectn, traitm) … 1. tuple extraction ⟨ctx, trait, obj⟩
  • 23.
    Analyzing COP programs 7 COPprogram Context.adapt(object1, trait1) Context.adapt(object2, trait1) Context.adapt(objectn, traitm) … 1. tuple extraction ⟨ctx, trait, obj⟩ 2. Code transformation
  • 24.
    Analyzing COP programs 7 COPprogram Context.adapt(object1, trait1) Context.adapt(object2, trait1) Context.adapt(objectn, traitm) … 1. tuple extraction ⟨ctx, trait, obj⟩ 2. Code transformation 3. Field-sensitive correlation tracking analysis
  • 25.
    Context identification andtransformation 8 Encryption.adapt(Msg, EncryptionBehavior); Encryption.activate(); Encryption = new cop.Context({}); EncryptionBehavior = Trait({ send: function(msg) { return "<E>" + this.proceed() + "<E>"; } });
  • 26.
    Context identification andtransformation 9 Encryption.adapt(Msg, EncryptionBehavior); Encryption.activate(); Encryption = new cop.Context({}); EncryptionBehavior = Trait({ send: function(msg) { return "<E>" + this.proceed() + "<E>"; } });
  • 27.
    Context identification andtransformation 9 Encryption.adapt(Msg, EncryptionBehavior); Encryption.activate(); Encryption = new cop.Context({}); EncryptionBehavior = Trait({ send: function(msg) { return "<E>" + this.proceed() + "<E>"; } }); o = { send: function() { return "<E>" + this.proceed() + “<E>"; } } EncryptionBehavior = Trait(o); EncryptionBehavior.obj = o;
  • 28.
    Context identification andtransformation 10 Encryption.adapt(Msg, EncryptionBehavior); Encryption.activate(); Encryption = new cop.Context({}); EncryptionBehavior = Trait({ send: function(msg) { return "<E>" + this.proceed() + "<E>"; } });
  • 29.
    Context identification andtransformation 10 Encryption.adapt(Msg, EncryptionBehavior); Encryption.activate(); Encryption = new cop.Context({}); EncryptionBehavior = Trait({ send: function(msg) { return "<E>" + this.proceed() + "<E>"; } }); Encryption.adaptation1 = { obj: Msg, trait: EncryptionBehavior }
  • 30.
    Context identification andtransformation 11 Encryption.adapt(Msg, EncryptionBehavior); Encryption.activate(); Encryption = new cop.Context({}); EncryptionBehavior = Trait({ send: function(msg) { return "<E>" + this.proceed() + "<E>"; } });
  • 31.
    Context identification andtransformation 11 Encryption.adapt(Msg, EncryptionBehavior); Encryption.activate(); Encryption = new cop.Context({}); EncryptionBehavior = Trait({ send: function(msg) { return "<E>" + this.proceed() + "<E>"; } }); for(var p in Encryption.adaptation1.trait.obj) { (function (prop) { Encryption.adaptation1.obj[prop] = Encryption.adaptation1.trait.obj[prop]; })(p); }
  • 32.
    12 Experiments use four different applications comparing field-sensitive analysis and ourextension hello-world.js shape-polymorphism.js video-encoder.js course-management.js https:// fl aglab.github.io/AdaptiveSystemAnalysis/
  • 33.
    Precision evaluation 13 Shape ={ b: 2, h: 3, type: "shape", getType: function() { return this.type; }, area: function() { return 'Calling an abstract method area’; }, perimeter: function() { return 'Calling an abstract method perimeter’; }, numberOfSides: function() { return 0; } }; Triangle = new cop.Context({}); TriangleBehavior = cop.Trait({ getType: function() { return “triangle"; }, area: function() { return this.b * this.h/2; }, perimeter: function() { return this.b + 2*Math.sqrt(Math.pow(this.h,2) + Math.pow(this.b/2, 2)); }, numberOfSides: function() { return 3; } }); Triangle.adapt(TShape, TriangleBehavior); Circle = new cop.Context({}); CircleBehavior = cop.Trait({ getType: function() { return “circle"; }, area: function() { return Math.pow(this.b, 2) * Math.PI; }, perimeter: function() { return this.b * 2* Math.PI; }, numberOfSides: function() { throw new Error("Number of sides is not defined in a circle"); } }); Circle.adapt(Shape, CircleBehavior); baseline ours r1 r2 r3 r4 r6 r5 r7 r8 r9
  • 34.
    Precision evaluation 13 Shape ={ b: 2, h: 3, type: "shape", getType: function() { return this.type; }, area: function() { return 'Calling an abstract method area’; }, perimeter: function() { return 'Calling an abstract method perimeter’; }, numberOfSides: function() { return 0; } }; Triangle = new cop.Context({}); TriangleBehavior = cop.Trait({ getType: function() { return “triangle"; }, area: function() { return this.b * this.h/2; }, perimeter: function() { return this.b + 2*Math.sqrt(Math.pow(this.h,2) + Math.pow(this.b/2, 2)); }, numberOfSides: function() { return 3; } }); Triangle.adapt(TShape, TriangleBehavior); Circle = new cop.Context({}); CircleBehavior = cop.Trait({ getType: function() { return “circle"; }, area: function() { return Math.pow(this.b, 2) * Math.PI; }, perimeter: function() { return this.b * 2* Math.PI; }, numberOfSides: function() { throw new Error("Number of sides is not defined in a circle"); } }); Circle.adapt(Shape, CircleBehavior); area baseline ours r1 r1 r2 r3 r4 r6 r5 r7 r8 r9
  • 35.
    Precision evaluation 13 Shape ={ b: 2, h: 3, type: "shape", getType: function() { return this.type; }, area: function() { return 'Calling an abstract method area’; }, perimeter: function() { return 'Calling an abstract method perimeter’; }, numberOfSides: function() { return 0; } }; Triangle = new cop.Context({}); TriangleBehavior = cop.Trait({ getType: function() { return “triangle"; }, area: function() { return this.b * this.h/2; }, perimeter: function() { return this.b + 2*Math.sqrt(Math.pow(this.h,2) + Math.pow(this.b/2, 2)); }, numberOfSides: function() { return 3; } }); Triangle.adapt(TShape, TriangleBehavior); Circle = new cop.Context({}); CircleBehavior = cop.Trait({ getType: function() { return “circle"; }, area: function() { return Math.pow(this.b, 2) * Math.PI; }, perimeter: function() { return this.b * 2* Math.PI; }, numberOfSides: function() { throw new Error("Number of sides is not defined in a circle"); } }); Circle.adapt(Shape, CircleBehavior); area baseline ours r1 r1 r2 r3 r4 r6 r5 r1 r3 r6 r7 r8 r9 area
  • 36.
    Precision evaluation 14 Shape ={ b: 2, h: 3, type: "shape", getType: function() { return this.type; }, area: function() { return 'Calling an abstract method area’; }, perimeter: function() { return 'Calling an abstract method perimeter’; }, numberOfSides: function() { return 0; } }; Triangle = new cop.Context({}); TriangleBehavior = cop.Trait({ getType: function() { return “triangle"; }, area: function() { return this.b * this.h/2; }, perimeter: function() { return this.b + 2*Math.sqrt(Math.pow(this.h,2) + Math.pow(this.b/2, 2)); }, numberOfSides: function() { return 3; } }); Triangle.adapt(TShape, TriangleBehavior); Circle = new cop.Context({}); CircleBehavior = cop.Trait({ getType: function() { return “circle"; }, area: function() { return Math.pow(this.b, 2) * Math.PI; }, perimeter: function() { return this.b * 2* Math.PI; }, numberOfSides: function() { throw new Error("Number of sides is not defined in a circle"); } }); Circle.adapt(Shape, CircleBehavior); baseline ours r1 r2 r3 r4 r6 r5 r7 r8 r9
  • 37.
    Precision evaluation 14 Shape ={ b: 2, h: 3, type: "shape", getType: function() { return this.type; }, area: function() { return 'Calling an abstract method area’; }, perimeter: function() { return 'Calling an abstract method perimeter’; }, numberOfSides: function() { return 0; } }; Triangle = new cop.Context({}); TriangleBehavior = cop.Trait({ getType: function() { return “triangle"; }, area: function() { return this.b * this.h/2; }, perimeter: function() { return this.b + 2*Math.sqrt(Math.pow(this.h,2) + Math.pow(this.b/2, 2)); }, numberOfSides: function() { return 3; } }); Triangle.adapt(TShape, TriangleBehavior); Circle = new cop.Context({}); CircleBehavior = cop.Trait({ getType: function() { return “circle"; }, area: function() { return Math.pow(this.b, 2) * Math.PI; }, perimeter: function() { return this.b * 2* Math.PI; }, numberOfSides: function() { throw new Error("Number of sides is not defined in a circle"); } }); Circle.adapt(Shape, CircleBehavior); sides baseline ours r9 r1 r2 r3 r4 r6 r5 r7 r8 r9
  • 38.
    Precision evaluation 14 Shape ={ b: 2, h: 3, type: "shape", getType: function() { return this.type; }, area: function() { return 'Calling an abstract method area’; }, perimeter: function() { return 'Calling an abstract method perimeter’; }, numberOfSides: function() { return 0; } }; Triangle = new cop.Context({}); TriangleBehavior = cop.Trait({ getType: function() { return “triangle"; }, area: function() { return this.b * this.h/2; }, perimeter: function() { return this.b + 2*Math.sqrt(Math.pow(this.h,2) + Math.pow(this.b/2, 2)); }, numberOfSides: function() { return 3; } }); Triangle.adapt(TShape, TriangleBehavior); Circle = new cop.Context({}); CircleBehavior = cop.Trait({ getType: function() { return “circle"; }, area: function() { return Math.pow(this.b, 2) * Math.PI; }, perimeter: function() { return this.b * 2* Math.PI; }, numberOfSides: function() { throw new Error("Number of sides is not defined in a circle"); } }); Circle.adapt(Shape, CircleBehavior); sides baseline ours r9 r1 r2 r3 r4 r6 r5 r8 r7 r9 r7 r8 r9 sides
  • 39.
    The road ahead… adaptation completeness 15 Context1 = new cop.Context({}); Behavior1 = cop.Trait({ foo: function() ... }); Context1.adapt(Object, Behavior1); Context2 = new cop.Context({}); Behavior2 = cop.Trait({ bar: function(){ baz(); foo(); } }); Context2.adapt(Object, Behavior2); Object = { baz: function() ... };
  • 40.
    The road ahead… adaptation completeness 15 Context1 = new cop.Context({}); Behavior1 = cop.Trait({ foo: function() ... }); Context1.adapt(Object, Behavior1); Context2 = new cop.Context({}); Behavior2 = cop.Trait({ bar: function(){ baz(); foo(); } }); Context2.adapt(Object, Behavior2); Object = { baz: function() ... }; Context1.activate(); Context2.activate(); bar(); 1.
  • 41.
    The road ahead… adaptation completeness 15 Context1 = new cop.Context({}); Behavior1 = cop.Trait({ foo: function() ... }); Context1.adapt(Object, Behavior1); Context2 = new cop.Context({}); Behavior2 = cop.Trait({ bar: function(){ baz(); foo(); } }); Context2.adapt(Object, Behavior2); Object = { baz: function() ... }; Context1.activate(); Context2.activate(); bar(); Context2.activate(); bar(); 1. 2.
  • 42.
    The road ahead… adaptation completeness 15 Context1 = new cop.Context({}); Behavior1 = cop.Trait({ foo: function() ... }); Context1.adapt(Object, Behavior1); Context2 = new cop.Context({}); Behavior2 = cop.Trait({ bar: function(){ baz(); foo(); } }); Context2.adapt(Object, Behavior2); Object = { baz: function() ... }; Context1.activate(); Context2.activate(); bar(); Context2.activate(); bar(); 1. 2.
  • 43.
  • 44.
    Conclusion 16 @ncardoz COP analysis framework First analysistaking into account the modularity and dynamic aspects of COP
  • 45.
    Conclusion 16 @ncardoz COP analysis framework First analysistaking into account the modularity and dynamic aspects of COP Improved recall for COP programs (without proceed)