From afc3f36104efc4d38347c951732008a9366929bf Mon Sep 17 00:00:00 2001 From: whitequark Date: Wed, 19 Aug 2015 12:37:22 -0700 Subject: [PATCH] ARTIQIRGenerator: fix polymorphic print on closures. --- artiq/compiler/builtins.py | 1 + artiq/compiler/transforms/artiq_ir_generator.py | 5 ++--- artiq/compiler/transforms/llvm_ir_generator.py | 2 ++ artiq/compiler/types.py | 16 +++++++++++++++- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/artiq/compiler/builtins.py b/artiq/compiler/builtins.py index 1a5cc3670..2e26b8f79 100644 --- a/artiq/compiler/builtins.py +++ b/artiq/compiler/builtins.py @@ -203,6 +203,7 @@ def is_collection(typ): def is_allocated(typ): return not (is_none(typ) or is_bool(typ) or is_int(typ) or is_float(typ) or is_range(typ) or + types._is_pointer(typ) or types.is_function(typ) or types.is_c_function(typ) or types.is_rpc_function(typ) or types.is_method(typ) or types.is_tuple(typ) or types.is_value(typ)) diff --git a/artiq/compiler/transforms/artiq_ir_generator.py b/artiq/compiler/transforms/artiq_ir_generator.py index 5a101cdec..b6cd2863e 100644 --- a/artiq/compiler/transforms/artiq_ir_generator.py +++ b/artiq/compiler/transforms/artiq_ir_generator.py @@ -1575,9 +1575,8 @@ class ARTIQIRGenerator(algorithm.Visitor): format_string += ")" elif types.is_function(value.type): format_string += "" - # We're relying on the internal layout of the closure here. - args.append(self.append(ir.GetAttr(value, 0))) - args.append(self.append(ir.GetAttr(value, 1))) + args.append(self.append(ir.GetAttr(value, '__code__'))) + args.append(self.append(ir.GetAttr(value, '__closure__'))) elif builtins.is_none(value.type): format_string += "None" elif builtins.is_bool(value.type): diff --git a/artiq/compiler/transforms/llvm_ir_generator.py b/artiq/compiler/transforms/llvm_ir_generator.py index fec9a16cd..660cf6750 100644 --- a/artiq/compiler/transforms/llvm_ir_generator.py +++ b/artiq/compiler/transforms/llvm_ir_generator.py @@ -180,6 +180,8 @@ class LLVMIRGenerator: return llvoid else: return ll.LiteralStructType([]) + elif types._is_pointer(typ): + return llptr elif types.is_function(typ): envarg = llptr llty = ll.FunctionType(args=[envarg] + diff --git a/artiq/compiler/types.py b/artiq/compiler/types.py index 34a86dd11..e1a3a406b 100644 --- a/artiq/compiler/types.py +++ b/artiq/compiler/types.py @@ -176,6 +176,10 @@ class TTuple(Type): def __ne__(self, other): return not (self == other) +class _TPointer(TMono): + def __init__(self): + super().__init__("pointer") + class TFunction(Type): """ A function type. @@ -188,7 +192,10 @@ class TFunction(Type): return type """ - attributes = OrderedDict() + attributes = OrderedDict([ + ('__code__', _TPointer()), + ('__closure__', _TPointer()), + ]) def __init__(self, args, optargs, ret): assert isinstance(args, OrderedDict) @@ -245,6 +252,8 @@ class TRPCFunction(TFunction): :ivar service: (int) RPC service number """ + attributes = OrderedDict() + def __init__(self, args, optargs, ret, service): super().__init__(args, optargs, ret) self.service = service @@ -265,6 +274,8 @@ class TCFunction(TFunction): :ivar name: (str) C function name """ + attributes = OrderedDict() + def __init__(self, args, ret, name): super().__init__(args, OrderedDict(), ret) self.name = name @@ -422,6 +433,9 @@ def is_tuple(typ, elts=None): else: return isinstance(typ, TTuple) +def _is_pointer(typ): + return isinstance(typ.find(), _TPointer) + def is_function(typ): return isinstance(typ.find(), TFunction)