compiler: implement kernel constant attributes.

Part of #322.
This commit is contained in:
whitequark 2016-03-27 16:10:01 +00:00
parent 42609d057e
commit f4e6b18690
6 changed files with 55 additions and 0 deletions

View File

@ -1,2 +1,3 @@
from .constness import Constness
from .domination import DominatorTree
from .devirtualization import Devirtualization

View File

@ -0,0 +1,30 @@
"""
:class:`Constness` checks that no attribute marked
as constant is ever set.
"""
from pythonparser import algorithm, diagnostic
from .. import types
class Constness(algorithm.Visitor):
def __init__(self, engine):
self.engine = engine
self.in_assign = False
def visit_Assign(self, node):
self.visit(node.value)
self.in_assign = True
self.visit(node.targets)
self.in_assign = False
def visit_AttributeT(self, node):
self.generic_visit(node)
if self.in_assign:
typ = node.value.type.find()
if types.is_instance(typ) and node.attr in typ.constant_attributes:
diag = diagnostic.Diagnostic("error",
"cannot assign to constant attribute '{attr}' of class '{class}'",
{"attr": node.attr, "class": typ.name},
node.loc)
self.engine.process(diag)
return

View File

@ -137,6 +137,9 @@ class ASTSynthesizer:
instance_type = types.TInstance("{}.{}".format(typ.__module__, typ.__qualname__),
OrderedDict())
instance_type.attributes['__objectid__'] = builtins.TInt32()
if hasattr(typ, 'kernel_constant_attributes'):
assert isinstance(typ.kernel_constant_attributes, set)
instance_type.constant_attributes = typ.kernel_constant_attributes
constructor_type = types.TConstructor(instance_type)
constructor_type.attributes['__objectid__'] = builtins.TInt32()

View File

@ -56,6 +56,7 @@ class Module:
escape_validator = validators.EscapeValidator(engine=self.engine)
iodelay_estimator = transforms.IODelayEstimator(engine=self.engine,
ref_period=ref_period)
constness = analyses.Constness(engine=self.engine)
artiq_ir_generator = transforms.ARTIQIRGenerator(engine=self.engine,
module_name=src.name,
ref_period=ref_period)
@ -71,6 +72,7 @@ class Module:
monomorphism_validator.visit(src.typedtree)
escape_validator.visit(src.typedtree)
iodelay_estimator.visit_fixpoint(src.typedtree)
constness.visit(src.typedtree)
devirtualization.visit(src.typedtree)
self.artiq_ir = artiq_ir_generator.visit(src.typedtree)
artiq_ir_generator.annotate_calls(devirtualization)

View File

@ -443,6 +443,7 @@ class TInstance(TMono):
assert isinstance(attributes, OrderedDict)
super().__init__(name)
self.attributes = attributes
self.constant_attributes = set()
def __repr__(self):
return "artiq.compiler.types.TInstance({}, {})".format(

View File

@ -0,0 +1,18 @@
# RUN: %python -m artiq.compiler.testbench.embedding +diag %s >%t
# RUN: OutputCheck %s --file-to-check=%t
from artiq.language.core import *
from artiq.language.types import *
class c:
kernel_constant_attributes = {'a'}
def __init__(self):
self.a = 1
i = c()
@kernel
def entrypoint():
# CHECK-L: ${LINE:+1}: error: cannot assign to constant attribute 'a' of class 'testbench.c'
i.a = 1