forked from M-Labs/artiq
parent
5c54a6a0e9
commit
f2ae24da39
|
@ -47,9 +47,20 @@ class EmbeddingMap:
|
||||||
self.object_current_key = 0
|
self.object_current_key = 0
|
||||||
self.object_forward_map = {}
|
self.object_forward_map = {}
|
||||||
self.object_reverse_map = {}
|
self.object_reverse_map = {}
|
||||||
|
self.module_map = {}
|
||||||
self.type_map = {}
|
self.type_map = {}
|
||||||
self.function_map = {}
|
self.function_map = {}
|
||||||
|
|
||||||
|
# Modules
|
||||||
|
def store_module(self, module, module_type):
|
||||||
|
self.module_map[module] = module_type
|
||||||
|
|
||||||
|
def retrieve_module(self, module):
|
||||||
|
return self.module_map[module]
|
||||||
|
|
||||||
|
def has_module(self, module):
|
||||||
|
return module in self.module_map
|
||||||
|
|
||||||
# Types
|
# Types
|
||||||
def store_type(self, host_type, instance_type, constructor_type):
|
def store_type(self, host_type, instance_type, constructor_type):
|
||||||
self.type_map[host_type] = (instance_type, constructor_type)
|
self.type_map[host_type] = (instance_type, constructor_type)
|
||||||
|
@ -88,7 +99,8 @@ class EmbeddingMap:
|
||||||
for obj_id in self.object_forward_map.keys():
|
for obj_id in self.object_forward_map.keys():
|
||||||
obj_ref = self.object_forward_map[obj_id]
|
obj_ref = self.object_forward_map[obj_id]
|
||||||
if isinstance(obj_ref, (pytypes.FunctionType, pytypes.MethodType,
|
if isinstance(obj_ref, (pytypes.FunctionType, pytypes.MethodType,
|
||||||
pytypes.BuiltinFunctionType, SpecializedFunction)):
|
pytypes.BuiltinFunctionType, pytypes.ModuleType,
|
||||||
|
SpecializedFunction)):
|
||||||
continue
|
continue
|
||||||
elif isinstance(obj_ref, type):
|
elif isinstance(obj_ref, type):
|
||||||
_, obj_typ = self.type_map[obj_ref]
|
_, obj_typ = self.type_map[obj_ref]
|
||||||
|
@ -178,6 +190,21 @@ class ASTSynthesizer:
|
||||||
unquote_loc = self._add('`')
|
unquote_loc = self._add('`')
|
||||||
loc = quote_loc.join(unquote_loc)
|
loc = quote_loc.join(unquote_loc)
|
||||||
return asttyped.QuoteT(value=value, type=function_type, loc=loc)
|
return asttyped.QuoteT(value=value, type=function_type, loc=loc)
|
||||||
|
elif isinstance(value, pytypes.ModuleType):
|
||||||
|
if self.embedding_map.has_module(value):
|
||||||
|
module_type = self.embedding_map.retrieve_module(value)
|
||||||
|
else:
|
||||||
|
module_type = types.TModule(value.__name__, OrderedDict())
|
||||||
|
module_type.attributes['__objectid__'] = builtins.TInt32()
|
||||||
|
self.embedding_map.store_module(value, module_type)
|
||||||
|
|
||||||
|
quote_loc = self._add('`')
|
||||||
|
repr_loc = self._add(repr(value))
|
||||||
|
unquote_loc = self._add('`')
|
||||||
|
loc = quote_loc.join(unquote_loc)
|
||||||
|
|
||||||
|
self.value_map[module_type].append((value, loc))
|
||||||
|
return asttyped.QuoteT(value=value, type=module_type, loc=loc)
|
||||||
else:
|
else:
|
||||||
quote_loc = self._add('`')
|
quote_loc = self._add('`')
|
||||||
repr_loc = self._add(repr(value))
|
repr_loc = self._add(repr(value))
|
||||||
|
@ -409,7 +436,7 @@ class StitchingInferencer(Inferencer):
|
||||||
self.quote = quote
|
self.quote = quote
|
||||||
self.attr_type_cache = {}
|
self.attr_type_cache = {}
|
||||||
|
|
||||||
def _compute_value_type(self, object_value, object_type, object_loc, attr_name, loc):
|
def _compute_attr_type(self, object_value, object_type, object_loc, attr_name, loc):
|
||||||
if not hasattr(object_value, attr_name):
|
if not hasattr(object_value, attr_name):
|
||||||
if attr_name.startswith('_'):
|
if attr_name.startswith('_'):
|
||||||
names = set(filter(lambda name: not name.startswith('_'),
|
names = set(filter(lambda name: not name.startswith('_'),
|
||||||
|
@ -519,7 +546,7 @@ class StitchingInferencer(Inferencer):
|
||||||
attributes, attr_value_type = self.attr_type_cache[attr_type_key]
|
attributes, attr_value_type = self.attr_type_cache[attr_type_key]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
attributes, attr_value_type = \
|
attributes, attr_value_type = \
|
||||||
self._compute_value_type(object_value, object_type, object_loc, attr_name, loc)
|
self._compute_attr_type(object_value, object_type, object_loc, attr_name, loc)
|
||||||
self.attr_type_cache[attr_type_key] = attributes, attr_value_type
|
self.attr_type_cache[attr_type_key] = attributes, attr_value_type
|
||||||
|
|
||||||
if attr_name not in attributes:
|
if attr_name not in attributes:
|
||||||
|
|
|
@ -1345,15 +1345,9 @@ class LLVMIRGenerator:
|
||||||
value_id = id(value)
|
value_id = id(value)
|
||||||
if value_id in self.llobject_map:
|
if value_id in self.llobject_map:
|
||||||
return self.llobject_map[value_id]
|
return self.llobject_map[value_id]
|
||||||
|
|
||||||
llty = self.llty_of_type(typ)
|
llty = self.llty_of_type(typ)
|
||||||
if types.is_constructor(typ) or types.is_instance(typ):
|
|
||||||
if types.is_instance(typ):
|
|
||||||
# Make sure the class functions are quoted, as this has the side effect of
|
|
||||||
# initializing the global closures.
|
|
||||||
self._quote(type(value), typ.constructor,
|
|
||||||
lambda: path() + ['__class__'])
|
|
||||||
|
|
||||||
|
def _quote_attributes():
|
||||||
llglobal = None
|
llglobal = None
|
||||||
llfields = []
|
llfields = []
|
||||||
for attr in typ.attributes:
|
for attr in typ.attributes:
|
||||||
|
@ -1386,6 +1380,16 @@ class LLVMIRGenerator:
|
||||||
llglobal.initializer = ll.Constant(llty.pointee, llfields)
|
llglobal.initializer = ll.Constant(llty.pointee, llfields)
|
||||||
llglobal.linkage = "private"
|
llglobal.linkage = "private"
|
||||||
return llglobal
|
return llglobal
|
||||||
|
|
||||||
|
if types.is_constructor(typ) or types.is_instance(typ):
|
||||||
|
if types.is_instance(typ):
|
||||||
|
# Make sure the class functions are quoted, as this has the side effect of
|
||||||
|
# initializing the global closures.
|
||||||
|
self._quote(type(value), typ.constructor,
|
||||||
|
lambda: path() + ['__class__'])
|
||||||
|
return _quote_attributes()
|
||||||
|
elif types.is_module(typ):
|
||||||
|
return _quote_attributes()
|
||||||
elif builtins.is_none(typ):
|
elif builtins.is_none(typ):
|
||||||
assert value is None
|
assert value is None
|
||||||
return ll.Constant.literal_struct([])
|
return ll.Constant.literal_struct([])
|
||||||
|
|
|
@ -425,6 +425,21 @@ class TInstance(TMono):
|
||||||
return "artiq.compiler.types.TInstance({}, {})".format(
|
return "artiq.compiler.types.TInstance({}, {})".format(
|
||||||
repr(self.name), repr(self.attributes))
|
repr(self.name), repr(self.attributes))
|
||||||
|
|
||||||
|
class TModule(TMono):
|
||||||
|
"""
|
||||||
|
A type of a module.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, name, attributes):
|
||||||
|
assert isinstance(attributes, OrderedDict)
|
||||||
|
super().__init__(name)
|
||||||
|
self.attributes = attributes
|
||||||
|
self.constant_attributes = set()
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "artiq.compiler.types.TModule({}, {})".format(
|
||||||
|
repr(self.name), repr(self.attributes))
|
||||||
|
|
||||||
class TMethod(TMono):
|
class TMethod(TMono):
|
||||||
"""
|
"""
|
||||||
A type of a method.
|
A type of a method.
|
||||||
|
@ -608,6 +623,14 @@ def is_instance(typ, name=None):
|
||||||
else:
|
else:
|
||||||
return isinstance(typ, TInstance)
|
return isinstance(typ, TInstance)
|
||||||
|
|
||||||
|
def is_module(typ, name=None):
|
||||||
|
typ = typ.find()
|
||||||
|
if name is not None:
|
||||||
|
return isinstance(typ, TModule) and \
|
||||||
|
typ.name == name
|
||||||
|
else:
|
||||||
|
return isinstance(typ, TModule)
|
||||||
|
|
||||||
def is_method(typ):
|
def is_method(typ):
|
||||||
return isinstance(typ.find(), TMethod)
|
return isinstance(typ.find(), TMethod)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
# RUN: %python -m artiq.compiler.testbench.embedding %s
|
||||||
|
|
||||||
|
from artiq.language.core import *
|
||||||
|
from artiq.language.types import *
|
||||||
|
|
||||||
|
import time, os
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def entrypoint():
|
||||||
|
time.sleep(10)
|
||||||
|
os.mkdir("foo")
|
Loading…
Reference in New Issue