Python: Minor performance enhancements.

This commit is contained in:
Mark Shannon
2019-06-14 16:16:06 +01:00
parent 87ebc178cc
commit a5fbbdeaf1
4 changed files with 20 additions and 7 deletions

View File

@@ -440,9 +440,8 @@ class SuperInstance extends TSuperInstance, ObjectInternal {
pragma [noinline] override predicate descriptorGetInstance(ObjectInternal instance, ObjectInternal value, CfgOrigin origin) { none() }
pragma [noinline] override predicate attribute(string name, ObjectInternal value, CfgOrigin origin) {
PointsToInternal::attributeRequired(this, name) and
exists(ObjectInternal cls_attr, CfgOrigin attr_orig |
this.lookup(name, cls_attr, attr_orig)
this.attribute_descriptor(name, cls_attr, attr_orig)
|
cls_attr.isDescriptor() = false and value = cls_attr and origin = attr_orig
or
@@ -450,6 +449,12 @@ class SuperInstance extends TSuperInstance, ObjectInternal {
)
}
/* Helper for `attribute` */
pragma [noinline] private predicate attribute_descriptor(string name, ObjectInternal cls_attr, CfgOrigin attr_orig) {
PointsToInternal::attributeRequired(this, name) and
this.lookup(name, cls_attr, attr_orig)
}
private predicate lookup(string name, ObjectInternal value, CfgOrigin origin) {
Types::getMro(this.getSelf().getClass()).startingAt(this.getStartClass()).getTail().lookup(name, value, origin)
}

View File

@@ -1856,9 +1856,13 @@ cached module Types {
result = getInheritedMetaclass(cls, 0)
or
// Best guess if base is not a known class
hasUnknownBase(cls) and result = ObjectInternal::unknownClass()
}
/* Helper for getInheritedMetaclass */
private predicate hasUnknownBase(ClassObjectInternal cls) {
exists(ObjectInternal base |
base = getBase(cls, _) and
result = ObjectInternal::unknownClass() |
base = getBase(cls, _) |
base.isClass() = false
or
base = ObjectInternal::unknownClass()
@@ -1868,14 +1872,18 @@ cached module Types {
private ClassObjectInternal getInheritedMetaclass(ClassObjectInternal cls, int n) {
exists(Class c |
c = cls.(PythonClassObjectInternal).getScope() and
n = count(c.getABase())
n = count(c.getABase()) and n != 1
|
result = ObjectInternal::type() and major_version() = 3
or
result = ObjectInternal::classType() and major_version() = 2
)
or
base_count(cls) = 1 and n = 0 and
result = getBase(cls, 0).getClass()
or
exists(ClassObjectInternal meta1, ClassObjectInternal meta2 |
base_count(cls) > 1 and
meta1 = getBase(cls, n).getClass() and
meta2 = getInheritedMetaclass(cls, n+1)
|

View File

@@ -182,7 +182,7 @@ class PointsToContext extends TPointsToContext {
this = TRuntimeContext() and executes_in_runtime_context(s)
or
/* Called functions, regardless of their name */
exists(CallableObjectInternal callable, ControlFlowNode call, TPointsToContext outerContext |
exists(PythonFunctionObjectInternal callable, ControlFlowNode call, TPointsToContext outerContext |
call = callable.getACall(outerContext) and
this = TCallContext(call, outerContext, _) |
s = callable.getScope()

View File

@@ -1512,7 +1512,7 @@ class CallContext extends TCallContext {
f.getFunction() = s and f.getACall() = call
)
or
exists(ClassValue cls,CallNode call |
exists(ClassValue cls, CallNode call |
this = TCalleeContext(call, _, _) and
call.getFunction().pointsTo(cls) and
s = cls.lookup("__init__").(CallableValue).getScope() and