From 0f6f6846705da02ab3279d70372071642989ec13 Mon Sep 17 00:00:00 2001 From: whitequark Date: Tue, 26 Apr 2016 01:31:17 +0000 Subject: [PATCH] compiler: allow RPCing builtin functions. Fixes #366. --- artiq/compiler/embedding.py | 25 +++++++++++-------- .../compiler/transforms/llvm_ir_generator.py | 3 ++- artiq/coredevice/comm_generic.py | 4 +-- artiq/test/coredevice/test_embedding.py | 7 ++++++ 4 files changed, 26 insertions(+), 13 deletions(-) diff --git a/artiq/compiler/embedding.py b/artiq/compiler/embedding.py index 426728fd5..3147467e6 100644 --- a/artiq/compiler/embedding.py +++ b/artiq/compiler/embedding.py @@ -5,7 +5,7 @@ the references to the host objects and translates the functions annotated as ``@kernel`` when they are referenced. """ -import sys, os, re, linecache, inspect, textwrap +import sys, os, re, linecache, inspect, textwrap, types as pytypes from collections import OrderedDict, defaultdict from pythonparser import ast, algorithm, source, diagnostic, parse_buffer @@ -102,7 +102,8 @@ class ASTSynthesizer: return asttyped.ListT(elts=elts, ctx=None, type=builtins.TList(), begin_loc=begin_loc, end_loc=end_loc, loc=begin_loc.join(end_loc)) - elif inspect.isfunction(value) or inspect.ismethod(value): + elif inspect.isfunction(value) or inspect.ismethod(value) or \ + isinstance(value, pytypes.BuiltinFunctionType): quote_loc = self._add('`') repr_loc = self._add(repr(value)) unquote_loc = self._add('`') @@ -734,17 +735,21 @@ class Stitcher: self.functions[function] = function_type return function_type - def _quote_rpc(self, function, loc): - signature = inspect.signature(function) + def _quote_rpc(self, callee, loc): + ret_type = builtins.TNone() - if signature.return_annotation is not inspect.Signature.empty: - ret_type = self._extract_annot(function, signature.return_annotation, - "return type", loc, is_syscall=False) + if isinstance(callee, pytypes.BuiltinFunctionType): + pass + elif isinstance(callee, pytypes.FunctionType): + signature = inspect.signature(callee) + if signature.return_annotation is not inspect.Signature.empty: + ret_type = self._extract_annot(callee, signature.return_annotation, + "return type", loc, is_syscall=False) else: - ret_type = builtins.TNone() + assert False - function_type = types.TRPC(ret_type, service=self.object_map.store(function)) - self.functions[function] = function_type + function_type = types.TRPC(ret_type, service=self.object_map.store(callee)) + self.functions[callee] = function_type return function_type def _quote_function(self, function, loc): diff --git a/artiq/compiler/transforms/llvm_ir_generator.py b/artiq/compiler/transforms/llvm_ir_generator.py index acec6953a..605e22840 100644 --- a/artiq/compiler/transforms/llvm_ir_generator.py +++ b/artiq/compiler/transforms/llvm_ir_generator.py @@ -412,7 +412,8 @@ class LLVMIRGenerator: for obj_id in self.object_map: obj_ref = self.object_map.retrieve(obj_id) - if isinstance(obj_ref, (pytypes.FunctionType, pytypes.MethodType)): + if isinstance(obj_ref, (pytypes.FunctionType, pytypes.MethodType, + pytypes.BuiltinFunctionType)): continue elif isinstance(obj_ref, type): _, typ = self.type_map[obj_ref] diff --git a/artiq/coredevice/comm_generic.py b/artiq/coredevice/comm_generic.py index 35ef9b3ce..929ea64ae 100644 --- a/artiq/coredevice/comm_generic.py +++ b/artiq/coredevice/comm_generic.py @@ -345,7 +345,7 @@ class CommGeneric: else: raise IOError("Unknown RPC value tag: {}".format(repr(tag))) - def _receive_rpc_args(self, object_map, defaults): + def _receive_rpc_args(self, object_map): args, kwargs = [], {} while True: value = self._receive_rpc_value(object_map) @@ -443,7 +443,7 @@ class CommGeneric: else: service = object_map.retrieve(service_id) - args, kwargs = self._receive_rpc_args(object_map, service.__defaults__) + args, kwargs = self._receive_rpc_args(object_map) return_tags = self._read_bytes() logger.debug("rpc service: [%d]%r %r %r -> %s", service_id, service, args, kwargs, return_tags) diff --git a/artiq/test/coredevice/test_embedding.py b/artiq/test/coredevice/test_embedding.py index 867dd5fa3..3ab53cb91 100644 --- a/artiq/test/coredevice/test_embedding.py +++ b/artiq/test/coredevice/test_embedding.py @@ -1,3 +1,5 @@ +from time import sleep + from artiq.experiment import * from artiq.test.hardware_testbench import ExperimentCase @@ -97,6 +99,10 @@ class _RPC(EnvExperiment): def args1kwargs2(self): return self.kwargs("X", a="A", b=1) + @kernel + def builtin(self): + sleep(1.0) + class RPCTest(ExperimentCase): def test_args(self): exp = self.create(_RPC) @@ -107,6 +113,7 @@ class RPCTest(ExperimentCase): self.assertEqual(exp.kwargs1(), 1) self.assertEqual(exp.kwargs2(), 2) self.assertEqual(exp.args1kwargs2(), 2) + exp.builtin() class _Payload1MB(EnvExperiment):